@liberseek/boft-cli-win32-arm64 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2278,7 +2278,7 @@ var require_websocket = __commonJS({
2278
2278
  var http = __require("http");
2279
2279
  var net5 = __require("net");
2280
2280
  var tls = __require("tls");
2281
- var { randomBytes: randomBytes4, createHash: createHash10 } = __require("crypto");
2281
+ var { randomBytes: randomBytes4, createHash: createHash11 } = __require("crypto");
2282
2282
  var { Duplex: Duplex2, Readable } = __require("stream");
2283
2283
  var { URL: URL2 } = __require("url");
2284
2284
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -2946,7 +2946,7 @@ var require_websocket = __commonJS({
2946
2946
  abortHandshake(websocket, socket, "Invalid Upgrade header");
2947
2947
  return;
2948
2948
  }
2949
- const digest2 = createHash10("sha1").update(key + GUID).digest("base64");
2949
+ const digest2 = createHash11("sha1").update(key + GUID).digest("base64");
2950
2950
  if (res.headers["sec-websocket-accept"] !== digest2) {
2951
2951
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2952
2952
  return;
@@ -3315,7 +3315,7 @@ var require_websocket_server = __commonJS({
3315
3315
  var EventEmitter = __require("events");
3316
3316
  var http = __require("http");
3317
3317
  var { Duplex: Duplex2 } = __require("stream");
3318
- var { createHash: createHash10 } = __require("crypto");
3318
+ var { createHash: createHash11 } = __require("crypto");
3319
3319
  var extension2 = require_extension();
3320
3320
  var PerMessageDeflate2 = require_permessage_deflate();
3321
3321
  var subprotocol2 = require_subprotocol();
@@ -3622,7 +3622,7 @@ var require_websocket_server = __commonJS({
3622
3622
  );
3623
3623
  }
3624
3624
  if (this._state > RUNNING) return abortHandshake(socket, 503);
3625
- const digest2 = createHash10("sha1").update(key + GUID).digest("base64");
3625
+ const digest2 = createHash11("sha1").update(key + GUID).digest("base64");
3626
3626
  const headers = [
3627
3627
  "HTTP/1.1 101 Switching Protocols",
3628
3628
  "Upgrade: websocket",
@@ -4283,7 +4283,7 @@ async function runDelegationCli(input) {
4283
4283
 
4284
4284
  // packages/host-runtime/src/run-host-runtime.ts
4285
4285
  import { randomBytes as randomBytes2 } from "node:crypto";
4286
- import path21 from "node:path";
4286
+ import path23 from "node:path";
4287
4287
  import { homedir as homedir2 } from "node:os";
4288
4288
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4289
4289
 
@@ -5978,10 +5978,10 @@ function mergeDefs(...defs) {
5978
5978
  function cloneDef(schema) {
5979
5979
  return mergeDefs(schema._zod.def);
5980
5980
  }
5981
- function getElementAtPath(obj, path26) {
5982
- if (!path26)
5981
+ function getElementAtPath(obj, path28) {
5982
+ if (!path28)
5983
5983
  return obj;
5984
- return path26.reduce((acc, key) => acc?.[key], obj);
5984
+ return path28.reduce((acc, key) => acc?.[key], obj);
5985
5985
  }
5986
5986
  function promiseAllObject(promisesObj) {
5987
5987
  const keys = Object.keys(promisesObj);
@@ -6390,11 +6390,11 @@ function explicitlyAborted(x, startIndex = 0) {
6390
6390
  }
6391
6391
  return false;
6392
6392
  }
6393
- function prefixIssues(path26, issues) {
6393
+ function prefixIssues(path28, issues) {
6394
6394
  return issues.map((iss) => {
6395
6395
  var _a3;
6396
6396
  (_a3 = iss).path ?? (_a3.path = []);
6397
- iss.path.unshift(path26);
6397
+ iss.path.unshift(path28);
6398
6398
  return iss;
6399
6399
  });
6400
6400
  }
@@ -6541,16 +6541,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
6541
6541
  }
6542
6542
  function formatError(error51, mapper = (issue2) => issue2.message) {
6543
6543
  const fieldErrors = { _errors: [] };
6544
- const processError = (error52, path26 = []) => {
6544
+ const processError = (error52, path28 = []) => {
6545
6545
  for (const issue2 of error52.issues) {
6546
6546
  if (issue2.code === "invalid_union" && issue2.errors.length) {
6547
- issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
6547
+ issue2.errors.map((issues) => processError({ issues }, [...path28, ...issue2.path]));
6548
6548
  } else if (issue2.code === "invalid_key") {
6549
- processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6549
+ processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
6550
6550
  } else if (issue2.code === "invalid_element") {
6551
- processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6551
+ processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
6552
6552
  } else {
6553
- const fullpath = [...path26, ...issue2.path];
6553
+ const fullpath = [...path28, ...issue2.path];
6554
6554
  if (fullpath.length === 0) {
6555
6555
  fieldErrors._errors.push(mapper(issue2));
6556
6556
  } else {
@@ -6577,17 +6577,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
6577
6577
  }
6578
6578
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
6579
6579
  const result = { errors: [] };
6580
- const processError = (error52, path26 = []) => {
6580
+ const processError = (error52, path28 = []) => {
6581
6581
  var _a3, _b;
6582
6582
  for (const issue2 of error52.issues) {
6583
6583
  if (issue2.code === "invalid_union" && issue2.errors.length) {
6584
- issue2.errors.map((issues) => processError({ issues }, [...path26, ...issue2.path]));
6584
+ issue2.errors.map((issues) => processError({ issues }, [...path28, ...issue2.path]));
6585
6585
  } else if (issue2.code === "invalid_key") {
6586
- processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6586
+ processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
6587
6587
  } else if (issue2.code === "invalid_element") {
6588
- processError({ issues: issue2.issues }, [...path26, ...issue2.path]);
6588
+ processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
6589
6589
  } else {
6590
- const fullpath = [...path26, ...issue2.path];
6590
+ const fullpath = [...path28, ...issue2.path];
6591
6591
  if (fullpath.length === 0) {
6592
6592
  result.errors.push(mapper(issue2));
6593
6593
  continue;
@@ -6619,8 +6619,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
6619
6619
  }
6620
6620
  function toDotPath(_path) {
6621
6621
  const segs = [];
6622
- const path26 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
6623
- for (const seg of path26) {
6622
+ const path28 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
6623
+ for (const seg of path28) {
6624
6624
  if (typeof seg === "number")
6625
6625
  segs.push(`[${seg}]`);
6626
6626
  else if (typeof seg === "symbol")
@@ -19312,13 +19312,13 @@ function resolveRef(ref, ctx) {
19312
19312
  if (!ref.startsWith("#")) {
19313
19313
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
19314
19314
  }
19315
- const path26 = ref.slice(1).split("/").filter(Boolean);
19316
- if (path26.length === 0) {
19315
+ const path28 = ref.slice(1).split("/").filter(Boolean);
19316
+ if (path28.length === 0) {
19317
19317
  return ctx.rootSchema;
19318
19318
  }
19319
19319
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
19320
- if (path26[0] === defsKey) {
19321
- const key = path26[1];
19320
+ if (path28[0] === defsKey) {
19321
+ const key = path28[1];
19322
19322
  if (!key || !ctx.defs[key]) {
19323
19323
  throw new Error(`Reference not found: ${ref}`);
19324
19324
  }
@@ -19726,6 +19726,62 @@ function date4(params) {
19726
19726
  // node_modules/zod/v4/classic/external.js
19727
19727
  config(en_default());
19728
19728
 
19729
+ // packages/shared-contracts/dist/credential-imports.js
19730
+ var credentialSourceSchema = external_exports.object({
19731
+ id: external_exports.string().min(1).max(256),
19732
+ harnessId: external_exports.string().min(1),
19733
+ label: external_exports.string().min(1).max(512),
19734
+ provider: external_exports.enum(["openai-codex", "xai"])
19735
+ }).strict();
19736
+ var credentialImportNameSchema = external_exports.string().regex(/^[a-z][a-z0-9-]{0,47}$/);
19737
+ var credentialImportRecordSchema = external_exports.object({
19738
+ name: credentialImportNameSchema,
19739
+ source: credentialSourceSchema,
19740
+ importedAt: external_exports.string()
19741
+ }).strict();
19742
+ var credentialImportsRequestSchema = external_exports.discriminatedUnion("action", [
19743
+ external_exports.object({ action: external_exports.literal("list") }).strict(),
19744
+ external_exports.object({
19745
+ action: external_exports.literal("import"),
19746
+ sourceId: external_exports.string().min(1).max(256),
19747
+ name: credentialImportNameSchema,
19748
+ confirmed: external_exports.literal(true)
19749
+ }).strict(),
19750
+ external_exports.object({
19751
+ action: external_exports.literal("reimport"),
19752
+ sourceId: external_exports.string().min(1).max(256),
19753
+ name: credentialImportNameSchema,
19754
+ confirmed: external_exports.literal(true)
19755
+ }).strict(),
19756
+ external_exports.object({
19757
+ action: external_exports.literal("remove"),
19758
+ name: credentialImportNameSchema,
19759
+ confirmed: external_exports.literal(true)
19760
+ }).strict()
19761
+ ]);
19762
+ var credentialOtherLoginSchema = external_exports.object({
19763
+ provider: external_exports.string().min(1).max(128),
19764
+ type: external_exports.enum(["oauth", "api_key", "unknown"]),
19765
+ /** Best-effort account label (e.g. the email in a Codex token), derived locally when present. */
19766
+ label: external_exports.string().min(1).max(512).optional(),
19767
+ /** Recognized credential vendor, derived from the OAuth token issuer. Absent when unknown. */
19768
+ vendor: external_exports.enum(["openai-codex", "xai"]).optional()
19769
+ }).strict();
19770
+ var credentialImportsResultSchema = external_exports.object({
19771
+ sources: external_exports.array(credentialSourceSchema),
19772
+ targets: external_exports.array(external_exports.object({
19773
+ harnessId: external_exports.string(),
19774
+ providers: external_exports.array(external_exports.enum(["openai-codex", "xai"])),
19775
+ imports: external_exports.array(credentialImportRecordSchema),
19776
+ others: external_exports.array(credentialOtherLoginSchema).default([])
19777
+ }).strict())
19778
+ }).strict();
19779
+ var credentialImportsParamsSchema = external_exports.object({
19780
+ targetHarnessId: external_exports.string().min(1).max(128).optional(),
19781
+ request: credentialImportsRequestSchema
19782
+ }).strict();
19783
+ var CREDENTIAL_IMPORTS_METHOD = "codexhost/harness/credential-imports";
19784
+
19729
19785
  // packages/shared-contracts/dist/version.js
19730
19786
  var WORKSPACE_CONTRACT_VERSION = 1;
19731
19787
 
@@ -20282,6 +20338,8 @@ var pluginPresentationShape = {
20282
20338
  id: harnessPluginIdSchema,
20283
20339
  name: external_exports.string().trim().min(1).max(128),
20284
20340
  version: external_exports.string().min(1).max(128),
20341
+ /** The factory accepts a persisted local entrypoint through its construction context. */
20342
+ launchCommand: external_exports.literal(true).optional(),
20285
20343
  links: external_exports.object({
20286
20344
  documentation: documentationUrlSchema.optional(),
20287
20345
  installation: documentationUrlSchema.optional()
@@ -20343,6 +20401,21 @@ function decodeHarnessPluginRoute(value2) {
20343
20401
  }
20344
20402
  }
20345
20403
 
20404
+ // packages/shared-contracts/dist/harness-launch-settings.js
20405
+ var HARNESS_LAUNCH_SETTINGS_GET_METHOD = "codexhost/harness/launch-settings/get";
20406
+ var HARNESS_LAUNCH_SETTINGS_SET_METHOD = "codexhost/harness/launch-settings/set";
20407
+ var harnessLaunchPathSchema = external_exports.string().trim().min(1).max(4096).refine((value2) => !/[\u0000\r\n]/u.test(value2), "Invalid entrypoint path");
20408
+ var harnessLaunchSettingsGetSchema = external_exports.object({
20409
+ harnessId: harnessPluginIdSchema
20410
+ }).strict();
20411
+ var harnessLaunchSettingsSetSchema = harnessLaunchSettingsGetSchema.extend({
20412
+ path: harnessLaunchPathSchema.nullable()
20413
+ });
20414
+ var harnessLaunchSettingsSchema = external_exports.object({
20415
+ path: harnessLaunchPathSchema.nullable(),
20416
+ restartRequired: external_exports.boolean()
20417
+ }).strict();
20418
+
20346
20419
  // packages/shared-contracts/dist/codex-accounts.js
20347
20420
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
20348
20421
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -20637,6 +20710,97 @@ var updateStatusResultSchema = external_exports.strictObject({
20637
20710
  // packages/shared-contracts/dist/index.js
20638
20711
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
20639
20712
 
20713
+ // packages/host-runtime/src/account/codex-credential-export.ts
20714
+ import { createHash as createHash2 } from "node:crypto";
20715
+ import { readFile as readFile4 } from "node:fs/promises";
20716
+ import os from "node:os";
20717
+ import path5 from "node:path";
20718
+ async function readCodexCredential(environment) {
20719
+ try {
20720
+ const home = environment.CODEX_HOME ?? path5.join(environment.HOME ?? os.homedir(), ".codex");
20721
+ const auth = JSON.parse(await readFile4(path5.join(home, "auth.json"), "utf8"));
20722
+ if (auth.OPENAI_API_KEY || auth.auth_mode && auth.auth_mode !== "chatgpt") return [];
20723
+ const t = auth.tokens;
20724
+ if (!t || ![t.access_token, t.refresh_token, t.account_id].every(
20725
+ (v) => typeof v === "string" && v.length
20726
+ ))
20727
+ return [];
20728
+ const claims = JSON.parse(Buffer.from(t.access_token.split(".")[1], "base64url").toString());
20729
+ if (claims.client_id !== "app_EMoamEEZ73f0CkXaXp7hrann" || !Number.isFinite(claims.exp * 1e3))
20730
+ return [];
20731
+ const account = claims["https://api.openai.com/auth"]?.chatgpt_account_id;
20732
+ if (account !== t.account_id) return [];
20733
+ let email3;
20734
+ try {
20735
+ email3 = JSON.parse(Buffer.from(t.id_token.split(".")[1], "base64url").toString()).email;
20736
+ } catch {
20737
+ }
20738
+ const identity = `${t.account_id}:${claims.sub ?? ""}`;
20739
+ return [
20740
+ {
20741
+ source: {
20742
+ id: `codex:${createHash2("sha256").update(identity).digest("hex")}`,
20743
+ harnessId: "codex",
20744
+ provider: "openai-codex",
20745
+ label: typeof email3 === "string" && email3 ? email3 : "Codex"
20746
+ },
20747
+ oauth: {
20748
+ access: t.access_token,
20749
+ refresh: t.refresh_token,
20750
+ expires: claims.exp * 1e3,
20751
+ accountId: t.account_id
20752
+ }
20753
+ }
20754
+ ];
20755
+ } catch {
20756
+ return [];
20757
+ }
20758
+ }
20759
+
20760
+ // packages/host-runtime/src/credential-imports.ts
20761
+ async function handleCredentialImports(params, adapters, environment) {
20762
+ const input = credentialImportsParamsSchema.parse(params);
20763
+ const installed = [...adapters];
20764
+ const sources = await readCodexCredential(environment);
20765
+ for (const adapter of installed) {
20766
+ if (adapter.credentialExport) sources.push(...await adapter.credentialExport.read());
20767
+ }
20768
+ const request = input.request;
20769
+ if (request.action !== "list") {
20770
+ const target = installed.find((a) => a.harnessId === input.targetHarnessId)?.credentialImports;
20771
+ if (!target) throw new Error("Target Harness does not support credential imports");
20772
+ if (request.action === "remove") await target.remove(request.name);
20773
+ else {
20774
+ const source = sources.find((s) => s.source.id === request.sourceId);
20775
+ if (!source || !target.providers.includes(source.source.provider))
20776
+ throw new Error("Source login changed or is unavailable; refresh and confirm again");
20777
+ if (request.action === "reimport") await target.reimport(request.name, source);
20778
+ else await target.add(request.name, source);
20779
+ }
20780
+ }
20781
+ const targets = [];
20782
+ for (const adapter of installed) {
20783
+ if (!adapter.credentialImports) continue;
20784
+ try {
20785
+ targets.push({
20786
+ harnessId: adapter.harnessId,
20787
+ providers: [...adapter.credentialImports.providers],
20788
+ imports: await adapter.credentialImports.list(),
20789
+ others: await listOthers(adapter)
20790
+ });
20791
+ } catch {
20792
+ }
20793
+ }
20794
+ return credentialImportsResultSchema.parse({ sources: sources.map((s) => s.source), targets });
20795
+ }
20796
+ async function listOthers(adapter) {
20797
+ try {
20798
+ return await adapter.credentialImports?.listOthers?.() ?? [];
20799
+ } catch {
20800
+ return [];
20801
+ }
20802
+ }
20803
+
20640
20804
  // packages/harness-adapter/dist/output-channel.js
20641
20805
  var HarnessOutputChannel = class {
20642
20806
  outputs;
@@ -20792,8 +20956,8 @@ var packageMetadata = {
20792
20956
  import { execFileSync } from "node:child_process";
20793
20957
  import { randomUUID as randomUUID2 } from "node:crypto";
20794
20958
  import { constants } from "node:fs";
20795
- import { copyFile as copyFile2, mkdir as mkdir3, open as open3, readFile as readFile4, readdir as readdir2, rename as rename2, rm as rm3, stat } from "node:fs/promises";
20796
- import path5 from "node:path";
20959
+ import { copyFile as copyFile2, mkdir as mkdir3, open as open3, readFile as readFile5, readdir as readdir2, rename as rename2, rm as rm3, stat } from "node:fs/promises";
20960
+ import path6 from "node:path";
20797
20961
 
20798
20962
  // packages/mapping-store/dist/records.js
20799
20963
  var nonBlankTextSchema6 = external_exports.string().refine((value2) => value2.trim().length > 0, {
@@ -21056,12 +21220,12 @@ var MappingStore = class {
21056
21220
  #initialized = false;
21057
21221
  #lockHandle = null;
21058
21222
  constructor(options2) {
21059
- this.#directory = path5.resolve(options2.directory);
21060
- this.#threadsDirectory = path5.join(this.#directory, "threads");
21061
- this.#delegationsDirectory = path5.join(this.#directory, "delegations");
21062
- this.#backupsDirectory = path5.join(this.#directory, "backups");
21063
- this.#quarantineDirectory = path5.join(this.#directory, "quarantine");
21064
- this.#lockPath = path5.join(this.#directory, "store.lock");
21223
+ this.#directory = path6.resolve(options2.directory);
21224
+ this.#threadsDirectory = path6.join(this.#directory, "threads");
21225
+ this.#delegationsDirectory = path6.join(this.#directory, "delegations");
21226
+ this.#backupsDirectory = path6.join(this.#directory, "backups");
21227
+ this.#quarantineDirectory = path6.join(this.#directory, "quarantine");
21228
+ this.#lockPath = path6.join(this.#directory, "store.lock");
21065
21229
  this.#instanceId = options2.instanceId ?? randomUUID2();
21066
21230
  this.#now = options2.now ?? (() => /* @__PURE__ */ new Date());
21067
21231
  this.#beforeReplace = options2.beforeReplace;
@@ -21080,8 +21244,8 @@ var MappingStore = class {
21080
21244
  await this.#cleanupResidue();
21081
21245
  const names = (await readdir2(this.#threadsDirectory)).filter((name) => name.endsWith(".json"));
21082
21246
  for (const name of names) {
21083
- const primary = path5.join(this.#threadsDirectory, name);
21084
- const backup = path5.join(this.#backupsDirectory, name);
21247
+ const primary = path6.join(this.#threadsDirectory, name);
21248
+ const backup = path6.join(this.#backupsDirectory, name);
21085
21249
  let record3 = null;
21086
21250
  try {
21087
21251
  record3 = await this.#readRecord(primary, name);
@@ -21090,7 +21254,7 @@ var MappingStore = class {
21090
21254
  record3 = await this.#readRecord(backup, name);
21091
21255
  await this.#replaceFile(primary, record3, false);
21092
21256
  } catch (backupError) {
21093
- const quarantine = path5.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
21257
+ const quarantine = path6.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
21094
21258
  await rename2(primary, quarantine).catch(() => void 0);
21095
21259
  void primaryError;
21096
21260
  void backupError;
@@ -21106,14 +21270,14 @@ var MappingStore = class {
21106
21270
  }
21107
21271
  const delegationNames = (await readdir2(this.#delegationsDirectory)).filter((name) => name.endsWith(".json"));
21108
21272
  for (const name of delegationNames) {
21109
- const file2 = path5.join(this.#delegationsDirectory, name);
21273
+ const file2 = path6.join(this.#delegationsDirectory, name);
21110
21274
  try {
21111
- const parsed = storedDelegationRecordV1Schema.parse(JSON.parse(await readFile4(file2, "utf8")));
21275
+ const parsed = storedDelegationRecordV1Schema.parse(JSON.parse(await readFile5(file2, "utf8")));
21112
21276
  if (`${parsed.delegationId}.json` !== name)
21113
21277
  throw new Error("filename mismatch");
21114
21278
  this.#delegations.set(parsed.delegationId, parsed);
21115
21279
  } catch {
21116
- const quarantine = path5.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid-delegation`);
21280
+ const quarantine = path6.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid-delegation`);
21117
21281
  await rename2(file2, quarantine).catch(() => void 0);
21118
21282
  }
21119
21283
  }
@@ -21407,7 +21571,7 @@ var MappingStore = class {
21407
21571
  if (handle)
21408
21572
  await handle.close().catch(() => void 0);
21409
21573
  try {
21410
- const current = JSON.parse(await readFile4(this.#lockPath, "utf8"));
21574
+ const current = JSON.parse(await readFile5(this.#lockPath, "utf8"));
21411
21575
  if (current.instanceId === this.#instanceId)
21412
21576
  await rm3(this.#lockPath, { force: true });
21413
21577
  } catch {
@@ -21523,7 +21687,7 @@ var MappingStore = class {
21523
21687
  }
21524
21688
  }
21525
21689
  async #readRecord(file2, expectedName) {
21526
- const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await readFile4(file2, "utf8")));
21690
+ const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await readFile5(file2, "utf8")));
21527
21691
  if (!parsed.success) {
21528
21692
  throw new MappingStoreError("INVALID_RECORD", "Mapping Store record is invalid", {
21529
21693
  cause: parsed.error
@@ -21541,10 +21705,10 @@ var MappingStore = class {
21541
21705
  readdir2(this.#directory)
21542
21706
  ]);
21543
21707
  await Promise.all([
21544
- ...threadNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path5.join(this.#threadsDirectory, name), { force: true })),
21545
- ...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path5.join(this.#delegationsDirectory, name), { force: true })),
21708
+ ...threadNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path6.join(this.#threadsDirectory, name), { force: true })),
21709
+ ...delegationNames.filter((name) => name.includes(".tmp-")).map((name) => rm3(path6.join(this.#delegationsDirectory, name), { force: true })),
21546
21710
  // Renamed aside by #acquireLock; nothing reads them back, and they accumulate one per run.
21547
- ...rootNames.filter((name) => name.startsWith(`${path5.basename(this.#lockPath)}.stale-`)).map((name) => rm3(path5.join(this.#directory, name), { force: true }))
21711
+ ...rootNames.filter((name) => name.startsWith(`${path6.basename(this.#lockPath)}.stale-`)).map((name) => rm3(path6.join(this.#directory, name), { force: true }))
21548
21712
  ]);
21549
21713
  }
21550
21714
  async #acquireLock() {
@@ -21571,7 +21735,7 @@ var MappingStore = class {
21571
21735
  }
21572
21736
  let existing = {};
21573
21737
  try {
21574
- existing = JSON.parse(await readFile4(this.#lockPath, "utf8"));
21738
+ existing = JSON.parse(await readFile5(this.#lockPath, "utf8"));
21575
21739
  } catch {
21576
21740
  }
21577
21741
  if (typeof existing.pid === "number" && lockOwnerIsLive(existing)) {
@@ -21645,13 +21809,13 @@ var MappingStore = class {
21645
21809
  await next;
21646
21810
  }
21647
21811
  #recordPath(hostThreadId) {
21648
- return path5.join(this.#threadsDirectory, `${hostThreadId}.json`);
21812
+ return path6.join(this.#threadsDirectory, `${hostThreadId}.json`);
21649
21813
  }
21650
21814
  #delegationPath(delegationId) {
21651
- return path5.join(this.#delegationsDirectory, `${delegationId}.json`);
21815
+ return path6.join(this.#delegationsDirectory, `${delegationId}.json`);
21652
21816
  }
21653
21817
  #backupPath(hostThreadId) {
21654
- return path5.join(this.#backupsDirectory, `${hostThreadId}.json`);
21818
+ return path6.join(this.#backupsDirectory, `${hostThreadId}.json`);
21655
21819
  }
21656
21820
  #requireInitialized() {
21657
21821
  if (!this.#initialized) {
@@ -22348,16 +22512,16 @@ var Diff = class {
22348
22512
  }
22349
22513
  }
22350
22514
  }
22351
- addToPath(path26, added, removed, oldPosInc, options2) {
22352
- const last = path26.lastComponent;
22515
+ addToPath(path28, added, removed, oldPosInc, options2) {
22516
+ const last = path28.lastComponent;
22353
22517
  if (last && !options2.oneChangePerToken && last.added === added && last.removed === removed) {
22354
22518
  return {
22355
- oldPos: path26.oldPos + oldPosInc,
22519
+ oldPos: path28.oldPos + oldPosInc,
22356
22520
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
22357
22521
  };
22358
22522
  } else {
22359
22523
  return {
22360
- oldPos: path26.oldPos + oldPosInc,
22524
+ oldPos: path28.oldPos + oldPosInc,
22361
22525
  lastComponent: { count: 1, added, removed, previousComponent: last }
22362
22526
  };
22363
22527
  }
@@ -22786,10 +22950,10 @@ function splitLines(text2) {
22786
22950
  }
22787
22951
 
22788
22952
  // packages/protocol-core/dist/file-change-summary.js
22789
- import path6 from "node:path";
22953
+ import path7 from "node:path";
22790
22954
  function filePathKey(file2, cwd) {
22791
22955
  const windows = /^[a-z]:[/\\]/i.test(cwd) || /^[a-z]:[/\\]/i.test(file2);
22792
- const paths = windows ? path6.win32 : path6.posix;
22956
+ const paths = windows ? path7.win32 : path7.posix;
22793
22957
  const resolved = paths.resolve(cwd, file2).replaceAll("\\", "/");
22794
22958
  return windows ? resolved.toLowerCase() : resolved;
22795
22959
  }
@@ -23059,8 +23223,8 @@ function projectFileChangeKind(kind) {
23059
23223
  return { type: kind };
23060
23224
  }
23061
23225
  function projectFileChanges(changes) {
23062
- return changes.map(({ path: path26, kind, unifiedDiff }) => ({
23063
- path: path26,
23226
+ return changes.map(({ path: path28, kind, unifiedDiff }) => ({
23227
+ path: path28,
23064
23228
  kind: projectFileChangeKind(kind),
23065
23229
  diff: unifiedDiff
23066
23230
  }));
@@ -24007,13 +24171,13 @@ function decodeThreadForkRequest(request) {
24007
24171
  if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
24008
24172
  throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
24009
24173
  }
24010
- const path26 = optionalText(params, "path", { allowEmpty: true });
24174
+ const path28 = optionalText(params, "path", { allowEmpty: true });
24011
24175
  const ephemeral = optionalBoolean(params, "ephemeral");
24012
24176
  return {
24013
24177
  threadId: threadId2,
24014
24178
  ...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
24015
24179
  ...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
24016
- ...path26 ? { path: path26 } : {},
24180
+ ...path28 ? { path: path28 } : {},
24017
24181
  ...optionalField(params, "model"),
24018
24182
  ...optionalField(params, "modelProvider"),
24019
24183
  ...optionalField(params, "cwd"),
@@ -24106,7 +24270,7 @@ function threadForkResult(thread, input) {
24106
24270
  }
24107
24271
 
24108
24272
  // packages/protocol-core/dist/thread-management.js
24109
- import { createHash as createHash2 } from "node:crypto";
24273
+ import { createHash as createHash3 } from "node:crypto";
24110
24274
  var HOST_CURSOR_PREFIX = "codexhost:thread-list:v1:";
24111
24275
  var MAX_CURSOR_LENGTH = 65536;
24112
24276
  var DEFAULT_PAGE_SIZE = 25;
@@ -24197,13 +24361,13 @@ function decodeSortDirection(value2) {
24197
24361
  function decodeSortKey(value2) {
24198
24362
  if (value2 === void 0 || value2 === null)
24199
24363
  return "created_at";
24200
- if (value2 !== "created_at" && value2 !== "updated_at" && value2 !== "recency_at") {
24364
+ if (value2 !== "created_at" && value2 !== "updated_at" && value2 !== "recency_at" && value2 !== "section_position") {
24201
24365
  throw new Error("thread/list params.sortKey is unsupported");
24202
24366
  }
24203
24367
  return value2;
24204
24368
  }
24205
24369
  function queryFingerprint(value2) {
24206
- return createHash2("sha256").update(JSON.stringify(value2)).digest("hex");
24370
+ return createHash3("sha256").update(JSON.stringify(value2)).digest("hex");
24207
24371
  }
24208
24372
  function cursorPayload(value2) {
24209
24373
  return {
@@ -24301,7 +24465,10 @@ function decodeThreadListRequest(request) {
24301
24465
  const cursorText = nullableText(params.cursor, "thread/list params.cursor");
24302
24466
  const hasUnknownFields = Object.keys(params).some((name) => !THREAD_LIST_FIELDS.has(name));
24303
24467
  const isHostCursor = cursorText?.startsWith(HOST_CURSOR_PREFIX) === true;
24304
- const supportsExternal = !hasUnknownFields && (cursorText === null || isHostCursor);
24468
+ if (sortKey === "section_position" && isHostCursor) {
24469
+ throw new Error("thread/list Host cursor cannot be used with section_position sorting");
24470
+ }
24471
+ const supportsExternal = sortKey !== "section_position" && !hasUnknownFields && (cursorText === null || isHostCursor);
24305
24472
  const cursor = supportsExternal && cursorText ? decodeHostThreadListCursor(cursorText, {
24306
24473
  queryFingerprint: fingerprint,
24307
24474
  sortDirection: sortDirection2
@@ -24880,22 +25047,38 @@ async function* readLfFrames(stream, options2 = {}) {
24880
25047
  const maximum = options2.maxFrameBytes ?? Infinity;
24881
25048
  if (maximum !== Infinity && (!Number.isSafeInteger(maximum) || maximum < 1))
24882
25049
  throw new Error("Invalid protocol frame limit");
24883
- let pending = Buffer.alloc(0);
25050
+ let pendingChunks = [];
25051
+ let pendingLength = 0;
24884
25052
  for await (const chunk of stream) {
24885
25053
  const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
24886
- pending = pending.length === 0 ? bytes : Buffer.concat([pending, bytes]);
24887
- let newlineIndex = pending.indexOf(10);
25054
+ let frameStart = 0;
25055
+ let newlineIndex = bytes.indexOf(10);
24888
25056
  while (newlineIndex >= 0) {
24889
- if (newlineIndex > maximum)
25057
+ const tail = bytes.subarray(frameStart, newlineIndex);
25058
+ const frameLength = pendingLength + tail.length;
25059
+ if (frameLength > maximum)
25060
+ throw new Error("Protocol frame exceeds its limit");
25061
+ if (pendingLength === 0) {
25062
+ yield tail;
25063
+ } else {
25064
+ pendingChunks.push(tail);
25065
+ pendingLength = frameLength;
25066
+ yield Buffer.concat(pendingChunks, pendingLength);
25067
+ pendingChunks = [];
25068
+ pendingLength = 0;
25069
+ }
25070
+ frameStart = newlineIndex + 1;
25071
+ newlineIndex = bytes.indexOf(10, frameStart);
25072
+ }
25073
+ if (frameStart < bytes.length) {
25074
+ const remainder = bytes.subarray(frameStart);
25075
+ pendingChunks.push(remainder);
25076
+ pendingLength += remainder.length;
25077
+ if (pendingLength > maximum)
24890
25078
  throw new Error("Protocol frame exceeds its limit");
24891
- yield pending.subarray(0, newlineIndex);
24892
- pending = pending.subarray(newlineIndex + 1);
24893
- newlineIndex = pending.indexOf(10);
24894
25079
  }
24895
- if (pending.length > maximum)
24896
- throw new Error("Protocol frame exceeds its limit");
24897
25080
  }
24898
- if (pending.length !== 0) {
25081
+ if (pendingLength !== 0) {
24899
25082
  throw new Error("Protocol stream ended with an unterminated JSONL frame");
24900
25083
  }
24901
25084
  }
@@ -25170,22 +25353,22 @@ var HarnessAccountInspectionCache = class {
25170
25353
  };
25171
25354
 
25172
25355
  // packages/host-runtime/src/app-server-host.ts
25173
- import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
25174
- import os2 from "node:os";
25175
- import path12 from "node:path";
25356
+ import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
25357
+ import os4 from "node:os";
25358
+ import path14 from "node:path";
25176
25359
 
25177
25360
  // packages/host-runtime/src/external-thread-fork.ts
25178
25361
  import nodePath from "node:path";
25179
25362
 
25180
25363
  // packages/host-runtime/src/external-thread-repository.ts
25181
25364
  import { randomUUID as randomUUID4 } from "node:crypto";
25182
- import os from "node:os";
25183
- import path7 from "node:path";
25365
+ import os2 from "node:os";
25366
+ import path8 from "node:path";
25184
25367
 
25185
25368
  // packages/host-runtime/src/external-subagent-threads.ts
25186
- import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
25369
+ import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
25187
25370
  function childCreateRequest(parent, nativeRef, id2) {
25188
- const key = createHash3("sha256").update(JSON.stringify([parent.hostThreadId, parent.harnessId, nativeRef.nativeSessionId, id2])).digest("hex");
25371
+ const key = createHash4("sha256").update(JSON.stringify([parent.hostThreadId, parent.harnessId, nativeRef.nativeSessionId, id2])).digest("hex");
25189
25372
  return `subagent:${key}`;
25190
25373
  }
25191
25374
  function subagentMaterializer(store, parent, previousParent) {
@@ -25320,8 +25503,8 @@ function sameMapping(left, right) {
25320
25503
  }
25321
25504
  function defaultMappingStoreDirectory(environment) {
25322
25505
  const dataDirectory = environment.CODEXHOST_DATA_DIR;
25323
- return path7.join(
25324
- dataDirectory ? path7.resolve(dataDirectory) : path7.join(os.homedir(), ".codexhost"),
25506
+ return path8.join(
25507
+ dataDirectory ? path8.resolve(dataDirectory) : path8.join(os2.homedir(), ".codexhost"),
25325
25508
  "mapping-store"
25326
25509
  );
25327
25510
  }
@@ -27395,11 +27578,11 @@ var ExternalTurnSteering = class {
27395
27578
  };
27396
27579
 
27397
27580
  // packages/host-runtime/src/harness-delegation-coordinator.ts
27398
- import { createHash as createHash5, randomUUID as randomUUID5 } from "node:crypto";
27399
- import path8 from "node:path";
27581
+ import { createHash as createHash6, randomUUID as randomUUID5 } from "node:crypto";
27582
+ import path9 from "node:path";
27400
27583
 
27401
27584
  // packages/host-runtime/src/delegation-snapshot.ts
27402
- import { createHash as createHash4 } from "node:crypto";
27585
+ import { createHash as createHash5 } from "node:crypto";
27403
27586
  var CURSOR_PREFIX = "codexhost:thread-messages:v1:";
27404
27587
  var DEFAULT_MESSAGE_LIMIT = 25;
27405
27588
  var MAX_MESSAGE_LIMIT = 100;
@@ -27453,7 +27636,7 @@ function allVisibleMessages(turns) {
27453
27636
  return messages;
27454
27637
  }
27455
27638
  function cursorFingerprint(threadId2) {
27456
- return createHash4("sha256").update(threadId2).digest("hex");
27639
+ return createHash5("sha256").update(threadId2).digest("hex");
27457
27640
  }
27458
27641
  function encodeCursor(threadId2, offset) {
27459
27642
  const payload = JSON.stringify({ version: 1, fingerprint: cursorFingerprint(threadId2), offset });
@@ -27564,10 +27747,10 @@ function terminal(status) {
27564
27747
  return status === "completed" || status === "failed" || status === "interrupted";
27565
27748
  }
27566
27749
  function taskDigest(input) {
27567
- return createHash5("sha256").update(
27750
+ return createHash6("sha256").update(
27568
27751
  JSON.stringify({
27569
27752
  task: input.task,
27570
- cwd: path8.resolve(input.cwd),
27753
+ cwd: path9.resolve(input.cwd),
27571
27754
  modelId: input.model?.id ?? null,
27572
27755
  thinkingOptionId: input.thinkingOptionId ?? null
27573
27756
  })
@@ -27638,7 +27821,7 @@ var HarnessDelegationCoordinator = class {
27638
27821
  return {
27639
27822
  harnessId: input.harnessId,
27640
27823
  inspection: await adapter.inspect({
27641
- ...input.cwd ? { cwd: path8.resolve(input.cwd) } : {},
27824
+ ...input.cwd ? { cwd: path9.resolve(input.cwd) } : {},
27642
27825
  ...input.refresh !== void 0 ? { refresh: input.refresh } : {}
27643
27826
  })
27644
27827
  };
@@ -27652,7 +27835,7 @@ var HarnessDelegationCoordinator = class {
27652
27835
  const result = await this.#startOfficial({ ...input, parentThreadId, cwd: selectedCwd });
27653
27836
  return { ...result, parentThreadId, cwd: result.cwd ?? selectedCwd };
27654
27837
  }
27655
- const startInput = { ...input, parentThreadId, cwd: path8.resolve(selectedCwd) };
27838
+ const startInput = { ...input, parentThreadId, cwd: path9.resolve(selectedCwd) };
27656
27839
  if (!this.#adapters.has(input.harnessId)) {
27657
27840
  throw new DelegationControlError(
27658
27841
  "HARNESS_NOT_FOUND",
@@ -28081,7 +28264,7 @@ var HarnessDelegationCoordinator = class {
28081
28264
 
28082
28265
  // packages/host-runtime/src/harness-plugin-loader.ts
28083
28266
  import { readdir as readdir3, realpath as realpath2 } from "node:fs/promises";
28084
- import path10 from "node:path";
28267
+ import path11 from "node:path";
28085
28268
  import { pathToFileURL } from "node:url";
28086
28269
 
28087
28270
  // packages/host-runtime/src/harness-plugin-registry.ts
@@ -28119,16 +28302,16 @@ var HarnessPluginRegistry = class {
28119
28302
 
28120
28303
  // packages/host-runtime/src/plugin-files.ts
28121
28304
  import { open as open4, realpath, stat as stat2 } from "node:fs/promises";
28122
- import path9 from "node:path";
28305
+ import path10 from "node:path";
28123
28306
  function inside(root, candidate) {
28124
- const relative = path9.relative(root, candidate);
28125
- return relative !== "" && !path9.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path9.sep}`);
28307
+ const relative = path10.relative(root, candidate);
28308
+ return relative !== "" && !path10.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path10.sep}`);
28126
28309
  }
28127
28310
  async function pluginResourcePath(root, relative) {
28128
- if (path9.isAbsolute(relative) || !inside(root, path9.resolve(root, relative))) {
28311
+ if (path10.isAbsolute(relative) || !inside(root, path10.resolve(root, relative))) {
28129
28312
  throw new Error("Plugin resource escapes its root");
28130
28313
  }
28131
- const resolved = await realpath(path9.resolve(root, relative));
28314
+ const resolved = await realpath(path10.resolve(root, relative));
28132
28315
  if (!inside(root, resolved) || !(await stat2(resolved)).isFile()) {
28133
28316
  throw new Error("Plugin resource must be a regular file inside its root");
28134
28317
  }
@@ -28290,7 +28473,7 @@ async function loadHarnessPlugins(options2) {
28290
28473
  const enabledIds = /* @__PURE__ */ new Set();
28291
28474
  const roots = /* @__PURE__ */ new Set();
28292
28475
  for (const configuredRoot of options2.roots) {
28293
- if (!path10.isAbsolute(configuredRoot)) {
28476
+ if (!path11.isAbsolute(configuredRoot)) {
28294
28477
  diagnose({ code: "invalidRoot" });
28295
28478
  continue;
28296
28479
  }
@@ -28320,7 +28503,7 @@ async function loadHarnessPlugins(options2) {
28320
28503
  for (const directory of directories) {
28321
28504
  try {
28322
28505
  const file2 = await pluginResourcePath(root, `${directory.name}/manifest.json`);
28323
- const pluginRoot = await realpath2(path10.join(root, directory.name));
28506
+ const pluginRoot = await realpath2(path11.join(root, directory.name));
28324
28507
  await pluginResourcePath(pluginRoot, "manifest.json");
28325
28508
  const manifest = harnessPluginManifestSchema.parse(
28326
28509
  JSON.parse(
@@ -28372,6 +28555,7 @@ async function loadHarnessPlugins(options2) {
28372
28555
  id: manifest.id,
28373
28556
  name: manifest.name,
28374
28557
  version: manifest.version,
28558
+ ...manifest.launchCommand && !options2.context.managedRemoteHost ? { launchCommand: true } : {},
28375
28559
  ...manifest.links ? { links: manifest.links } : {}
28376
28560
  });
28377
28561
  let adapter;
@@ -28382,9 +28566,10 @@ async function loadHarnessPlugins(options2) {
28382
28566
  } else {
28383
28567
  try {
28384
28568
  if (manifest.icon) descriptor.icon = await readPluginIcon(candidate.root, manifest.icon);
28569
+ const launchCommand = descriptor.launchCommand ? await options2.launchCommandForPlugin?.(manifest.id) : void 0;
28385
28570
  adapter = await loadAdapter(
28386
28571
  candidate,
28387
- options2.context,
28572
+ { ...options2.context, ...launchCommand ? { launchCommand } : {} },
28388
28573
  timeoutMs,
28389
28574
  diagnose,
28390
28575
  options2.warmup !== false,
@@ -28412,6 +28597,76 @@ async function loadHarnessPlugins(options2) {
28412
28597
  return registry2;
28413
28598
  }
28414
28599
 
28600
+ // packages/host-runtime/src/harness-launch-settings.ts
28601
+ import { randomUUID as randomUUID6 } from "node:crypto";
28602
+ import { mkdir as mkdir4, readFile as readFile6, rename as rename3, rm as rm4, stat as stat3, writeFile as writeFile3 } from "node:fs/promises";
28603
+ import os3 from "node:os";
28604
+ import path12 from "node:path";
28605
+ var HarnessLaunchSettingsStore = class {
28606
+ #directory;
28607
+ #initial = /* @__PURE__ */ new Map();
28608
+ constructor(environment) {
28609
+ this.#directory = path12.join(
28610
+ environment.CODEXHOST_DATA_DIR ? path12.resolve(environment.CODEXHOST_DATA_DIR) : path12.join(os3.homedir(), ".codexhost"),
28611
+ "harness-launch-settings"
28612
+ );
28613
+ }
28614
+ #file(id2) {
28615
+ return path12.join(this.#directory, `${harnessPluginIdSchema.parse(id2)}.json`);
28616
+ }
28617
+ async #read(id2) {
28618
+ try {
28619
+ const value2 = harnessLaunchPathSchema.parse(
28620
+ JSON.parse(await readFile6(this.#file(id2), "utf8"))
28621
+ );
28622
+ if (!path12.isAbsolute(value2)) throw new Error("Expected an absolute entrypoint path");
28623
+ return value2;
28624
+ } catch (error51) {
28625
+ if (error51 && typeof error51 === "object" && "code" in error51 && error51.code === "ENOENT")
28626
+ return null;
28627
+ throw new Error("Could not read Harness launch settings");
28628
+ }
28629
+ }
28630
+ /** Capture the value used to construct this Host's Adapter; changes require a restart. */
28631
+ async initialCommand(id2) {
28632
+ let initial = this.#initial.get(id2);
28633
+ if (!initial) {
28634
+ initial = this.#read(id2);
28635
+ this.#initial.set(id2, initial);
28636
+ }
28637
+ return await initial ?? void 0;
28638
+ }
28639
+ async get(id2) {
28640
+ const initial = await this.initialCommand(id2) ?? null;
28641
+ const value2 = await this.#read(id2);
28642
+ return { path: value2, restartRequired: value2 !== initial };
28643
+ }
28644
+ async set(id2, value2) {
28645
+ const initial = await this.initialCommand(id2) ?? null;
28646
+ const file2 = this.#file(id2);
28647
+ if (value2 === null) {
28648
+ await rm4(file2, { force: true });
28649
+ } else {
28650
+ value2 = harnessLaunchPathSchema.parse(value2);
28651
+ if (!path12.isAbsolute(value2))
28652
+ throw new Error("Use an absolute entrypoint path without arguments");
28653
+ const metadata = await stat3(value2).catch(() => void 0);
28654
+ if (!metadata?.isDirectory() && !metadata?.isFile())
28655
+ throw new Error("The installation path must be an existing directory on this Host");
28656
+ await mkdir4(this.#directory, { recursive: true, mode: 448 });
28657
+ const temporary = `${file2}.${randomUUID6()}.tmp`;
28658
+ try {
28659
+ await writeFile3(temporary, `${JSON.stringify(value2)}
28660
+ `, { mode: 384, flag: "wx" });
28661
+ await rename3(temporary, file2);
28662
+ } finally {
28663
+ await rm4(temporary, { force: true });
28664
+ }
28665
+ }
28666
+ return { path: value2, restartRequired: value2 !== initial };
28667
+ }
28668
+ };
28669
+
28415
28670
  // packages/host-runtime/src/official-codex-model-ref.ts
28416
28671
  import { Buffer as Buffer2 } from "node:buffer";
28417
28672
  var OFFICIAL_CODEX_MODEL_REF_PREFIX = "codex-model-v1.";
@@ -28602,8 +28857,8 @@ var SingleNativeCodexAccount = class {
28602
28857
  };
28603
28858
 
28604
28859
  // packages/host-runtime/src/account/codex-home-auth.ts
28605
- import { readFile as readFile5 } from "node:fs/promises";
28606
- import path11 from "node:path";
28860
+ import { readFile as readFile7 } from "node:fs/promises";
28861
+ import path13 from "node:path";
28607
28862
  var CODEX_API_AUTH_IDENTITY_FALLBACK = "BANK OF TOKEN";
28608
28863
  function tomlUnquote(value2) {
28609
28864
  const trimmed = value2.trim();
@@ -28724,7 +28979,7 @@ function inspectCodexAuthDocuments(input) {
28724
28979
  }
28725
28980
  async function readOptionalUtf8(file2) {
28726
28981
  try {
28727
- return await readFile5(file2, "utf8");
28982
+ return await readFile7(file2, "utf8");
28728
28983
  } catch (error51) {
28729
28984
  if (error51.code === "ENOENT") return void 0;
28730
28985
  throw error51;
@@ -28749,10 +29004,10 @@ function inspectCodexApiUsageSource(input) {
28749
29004
  return { baseUrl, apiKey };
28750
29005
  }
28751
29006
  async function inspectCodexHomeAuth(codexHome) {
28752
- const root = path11.resolve(codexHome);
29007
+ const root = path13.resolve(codexHome);
28753
29008
  const [configToml, authJson] = await Promise.all([
28754
- readOptionalUtf8(path11.join(root, "config.toml")),
28755
- readOptionalUtf8(path11.join(root, "auth.json"))
29009
+ readOptionalUtf8(path13.join(root, "config.toml")),
29010
+ readOptionalUtf8(path13.join(root, "auth.json"))
28756
29011
  ]);
28757
29012
  return inspectCodexAuthDocuments({
28758
29013
  ...configToml ? { configToml } : {},
@@ -28760,10 +29015,10 @@ async function inspectCodexHomeAuth(codexHome) {
28760
29015
  });
28761
29016
  }
28762
29017
  async function inspectCodexHomeApiUsageSource(codexHome, env = process.env) {
28763
- const root = path11.resolve(codexHome);
29018
+ const root = path13.resolve(codexHome);
28764
29019
  const [configToml, authJson] = await Promise.all([
28765
- readOptionalUtf8(path11.join(root, "config.toml")),
28766
- readOptionalUtf8(path11.join(root, "auth.json"))
29020
+ readOptionalUtf8(path13.join(root, "config.toml")),
29021
+ readOptionalUtf8(path13.join(root, "auth.json"))
28767
29022
  ]);
28768
29023
  return inspectCodexApiUsageSource({
28769
29024
  ...configToml ? { configToml } : {},
@@ -28879,10 +29134,10 @@ function projectCodexAccountAuth(snapshot, homeAuth) {
28879
29134
  }
28880
29135
 
28881
29136
  // packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
28882
- import { randomUUID as randomUUID7 } from "node:crypto";
29137
+ import { randomUUID as randomUUID8 } from "node:crypto";
28883
29138
 
28884
29139
  // packages/host-runtime/src/official-request-broker.ts
28885
- import { randomUUID as randomUUID6 } from "node:crypto";
29140
+ import { randomUUID as randomUUID7 } from "node:crypto";
28886
29141
  var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
28887
29142
  var MAX_RETIRED_IDS = 1024;
28888
29143
  function isRecord11(value2) {
@@ -28898,7 +29153,7 @@ var OfficialRequestBroker = class {
28898
29153
  constructor(input) {
28899
29154
  this.#send = input.send;
28900
29155
  this.#timeoutMs = input.timeoutMs ?? 3e4;
28901
- this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID6()}`);
29156
+ this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID7()}`);
28902
29157
  }
28903
29158
  get pendingCount() {
28904
29159
  return this.#pending.size;
@@ -29252,7 +29507,7 @@ var OfficialRuntimeOwner = class {
29252
29507
  }
29253
29508
  #attach(role, output, onBackendStopped) {
29254
29509
  const client = {
29255
- id: randomUUID7(),
29510
+ id: randomUUID8(),
29256
29511
  role,
29257
29512
  output,
29258
29513
  ...onBackendStopped ? { onBackendStopped } : {},
@@ -29410,7 +29665,7 @@ var OfficialRuntimeOwner = class {
29410
29665
  if (!object4(value2)) return client.output(event);
29411
29666
  if (typeof value2.id === "string" || typeof value2.id === "number") {
29412
29667
  if (typeof value2.method === "string") {
29413
- const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID7()}`;
29668
+ const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID8()}`;
29414
29669
  client.serverRequests.set(id2, value2.id);
29415
29670
  const projected = { ...value2, id: id2 };
29416
29671
  return client.output({
@@ -29805,25 +30060,25 @@ function resolveExternalSessionTreeIds(records) {
29805
30060
  const resolve = (start) => {
29806
30061
  const cached2 = resolved.get(start.hostThreadId);
29807
30062
  if (cached2) return cached2;
29808
- const path26 = [];
30063
+ const path28 = [];
29809
30064
  const visited = /* @__PURE__ */ new Set();
29810
30065
  let current = start;
29811
30066
  while (true) {
29812
30067
  const known = resolved.get(current.hostThreadId);
29813
30068
  if (known) {
29814
- for (const record3 of path26) resolved.set(record3.hostThreadId, known);
30069
+ for (const record3 of path28) resolved.set(record3.hostThreadId, known);
29815
30070
  return known;
29816
30071
  }
29817
30072
  if (visited.has(current.hostThreadId)) {
29818
30073
  throw new Error("External Thread Fork tree contains a cycle");
29819
30074
  }
29820
30075
  visited.add(current.hostThreadId);
29821
- path26.push(current);
30076
+ path28.push(current);
29822
30077
  const sourceId = current.subagent?.parentHostThreadId ?? current.forkSource?.hostThreadId;
29823
30078
  const source = sourceId ? byId.get(sourceId) : void 0;
29824
30079
  if (!source) {
29825
30080
  const root = current.hostThreadId;
29826
- for (const record3 of path26) resolved.set(record3.hostThreadId, root);
30081
+ for (const record3 of path28) resolved.set(record3.hostThreadId, root);
29827
30082
  return root;
29828
30083
  }
29829
30084
  current = source;
@@ -29833,7 +30088,9 @@ function resolveExternalSessionTreeIds(records) {
29833
30088
  return resolved;
29834
30089
  }
29835
30090
  function listExternalThreadMetadata(input) {
29836
- if (!input.query.supportsExternal) return { data: [], hasMore: false };
30091
+ if (!input.query.supportsExternal || input.query.sortKey === "section_position") {
30092
+ return { data: [], hasMore: false };
30093
+ }
29837
30094
  const sessionIds = resolveExternalSessionTreeIds(input.records);
29838
30095
  const byId = new Map(input.records.map((record3) => [record3.hostThreadId, record3]));
29839
30096
  const entries = input.records.filter((record3) => includesExternalRecord(record3, input.query, byId)).map((record3) => {
@@ -29910,7 +30167,10 @@ function cursorValue(input) {
29910
30167
  }
29911
30168
  async function aggregateThreadList(input) {
29912
30169
  const { query } = input;
29913
- if (!query.supportsExternal) throw new Error("External aggregation is not supported for query");
30170
+ if (!query.supportsExternal || query.sortKey === "section_position") {
30171
+ throw new Error("External aggregation is not supported for query");
30172
+ }
30173
+ const externalSortKey = query.sortKey;
29914
30174
  const start = query.cursor ?? {
29915
30175
  queryFingerprint: query.queryFingerprint,
29916
30176
  sortDirection: query.sortDirection,
@@ -29960,7 +30220,7 @@ async function aggregateThreadList(input) {
29960
30220
  firstOfficialBackwardsCursor = page.backwardsCursor;
29961
30221
  }
29962
30222
  officialBatch = page;
29963
- officialEntries = page.data.map((thread) => officialThreadListEntry(thread, query.sortKey));
30223
+ officialEntries = page.data.map((thread) => officialThreadListEntry(thread, externalSortKey));
29964
30224
  officialIndex = 0;
29965
30225
  if (officialEntries.length === 0) {
29966
30226
  if (page.nextCursor === null || page.nextCursor === officialCursor) {
@@ -30237,6 +30497,7 @@ var AppServerHost = class {
30237
30497
  #nativeAccountObserver;
30238
30498
  #externalAdapters;
30239
30499
  #pluginDescriptors = [];
30500
+ #launchSettings;
30240
30501
  #accountInspections = new HarnessAccountInspectionCache();
30241
30502
  #externalRuntime;
30242
30503
  #externalSteering = new ExternalTurnSteering();
@@ -30278,7 +30539,10 @@ var AppServerHost = class {
30278
30539
  };
30279
30540
  this.#writer = new OrderedWriter(this.#options.desktopOutput);
30280
30541
  const environment = this.#options.environment ?? process.env;
30281
- const permanentHome = path12.resolve(environment.CODEX_HOME ?? path12.join(os2.homedir(), ".codex"));
30542
+ this.#launchSettings = new HarnessLaunchSettingsStore(
30543
+ this.#options.pluginContext?.environment ?? environment
30544
+ );
30545
+ const permanentHome = path14.resolve(environment.CODEX_HOME ?? path14.join(os4.homedir(), ".codex"));
30282
30546
  this.#ownsOfficialRuntimeScope = options2.officialRuntimeScope === void 0;
30283
30547
  this.#officialRuntimeScope = options2.officialRuntimeScope ?? new OfficialRuntimeScope({
30284
30548
  diagnosticOutput: this.#options.diagnosticOutput,
@@ -30291,7 +30555,8 @@ var AppServerHost = class {
30291
30555
  ...officialEnvironment(environment),
30292
30556
  CODEX_HOME: permanentHome
30293
30557
  },
30294
- ...this.#options.spawnOfficial ? { spawnOfficial: this.#options.spawnOfficial } : {}
30558
+ ...this.#options.spawnOfficial ? { spawnOfficial: this.#options.spawnOfficial } : {},
30559
+ ...this.#options.officialCloseTimeoutMs === void 0 ? {} : { closeTimeoutMs: this.#options.officialCloseTimeoutMs }
30295
30560
  })
30296
30561
  )
30297
30562
  });
@@ -30431,6 +30696,7 @@ var AppServerHost = class {
30431
30696
  if (!this.#options.pluginRoots || this.#pluginLoadAbort.signal.aborted) return;
30432
30697
  const plugins = await loadHarnessPlugins({
30433
30698
  roots: this.#options.pluginRoots,
30699
+ launchCommandForPlugin: (id2) => this.#launchSettings.initialCommand(id2),
30434
30700
  context: this.#options.pluginContext ?? {
30435
30701
  environment: this.#options.environment ?? process.env,
30436
30702
  platform: process.platform,
@@ -30632,6 +30898,32 @@ var AppServerHost = class {
30632
30898
  this.#dispatchDesktopRequest(() => this.#handleCodexAccountRequest(request));
30633
30899
  return;
30634
30900
  }
30901
+ if (request.method === CREDENTIAL_IMPORTS_METHOD) {
30902
+ this.#dispatchDesktopRequest(async () => {
30903
+ if (!credentialImportsParamsSchema.safeParse(request.params).success) {
30904
+ await this.#writer.json(rpcError(request, -32602, "Invalid credential import request"));
30905
+ return;
30906
+ }
30907
+ await this.#waitForPlugins();
30908
+ try {
30909
+ const result = await handleCredentialImports(
30910
+ request.params,
30911
+ this.#externalAdapters.values(),
30912
+ this.#options.environment ?? process.env
30913
+ );
30914
+ await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
30915
+ } catch {
30916
+ await this.#writer.json(
30917
+ rpcError(
30918
+ request,
30919
+ -32077,
30920
+ "Credential operation failed. Check the source login, choose an unused Provider name, and verify Pi configuration access."
30921
+ )
30922
+ );
30923
+ }
30924
+ });
30925
+ return;
30926
+ }
30635
30927
  if (request.method === "codexhost/harness/accounts/sources") {
30636
30928
  this.#dispatchDesktopRequest(async () => {
30637
30929
  if (!harnessAccountSourceListParamsSchema.safeParse(request.params).success) {
@@ -30703,6 +30995,41 @@ var AppServerHost = class {
30703
30995
  this.#dispatchDesktopRequest(() => this.#openHarnessWebUi(request));
30704
30996
  return;
30705
30997
  }
30998
+ if (request.method === HARNESS_LAUNCH_SETTINGS_GET_METHOD || request.method === HARNESS_LAUNCH_SETTINGS_SET_METHOD) {
30999
+ this.#dispatchDesktopRequest(async () => {
31000
+ const schema = request.method === HARNESS_LAUNCH_SETTINGS_SET_METHOD ? harnessLaunchSettingsSetSchema : harnessLaunchSettingsGetSchema;
31001
+ const params = schema.safeParse(request.params);
31002
+ if (!params.success) {
31003
+ await this.#writer.json(rpcError(request, -32602, "Invalid Harness launch settings"));
31004
+ return;
31005
+ }
31006
+ await this.#waitForPlugins();
31007
+ if (!this.#pluginDescriptors.some(
31008
+ (plugin) => plugin.id === params.data.harnessId && plugin.launchCommand
31009
+ )) {
31010
+ await this.#writer.json(
31011
+ rpcError(request, -32602, "Harness launch settings are unavailable")
31012
+ );
31013
+ return;
31014
+ }
31015
+ try {
31016
+ const result = request.method === HARNESS_LAUNCH_SETTINGS_SET_METHOD ? await this.#launchSettings.set(
31017
+ params.data.harnessId,
31018
+ harnessLaunchSettingsSetSchema.parse(request.params).path
31019
+ ) : await this.#launchSettings.get(params.data.harnessId);
31020
+ await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
31021
+ } catch {
31022
+ await this.#writer.json(
31023
+ rpcError(
31024
+ request,
31025
+ -32602,
31026
+ "Could not read or save launch settings. Use an existing absolute installation directory on this Host, without arguments, and check configuration permissions."
31027
+ )
31028
+ );
31029
+ }
31030
+ });
31031
+ return;
31032
+ }
30706
31033
  if (request.method === "codexhost/harness/plugins/list") {
30707
31034
  this.#dispatchDesktopRequest(async () => {
30708
31035
  if (!harnessPluginListParamsSchema.safeParse(request.params).success) {
@@ -31326,7 +31653,7 @@ var AppServerHost = class {
31326
31653
  throw new DelegationControlError("INVALID_ARGUMENT", "Official Model Ref is invalid");
31327
31654
  }
31328
31655
  const nativeModelId = requestedModel ? decodeOfficialCodexModelRef(requestedModel) : void 0;
31329
- const digest2 = createHash6("sha256").update(
31656
+ const digest2 = createHash7("sha256").update(
31330
31657
  JSON.stringify({
31331
31658
  task: input.task,
31332
31659
  cwd: input.cwd,
@@ -31427,7 +31754,7 @@ var AppServerHost = class {
31427
31754
  throw error51;
31428
31755
  }
31429
31756
  this.#activeOfficialTurns.set(threadId2, turnId);
31430
- const delegationId = hostThreadIdSchema.parse(randomUUID8());
31757
+ const delegationId = hostThreadIdSchema.parse(randomUUID9());
31431
31758
  try {
31432
31759
  const source = await this.#repository.find(input.parentThreadId);
31433
31760
  const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
@@ -31591,7 +31918,7 @@ var AppServerHost = class {
31591
31918
  async #listDelegationThreads(input) {
31592
31919
  const [sortKey, sortDirection2] = input.sort.split("-");
31593
31920
  const request = {
31594
- id: `codexhost:delegation-list:${randomUUID8()}`,
31921
+ id: `codexhost:delegation-list:${randomUUID9()}`,
31595
31922
  method: "thread/list",
31596
31923
  params: {
31597
31924
  cwd: input.cwd ? [input.cwd] : null,
@@ -32075,7 +32402,7 @@ var AppServerHost = class {
32075
32402
  );
32076
32403
  return;
32077
32404
  }
32078
- const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID8());
32405
+ const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID9());
32079
32406
  const projection = {
32080
32407
  projector: new CodexTurnProjector({
32081
32408
  threadId: thread.id,
@@ -32942,7 +33269,7 @@ var AppServerHost = class {
32942
33269
  if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
32943
33270
  throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
32944
33271
  }
32945
- const turnId = hostTurnIdSchema.parse(randomUUID8());
33272
+ const turnId = hostTurnIdSchema.parse(randomUUID9());
32946
33273
  const startedAtMs = Date.now();
32947
33274
  const projection = {
32948
33275
  projector: new CodexTurnProjector({
@@ -33570,7 +33897,7 @@ var AppServerHost = class {
33570
33897
  try {
33571
33898
  result = projection.projector.projectQuestion(
33572
33899
  interaction,
33573
- hostItemIdSchema.parse(randomUUID8())
33900
+ hostItemIdSchema.parse(randomUUID9())
33574
33901
  );
33575
33902
  } catch (error51) {
33576
33903
  this.#diagnose(error51);
@@ -33736,19 +34063,19 @@ var AppServerHost = class {
33736
34063
  };
33737
34064
 
33738
34065
  // packages/host-runtime/src/native-account-host.ts
33739
- import { mkdir as mkdir6, realpath as realpath3 } from "node:fs/promises";
34066
+ import { mkdir as mkdir7, realpath as realpath3 } from "node:fs/promises";
33740
34067
  import { homedir } from "node:os";
33741
- import path16 from "node:path";
34068
+ import path18 from "node:path";
33742
34069
 
33743
34070
  // packages/host-runtime/src/codex-runtime/owned-official-backends.ts
33744
- import { createHash as createHash7, randomBytes } from "node:crypto";
34071
+ import { createHash as createHash8, randomBytes } from "node:crypto";
33745
34072
  import { Writable as Writable2 } from "node:stream";
33746
34073
 
33747
34074
  // packages/host-runtime/src/remote-app-server.ts
33748
34075
  import { createServer } from "node:http";
33749
34076
  import net from "node:net";
33750
- import { chmod as chmod3, lstat as lstat6, mkdir as mkdir5, rm as rm5 } from "node:fs/promises";
33751
- import path14 from "node:path";
34077
+ import { chmod as chmod3, lstat as lstat6, mkdir as mkdir6, rm as rm6 } from "node:fs/promises";
34078
+ import path16 from "node:path";
33752
34079
  import { PassThrough } from "node:stream";
33753
34080
 
33754
34081
  // node_modules/ws/wrapper.mjs
@@ -33763,10 +34090,10 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
33763
34090
  var wrapper_default = import_websocket.default;
33764
34091
 
33765
34092
  // packages/host-runtime/src/remote-socket-lock.ts
33766
- import { randomUUID as randomUUID9 } from "node:crypto";
33767
- import { chmod as chmod2, lstat as lstat5, mkdir as mkdir4, open as open5, readFile as readFile6, readdir as readdir4, rename as rename3, rm as rm4 } from "node:fs/promises";
34093
+ import { randomUUID as randomUUID10 } from "node:crypto";
34094
+ import { chmod as chmod2, lstat as lstat5, mkdir as mkdir5, open as open5, readFile as readFile8, readdir as readdir4, rename as rename4, rm as rm5 } from "node:fs/promises";
33768
34095
  import { uptime } from "node:os";
33769
- import path13 from "node:path";
34096
+ import path15 from "node:path";
33770
34097
  import { setTimeout as delay4 } from "node:timers/promises";
33771
34098
  var LOCK_RETRY_COUNT = 200;
33772
34099
  var LOCK_RETRY_DELAY_MS = 25;
@@ -33829,7 +34156,7 @@ async function readLockEntrySnapshot(filePath) {
33829
34156
  throw error51;
33830
34157
  });
33831
34158
  if (metadata === null || !metadata.isFile()) return null;
33832
- const source = await readFile6(filePath, "utf8").catch((error51) => {
34159
+ const source = await readFile8(filePath, "utf8").catch((error51) => {
33833
34160
  if (error51.code === "ENOENT") return null;
33834
34161
  throw error51;
33835
34162
  });
@@ -33840,7 +34167,7 @@ async function readLockEntrySnapshot(filePath) {
33840
34167
  source,
33841
34168
  identity: { dev: metadata.dev, ino: metadata.ino },
33842
34169
  mtimeMs: metadata.mtimeMs,
33843
- record: record3 && path13.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
34170
+ record: record3 && path15.basename(filePath) === lockEntryName(record3.ownerToken) ? record3 : null
33844
34171
  };
33845
34172
  }
33846
34173
  function lockEntryIsAbandoned(snapshot) {
@@ -33852,7 +34179,7 @@ async function removeAbandonedLockEntry(snapshot) {
33852
34179
  if (current === null || current.source !== snapshot.source || !sameUnixFileIdentity(current.identity, snapshot.identity) || !lockEntryIsAbandoned(current)) {
33853
34180
  return false;
33854
34181
  }
33855
- await rm4(snapshot.filePath, { force: true });
34182
+ await rm5(snapshot.filePath, { force: true });
33856
34183
  return true;
33857
34184
  }
33858
34185
  async function readLockEntryCatalog(lockDirectory) {
@@ -33861,7 +34188,7 @@ async function readLockEntryCatalog(lockDirectory) {
33861
34188
  let unsettled = false;
33862
34189
  for (const name of names) {
33863
34190
  if (!name.startsWith(LOCK_ENTRY_PREFIX) || !name.endsWith(LOCK_ENTRY_SUFFIX)) continue;
33864
- const snapshot = await readLockEntrySnapshot(path13.join(lockDirectory, name));
34191
+ const snapshot = await readLockEntrySnapshot(path15.join(lockDirectory, name));
33865
34192
  if (snapshot === null) continue;
33866
34193
  if (lockEntryIsAbandoned(snapshot)) {
33867
34194
  if (!await removeAbandonedLockEntry(snapshot)) unsettled = true;
@@ -33876,7 +34203,7 @@ async function readLockEntryCatalog(lockDirectory) {
33876
34203
  return { entries, unsettled };
33877
34204
  }
33878
34205
  async function preparePrivateLockDirectory(lockDirectory) {
33879
- await mkdir4(lockDirectory, { mode: 448 }).catch((error51) => {
34206
+ await mkdir5(lockDirectory, { mode: 448 }).catch((error51) => {
33880
34207
  if (error51.code !== "EEXIST") throw error51;
33881
34208
  });
33882
34209
  const metadata = await lstat5(lockDirectory);
@@ -33889,7 +34216,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
33889
34216
  await chmod2(lockDirectory, 448);
33890
34217
  }
33891
34218
  async function writeLockRecordAtomic(lockDirectory, entryPath, record3) {
33892
- const temporary = path13.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID9()}`);
34219
+ const temporary = path15.join(lockDirectory, `.tmp-${record3.ownerToken}-${randomUUID10()}`);
33893
34220
  const handle = await open5(temporary, "wx", 384);
33894
34221
  try {
33895
34222
  await handle.writeFile(`${JSON.stringify(record3)}
@@ -33899,15 +34226,15 @@ async function writeLockRecordAtomic(lockDirectory, entryPath, record3) {
33899
34226
  await handle.close();
33900
34227
  }
33901
34228
  try {
33902
- await rename3(temporary, entryPath);
34229
+ await rename4(temporary, entryPath);
33903
34230
  } finally {
33904
- await rm4(temporary, { force: true });
34231
+ await rm5(temporary, { force: true });
33905
34232
  }
33906
34233
  }
33907
34234
  async function removeOwnedLockEntry(entryPath, ownerToken) {
33908
34235
  const snapshot = await readLockEntrySnapshot(entryPath);
33909
34236
  if (snapshot?.record?.ownerToken !== ownerToken) return;
33910
- await rm4(entryPath, { force: true });
34237
+ await rm5(entryPath, { force: true });
33911
34238
  }
33912
34239
  async function legacyLockState(legacyPath) {
33913
34240
  const metadata = await lstat5(legacyPath).catch((error51) => {
@@ -33916,7 +34243,7 @@ async function legacyLockState(legacyPath) {
33916
34243
  });
33917
34244
  if (metadata === null) return "absent";
33918
34245
  if (!metadata.isFile()) return "blocking";
33919
- const source = await readFile6(legacyPath, "utf8").catch((error51) => {
34246
+ const source = await readFile8(legacyPath, "utf8").catch((error51) => {
33920
34247
  if (error51.code === "ENOENT") return null;
33921
34248
  throw error51;
33922
34249
  });
@@ -33953,7 +34280,7 @@ async function releaseLegacyCompatibilityGuard(legacyPath, guard) {
33953
34280
  throw error51;
33954
34281
  });
33955
34282
  if (metadata?.isFile() && sameUnixFileIdentity({ dev: metadata.dev, ino: metadata.ino }, guard.identity)) {
33956
- await rm4(legacyPath, { force: true });
34283
+ await rm5(legacyPath, { force: true });
33957
34284
  }
33958
34285
  }
33959
34286
  }
@@ -33964,8 +34291,8 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
33964
34291
  const legacyPath = `${socketPath}.initializing`;
33965
34292
  const lockDirectory = `${socketPath}.initializers`;
33966
34293
  await preparePrivateLockDirectory(lockDirectory);
33967
- const ownerToken = randomUUID9();
33968
- const entryPath = path13.join(lockDirectory, lockEntryName(ownerToken));
34294
+ const ownerToken = randomUUID10();
34295
+ const entryPath = path15.join(lockDirectory, lockEntryName(ownerToken));
33969
34296
  const baseRecord = {
33970
34297
  version: 2,
33971
34298
  ownerToken,
@@ -34139,14 +34466,14 @@ function remoteAppServerSocketPath(environment, listenUrl = "unix://") {
34139
34466
  throw new Error("Remote app-server listener must use a Unix URL");
34140
34467
  }
34141
34468
  const explicit = listenUrl.slice("unix://".length);
34142
- if (explicit.length > 0) return path14.posix.resolve(decodeURIComponent(explicit));
34143
- const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path14.posix.join(environment.HOME, ".codex") : void 0);
34469
+ if (explicit.length > 0) return path16.posix.resolve(decodeURIComponent(explicit));
34470
+ const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path16.posix.join(environment.HOME, ".codex") : void 0);
34144
34471
  if (!codexHome)
34145
34472
  throw new Error("CODEX_HOME or HOME is required for the remote app-server socket");
34146
- return path14.posix.join(codexHome, "app-server-control", "app-server-control.sock");
34473
+ return path16.posix.join(codexHome, "app-server-control", "app-server-control.sock");
34147
34474
  }
34148
34475
  function officialListenerArgumentsForRemoteListener(arguments_2, socketPath) {
34149
- if (!path14.posix.isAbsolute(socketPath)) {
34476
+ if (!path16.posix.isAbsolute(socketPath)) {
34150
34477
  throw new Error("Shared official app-server socket path must be absolute");
34151
34478
  }
34152
34479
  if (remoteUnixListenerUrl(arguments_2) === null) {
@@ -34254,10 +34581,10 @@ async function removeStaleSocket(socketPath) {
34254
34581
  });
34255
34582
  });
34256
34583
  if (active) throw new Error(`Remote app-server socket is already in use at ${socketPath}`);
34257
- await rm5(socketPath, { force: true });
34584
+ await rm6(socketPath, { force: true });
34258
34585
  }
34259
34586
  async function prepareRemoteAppServerSocketDirectory(socketPath) {
34260
- const socketDirectory = path14.dirname(socketPath);
34587
+ const socketDirectory = path16.dirname(socketPath);
34261
34588
  const existing = await lstat6(socketDirectory).catch((error51) => {
34262
34589
  if (error51.code === "ENOENT") return null;
34263
34590
  throw error51;
@@ -34271,7 +34598,7 @@ async function prepareRemoteAppServerSocketDirectory(socketPath) {
34271
34598
  );
34272
34599
  }
34273
34600
  }
34274
- await mkdir5(socketDirectory, { recursive: true, mode: 448 });
34601
+ await mkdir6(socketDirectory, { recursive: true, mode: 448 });
34275
34602
  await chmod3(socketDirectory, 448);
34276
34603
  }
34277
34604
  function sendOutputFrames(socket, output) {
@@ -34444,7 +34771,7 @@ function createRemoteAppServerWebSocketListener(input) {
34444
34771
  if (ownedSocketIdentity) {
34445
34772
  const current = await unixSocketIdentity(input.socketPath);
34446
34773
  if (current && sameUnixFileIdentity2(current, ownedSocketIdentity)) {
34447
- await rm5(input.socketPath, { force: true });
34774
+ await rm6(input.socketPath, { force: true });
34448
34775
  }
34449
34776
  ownedSocketIdentity = null;
34450
34777
  }
@@ -34462,20 +34789,20 @@ function createRemoteAppServerWebSocketListener(input) {
34462
34789
 
34463
34790
  // packages/host-runtime/src/remote-official-app-server.ts
34464
34791
  import { spawn as spawn3 } from "node:child_process";
34465
- import { randomUUID as randomUUID10 } from "node:crypto";
34466
- import { lstat as lstat7, rm as rm6 } from "node:fs/promises";
34467
- import path15 from "node:path";
34792
+ import { randomUUID as randomUUID11 } from "node:crypto";
34793
+ import { lstat as lstat7, rm as rm7 } from "node:fs/promises";
34794
+ import path17 from "node:path";
34468
34795
  var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
34469
34796
  var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
34470
- function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID10()) {
34471
- if (!path15.posix.isAbsolute(desktopControlSocketPath)) {
34797
+ function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID11()) {
34798
+ if (!path17.posix.isAbsolute(desktopControlSocketPath)) {
34472
34799
  throw new Error("Desktop control socket path must be absolute");
34473
34800
  }
34474
34801
  if (!/^[A-Za-z0-9-]+$/u.test(token) || !/[A-Za-z0-9]/u.test(token)) {
34475
34802
  throw new Error("Shared official app-server socket token is invalid");
34476
34803
  }
34477
34804
  const compactToken = token.replaceAll("-", "").slice(0, 15);
34478
- return path15.posix.join(path15.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
34805
+ return path17.posix.join(path17.posix.dirname(desktopControlSocketPath), `.c-${compactToken}.sock`);
34479
34806
  }
34480
34807
  function errorMessage4(error51) {
34481
34808
  return error51 instanceof Error ? error51.message : String(error51);
@@ -34547,7 +34874,7 @@ function createRemoteOfficialAppServerListener(input) {
34547
34874
  if (ownedSocketIdentity === null) return;
34548
34875
  const current = await socketIdentity(input.socketPath).catch(() => null);
34549
34876
  if (current && sameUnixFileIdentity3(current, ownedSocketIdentity)) {
34550
- await rm6(input.socketPath, { force: true });
34877
+ await rm7(input.socketPath, { force: true });
34551
34878
  }
34552
34879
  ownedSocketIdentity = null;
34553
34880
  };
@@ -34751,7 +35078,10 @@ async function createRemoteOfficialAppServerConnection(endpoint, options2 = {})
34751
35078
  let pending = Buffer.alloc(0);
34752
35079
  let outputPaused = false;
34753
35080
  const webSocketOptions = {
34754
- maxPayload: 128 * 1024 * 1024,
35081
+ // This private native listener can return large history pages, including
35082
+ // images. Match stdio instead of retiring the connection at an arbitrary
35083
+ // response size; ws uses zero for an unlimited payload.
35084
+ maxPayload: 0,
34755
35085
  // The native Codex daemon client uses tokio-tungstenite without offering
34756
35086
  // permessage-deflate. Keep the same handshake for every private listener.
34757
35087
  perMessageDeflate: false,
@@ -34905,7 +35235,7 @@ function createOwnedLoopbackBackend(input) {
34905
35235
  "--ws-auth",
34906
35236
  "capability-token",
34907
35237
  "--ws-token-sha256",
34908
- createHash7("sha256").update(capabilityToken).digest("hex")
35238
+ createHash8("sha256").update(capabilityToken).digest("hex")
34909
35239
  ],
34910
35240
  // Managed stderr may carry credential-bearing errors. Never forward raw bytes.
34911
35241
  diagnosticOutput: new Writable2({
@@ -34958,21 +35288,21 @@ function createOwnedUnixBackend(input) {
34958
35288
 
34959
35289
  // packages/host-runtime/src/native-account-host.ts
34960
35290
  async function canonicalCodexHome(home) {
34961
- const absolute = path16.resolve(home);
35291
+ const absolute = path18.resolve(home);
34962
35292
  try {
34963
35293
  return await realpath3(absolute);
34964
35294
  } catch (error51) {
34965
35295
  if (!(error51 instanceof Error && "code" in error51 && error51.code === "ENOENT")) throw error51;
34966
- const parent = path16.dirname(absolute);
35296
+ const parent = path18.dirname(absolute);
34967
35297
  if (parent === absolute) throw error51;
34968
- return path16.join(await canonicalCodexHome(parent), path16.basename(absolute));
35298
+ return path18.join(await canonicalCodexHome(parent), path18.basename(absolute));
34969
35299
  }
34970
35300
  }
34971
35301
  async function prepareLocalCodex(input) {
34972
35302
  const home = await canonicalCodexHome(
34973
- input.environment.CODEX_HOME ?? path16.join(homedir(), ".codex")
35303
+ input.environment.CODEX_HOME ?? path18.join(homedir(), ".codex")
34974
35304
  );
34975
- await mkdir6(home, { recursive: true });
35305
+ await mkdir7(home, { recursive: true });
34976
35306
  const scope = new OfficialRuntimeScope({
34977
35307
  permanentHome: home,
34978
35308
  diagnosticOutput: input.diagnosticOutput,
@@ -35136,18 +35466,18 @@ var DelegationControlRegistry = class {
35136
35466
  };
35137
35467
 
35138
35468
  // packages/host-runtime/src/installed-harness-plugins.ts
35139
- import os3 from "node:os";
35140
- import path18 from "node:path";
35469
+ import os5 from "node:os";
35470
+ import path20 from "node:path";
35141
35471
  import { fileURLToPath } from "node:url";
35142
35472
 
35143
35473
  // packages/host-runtime/src/launcher-url-opener.ts
35144
35474
  import { spawn as spawn4 } from "node:child_process";
35145
- import path17 from "node:path";
35475
+ import path19 from "node:path";
35146
35476
  var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
35147
35477
  var OPEN_TIMEOUT_MS = 1e4;
35148
35478
  function createLauncherUrlOpener(environment, spawnLauncher = (command, arguments_2, options2) => spawn4(command, arguments_2, options2)) {
35149
35479
  const launcher = environment.CODEXHOST_LAUNCHER_EXECUTABLE;
35150
- if (!launcher || !path17.isAbsolute(launcher)) return void 0;
35480
+ if (!launcher || !path19.isAbsolute(launcher)) return void 0;
35151
35481
  const launcherEnvironment = Object.fromEntries(
35152
35482
  Object.entries(environment).filter(([name]) => {
35153
35483
  const normalized = name.toUpperCase();
@@ -35205,9 +35535,9 @@ function installedHarnessPluginOptions(environment, managedRemoteHost = false, h
35205
35535
  const opener = managedRemoteHost ? void 0 : createLauncherUrlOpener(environment);
35206
35536
  return {
35207
35537
  pluginRoots: [
35208
- path18.join(path18.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
35209
- environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path18.join(
35210
- environment.CODEXHOST_DATA_DIR ? path18.resolve(environment.CODEXHOST_DATA_DIR) : path18.join(os3.homedir(), ".codexhost"),
35538
+ path20.join(path20.dirname(fileURLToPath(hostRuntimeUrl)), "plugins"),
35539
+ environment[HARNESS_PLUGIN_DIRECTORY_ENV] ?? path20.join(
35540
+ environment.CODEXHOST_DATA_DIR ? path20.resolve(environment.CODEXHOST_DATA_DIR) : path20.join(os5.homedir(), ".codexhost"),
35211
35541
  "plugins"
35212
35542
  )
35213
35543
  ],
@@ -35332,12 +35662,12 @@ async function startDelegationControlServer(input) {
35332
35662
  }
35333
35663
 
35334
35664
  // packages/host-runtime/src/delegation-skill.ts
35335
- import { createHash as createHash8, randomUUID as randomUUID11 } from "node:crypto";
35336
- import { mkdir as mkdir7, open as open6, readFile as readFile7, rename as rename4, rm as rm7, stat as stat3 } from "node:fs/promises";
35337
- import os4 from "node:os";
35338
- import path19 from "node:path";
35665
+ import { createHash as createHash9, randomUUID as randomUUID12 } from "node:crypto";
35666
+ import { mkdir as mkdir8, open as open6, readFile as readFile9, rename as rename5, rm as rm8, stat as stat4 } from "node:fs/promises";
35667
+ import os6 from "node:os";
35668
+ import path21 from "node:path";
35339
35669
  var SKILL_VERSION = 7;
35340
- var SKILL_RELATIVE_PATH = path19.join("skills", "codexhost-delegation", "SKILL.md");
35670
+ var SKILL_RELATIVE_PATH = path21.join("skills", "codexhost-delegation", "SKILL.md");
35341
35671
  var PREVIOUS_MANAGED_DIGESTS = [
35342
35672
  "9d2f491850fb0b4084a31ba9b5e4a550b5e833747af322090d8ed0ff80b88c30",
35343
35673
  "2bb0aebb9b06febbc6c0c0bcdb0b32506c7cdbf8dc3b734cc6b2a86621270e4e",
@@ -35393,9 +35723,9 @@ user’s request and the task:
35393
35723
  Report the result returned by read or a completed wait, together with the target
35394
35724
  agent, status, and a labeled task link. Keep internal tracking IDs in tool calls.
35395
35725
  `;
35396
- var CURRENT_DIGEST = createHash8("sha256").update(CODEXHOST_DELEGATION_SKILL).digest("hex");
35726
+ var CURRENT_DIGEST = createHash9("sha256").update(CODEXHOST_DELEGATION_SKILL).digest("hex");
35397
35727
  function digest(value2) {
35398
- return createHash8("sha256").update(value2).digest("hex");
35728
+ return createHash9("sha256").update(value2).digest("hex");
35399
35729
  }
35400
35730
  function managedVersion(value2) {
35401
35731
  const match = /^version:\s*(\d+)\s*$/mu.exec(value2);
@@ -35403,15 +35733,15 @@ function managedVersion(value2) {
35403
35733
  }
35404
35734
  async function readOptional(filePath) {
35405
35735
  try {
35406
- return await readFile7(filePath, "utf8");
35736
+ return await readFile9(filePath, "utf8");
35407
35737
  } catch (error51) {
35408
35738
  if (error51.code === "ENOENT") return null;
35409
35739
  throw error51;
35410
35740
  }
35411
35741
  }
35412
35742
  async function atomicWrite(filePath, content) {
35413
- await mkdir7(path19.dirname(filePath), { recursive: true, mode: 448 });
35414
- const temporaryPath = path19.join(path19.dirname(filePath), `.SKILL.md.${randomUUID11()}.tmp`);
35743
+ await mkdir8(path21.dirname(filePath), { recursive: true, mode: 448 });
35744
+ const temporaryPath = path21.join(path21.dirname(filePath), `.SKILL.md.${randomUUID12()}.tmp`);
35415
35745
  const handle = await open6(temporaryPath, "wx", 384);
35416
35746
  try {
35417
35747
  await handle.writeFile(content, "utf8");
@@ -35420,16 +35750,16 @@ async function atomicWrite(filePath, content) {
35420
35750
  await handle.close();
35421
35751
  }
35422
35752
  try {
35423
- await rename4(temporaryPath, filePath);
35753
+ await rename5(temporaryPath, filePath);
35424
35754
  } finally {
35425
- await rm7(temporaryPath, { force: true });
35755
+ await rm8(temporaryPath, { force: true });
35426
35756
  }
35427
35757
  }
35428
35758
  async function installDelegationSkills(input = {}) {
35429
- const home = input.homeDirectory ?? os4.homedir();
35759
+ const home = input.homeDirectory ?? os6.homedir();
35430
35760
  const destinations = [
35431
- path19.join(home, ".agents", SKILL_RELATIVE_PATH),
35432
- path19.join(home, ".claude", SKILL_RELATIVE_PATH)
35761
+ path21.join(home, ".agents", SKILL_RELATIVE_PATH),
35762
+ path21.join(home, ".claude", SKILL_RELATIVE_PATH)
35433
35763
  ];
35434
35764
  const knownDigests = /* @__PURE__ */ new Set([
35435
35765
  CURRENT_DIGEST,
@@ -35474,8 +35804,8 @@ async function installDelegationSkills(input = {}) {
35474
35804
  }
35475
35805
  for (const result of results) {
35476
35806
  if (result.status === "conflict") continue;
35477
- const source = await readFile7(result.path, "utf8");
35478
- const metadata = await stat3(result.path);
35807
+ const source = await readFile9(result.path, "utf8");
35808
+ const metadata = await stat4(result.path);
35479
35809
  if (!metadata.isFile() || source !== CODEXHOST_DELEGATION_SKILL) {
35480
35810
  throw new Error(`Delegation Skill verification failed: ${result.path}`);
35481
35811
  }
@@ -35485,7 +35815,7 @@ async function installDelegationSkills(input = {}) {
35485
35815
  throw new Error("Delegation Skill copies are inconsistent");
35486
35816
  }
35487
35817
  if (results.every((result) => result.status !== "conflict")) {
35488
- const copies = await Promise.all(results.map((result) => readFile7(result.path, "utf8")));
35818
+ const copies = await Promise.all(results.map((result) => readFile9(result.path, "utf8")));
35489
35819
  if (copies.some((copy) => copy !== copies[0])) {
35490
35820
  throw new Error("Delegation Skill copies are inconsistent");
35491
35821
  }
@@ -35494,9 +35824,9 @@ async function installDelegationSkills(input = {}) {
35494
35824
  }
35495
35825
 
35496
35826
  // packages/host-runtime/src/remote-control-app-server.ts
35497
- import { randomUUID as randomUUID12 } from "node:crypto";
35498
- import { mkdir as mkdir8, open as open7, rename as rename5, rm as rm8 } from "node:fs/promises";
35499
- import path20 from "node:path";
35827
+ import { randomUUID as randomUUID13 } from "node:crypto";
35828
+ import { mkdir as mkdir9, open as open7, rename as rename6, rm as rm9 } from "node:fs/promises";
35829
+ import path22 from "node:path";
35500
35830
  var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
35501
35831
  var REMOTE_CONTROL_BRIDGE_NODE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_NODE_PATH";
35502
35832
  var REMOTE_CONTROL_BRIDGE_RUNTIME_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_RUNTIME_PATH";
@@ -35507,30 +35837,30 @@ var BRIDGE_READY_METHOD = "codexhost/remote-control-bridge/ready";
35507
35837
  function absoluteEnvironmentPath2(environment, name, fallback, platform = process.platform) {
35508
35838
  const value2 = environment[name] ?? fallback;
35509
35839
  if (!value2) return null;
35510
- if (path20.isAbsolute(value2)) return path20.normalize(value2);
35511
- return platform === "win32" && path20.win32.isAbsolute(value2) ? path20.win32.normalize(value2) : null;
35840
+ if (path22.isAbsolute(value2)) return path22.normalize(value2);
35841
+ return platform === "win32" && path22.win32.isAbsolute(value2) ? path22.win32.normalize(value2) : null;
35512
35842
  }
35513
35843
  function nodeCompatibleWindowsPath(value2) {
35514
35844
  if (value2.startsWith("\\\\?\\UNC\\")) return `\\\\${value2.slice(8)}`;
35515
35845
  if (value2.startsWith("\\\\?\\")) return value2.slice(4);
35516
35846
  return value2;
35517
35847
  }
35518
- function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID12()) {
35848
+ function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID13()) {
35519
35849
  const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
35520
35850
  if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
35521
35851
  return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
35522
35852
  }
35523
35853
  function remoteControlBridgeDescriptorPath(environment) {
35524
35854
  const root = environment.LOCALAPPDATA;
35525
- if (!root || !path20.isAbsolute(root)) return null;
35526
- return path20.join(path20.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
35855
+ if (!root || !path22.isAbsolute(root)) return null;
35856
+ return path22.join(path22.normalize(root), "codexhost", REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE);
35527
35857
  }
35528
35858
  async function publishRemoteControlAppServerDescriptor(plan) {
35529
- const directory = path20.dirname(plan.descriptorPath);
35530
- await mkdir8(directory, { recursive: true, mode: 448 });
35531
- const temporaryPath = path20.join(
35859
+ const directory = path22.dirname(plan.descriptorPath);
35860
+ await mkdir9(directory, { recursive: true, mode: 448 });
35861
+ const temporaryPath = path22.join(
35532
35862
  directory,
35533
- `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID12()}.tmp`
35863
+ `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID13()}.tmp`
35534
35864
  );
35535
35865
  const handle = await open7(temporaryPath, "wx", 384);
35536
35866
  try {
@@ -35541,9 +35871,9 @@ async function publishRemoteControlAppServerDescriptor(plan) {
35541
35871
  await handle.close();
35542
35872
  }
35543
35873
  try {
35544
- await rename5(temporaryPath, plan.descriptorPath);
35874
+ await rename6(temporaryPath, plan.descriptorPath);
35545
35875
  } finally {
35546
- await rm8(temporaryPath, { force: true });
35876
+ await rm9(temporaryPath, { force: true });
35547
35877
  }
35548
35878
  }
35549
35879
  function createRemoteControlAppServerPlan(input) {
@@ -35829,9 +36159,9 @@ function hasLauncherManagedUpdateRuntime(environment, hostRuntimePath) {
35829
36159
  if (!environment[UPDATE_RUNTIME_ENV.launcherPid]) return false;
35830
36160
  const npmPackageRoot = environment[UPDATE_RUNTIME_ENV.npmPackageRoot];
35831
36161
  if (!npmPackageRoot || !hostRuntimePath) return true;
35832
- if (!path21.isAbsolute(npmPackageRoot) || !path21.isAbsolute(hostRuntimePath)) return false;
35833
- const runtimePackageRoot = path21.dirname(path21.dirname(path21.normalize(hostRuntimePath)));
35834
- return path21.relative(path21.normalize(npmPackageRoot), runtimePackageRoot) === "";
36162
+ if (!path23.isAbsolute(npmPackageRoot) || !path23.isAbsolute(hostRuntimePath)) return false;
36163
+ const runtimePackageRoot = path23.dirname(path23.dirname(path23.normalize(hostRuntimePath)));
36164
+ return path23.relative(path23.normalize(npmPackageRoot), runtimePackageRoot) === "";
35835
36165
  }
35836
36166
  function requiredRuntimeConfiguration(environment) {
35837
36167
  const stockCodexPath = environment[STOCK_CODEX_PATH_ENV];
@@ -35977,8 +36307,8 @@ async function runHostRuntime(input) {
35977
36307
  const socketPath = remoteAppServerSocketPath(delegationEnvironment, listenUrl);
35978
36308
  const officialPlan = createRemoteOfficialAppServerPlan(input.arguments, socketPath);
35979
36309
  const officialRuntimeScope = new OfficialRuntimeScope({
35980
- permanentHome: path21.resolve(
35981
- delegationEnvironment.CODEX_HOME ?? path21.join(homedir2(), ".codex")
36310
+ permanentHome: path23.resolve(
36311
+ delegationEnvironment.CODEX_HOME ?? path23.join(homedir2(), ".codex")
35982
36312
  ),
35983
36313
  diagnosticOutput: process.stderr,
35984
36314
  createBackend: () => createOwnedUnixBackend({
@@ -36059,22 +36389,22 @@ async function runHostRuntime(input) {
36059
36389
  }
36060
36390
 
36061
36391
  // packages/host-runtime/src/remote-host-install.ts
36062
- import { createHash as createHash9, randomUUID as randomUUID13 } from "node:crypto";
36392
+ import { createHash as createHash10, randomUUID as randomUUID14 } from "node:crypto";
36063
36393
  import { constants as fsConstants } from "node:fs";
36064
36394
  import {
36065
36395
  access,
36066
36396
  chmod as chmod4,
36067
36397
  copyFile as copyFile3,
36068
36398
  lstat as lstat8,
36069
- mkdir as mkdir9,
36070
- readFile as readFile8,
36071
- rename as rename6,
36072
- rm as rm9,
36399
+ mkdir as mkdir10,
36400
+ readFile as readFile10,
36401
+ rename as rename7,
36402
+ rm as rm10,
36073
36403
  rmdir,
36074
- stat as stat4,
36075
- writeFile as writeFile3
36404
+ stat as stat5,
36405
+ writeFile as writeFile4
36076
36406
  } from "node:fs/promises";
36077
- import path22 from "node:path";
36407
+ import path24 from "node:path";
36078
36408
  var MANIFEST_FORMAT = 1;
36079
36409
  var WRAPPER_MARKER = "# codexhost remote SSH wrapper v1";
36080
36410
  var PROFILE_START = "# >>> codexhost remote SSH >>>";
@@ -36085,25 +36415,25 @@ function resolvePaths(options2) {
36085
36415
  if (!configuredHome) {
36086
36416
  throw new Error("A non-root HOME is required for remote Host installation");
36087
36417
  }
36088
- const home = path22.resolve(configuredHome);
36089
- if (!home || home === path22.parse(home).root) {
36418
+ const home = path24.resolve(configuredHome);
36419
+ if (!home || home === path24.parse(home).root) {
36090
36420
  throw new Error("A non-root HOME is required for remote Host installation");
36091
36421
  }
36092
- const installRoot = path22.resolve(options2.installRoot ?? path22.join(home, ".codexhost", "remote"));
36093
- const profilePath = path22.resolve(
36094
- options2.profilePath ?? path22.join(
36422
+ const installRoot = path24.resolve(options2.installRoot ?? path24.join(home, ".codexhost", "remote"));
36423
+ const profilePath = path24.resolve(
36424
+ options2.profilePath ?? path24.join(
36095
36425
  home,
36096
- path22.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path22.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
36426
+ path24.basename(environment.SHELL ?? "") === "zsh" ? ".zshenv" : path24.basename(environment.SHELL ?? "") === "bash" ? ".bashrc" : ".profile"
36097
36427
  )
36098
36428
  );
36099
- const binDirectory = path22.join(installRoot, "bin");
36429
+ const binDirectory = path24.join(installRoot, "bin");
36100
36430
  return {
36101
36431
  home,
36102
36432
  installRoot,
36103
36433
  binDirectory,
36104
- wrapperPath: path22.join(binDirectory, "codex"),
36105
- manifestPath: path22.join(installRoot, "manifest.json"),
36106
- dataDirectory: path22.join(installRoot, "data"),
36434
+ wrapperPath: path24.join(binDirectory, "codex"),
36435
+ manifestPath: path24.join(installRoot, "manifest.json"),
36436
+ dataDirectory: path24.join(installRoot, "data"),
36107
36437
  profilePath
36108
36438
  };
36109
36439
  }
@@ -36112,19 +36442,19 @@ function shellQuote(value2) {
36112
36442
  }
36113
36443
  async function existingText(filePath) {
36114
36444
  try {
36115
- return await readFile8(filePath, "utf8");
36445
+ return await readFile10(filePath, "utf8");
36116
36446
  } catch (error51) {
36117
36447
  if (error51.code === "ENOENT") return null;
36118
36448
  throw error51;
36119
36449
  }
36120
36450
  }
36121
36451
  async function fileSha256(filePath) {
36122
- return createHash9("sha256").update(await readFile8(filePath)).digest("hex");
36452
+ return createHash10("sha256").update(await readFile10(filePath)).digest("hex");
36123
36453
  }
36124
36454
  async function executable(filePath, label) {
36125
- const absolute = path22.resolve(filePath);
36455
+ const absolute = path24.resolve(filePath);
36126
36456
  try {
36127
- if (!(await stat4(absolute)).isFile()) throw new Error("not a regular file");
36457
+ if (!(await stat5(absolute)).isFile()) throw new Error("not a regular file");
36128
36458
  await access(absolute, fsConstants.X_OK);
36129
36459
  } catch {
36130
36460
  throw new Error(`${label} is not an executable file: ${absolute}`);
@@ -36132,9 +36462,9 @@ async function executable(filePath, label) {
36132
36462
  return absolute;
36133
36463
  }
36134
36464
  async function existingFile(filePath, label) {
36135
- const absolute = path22.resolve(filePath);
36465
+ const absolute = path24.resolve(filePath);
36136
36466
  try {
36137
- const metadata = await stat4(absolute);
36467
+ const metadata = await stat5(absolute);
36138
36468
  if (!metadata.isFile()) throw new Error("not a regular file");
36139
36469
  } catch {
36140
36470
  throw new Error(`${label} is not a regular file: ${absolute}`);
@@ -36142,9 +36472,9 @@ async function existingFile(filePath, label) {
36142
36472
  return absolute;
36143
36473
  }
36144
36474
  async function discoverExecutable(name, environment) {
36145
- for (const directory of (environment.PATH ?? "").split(path22.delimiter)) {
36475
+ for (const directory of (environment.PATH ?? "").split(path24.delimiter)) {
36146
36476
  if (!directory) continue;
36147
- const candidate = path22.resolve(directory, name);
36477
+ const candidate = path24.resolve(directory, name);
36148
36478
  try {
36149
36479
  await access(candidate, fsConstants.X_OK);
36150
36480
  return candidate;
@@ -36155,47 +36485,47 @@ async function discoverExecutable(name, environment) {
36155
36485
  return null;
36156
36486
  }
36157
36487
  async function writeAtomic(filePath, contents, mode) {
36158
- await mkdir9(path22.dirname(filePath), { recursive: true, mode: 448 });
36159
- const temporary = path22.join(
36160
- path22.dirname(filePath),
36161
- `.${path22.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
36488
+ await mkdir10(path24.dirname(filePath), { recursive: true, mode: 448 });
36489
+ const temporary = path24.join(
36490
+ path24.dirname(filePath),
36491
+ `.${path24.basename(filePath)}.${process.pid}.${randomUUID14()}.tmp`
36162
36492
  );
36163
36493
  try {
36164
36494
  if (typeof contents === "string") {
36165
- await writeFile3(temporary, contents, { encoding: "utf8", flag: "wx", mode });
36495
+ await writeFile4(temporary, contents, { encoding: "utf8", flag: "wx", mode });
36166
36496
  } else {
36167
- await writeFile3(temporary, contents, { flag: "wx", mode });
36497
+ await writeFile4(temporary, contents, { flag: "wx", mode });
36168
36498
  }
36169
36499
  await chmod4(temporary, mode);
36170
36500
  try {
36171
- await rename6(temporary, filePath);
36501
+ await rename7(temporary, filePath);
36172
36502
  } catch (error51) {
36173
36503
  if (process.platform !== "win32") throw error51;
36174
- await rm9(filePath, { force: true });
36175
- await rename6(temporary, filePath);
36504
+ await rm10(filePath, { force: true });
36505
+ await rename7(temporary, filePath);
36176
36506
  }
36177
36507
  } finally {
36178
- await rm9(temporary, { force: true });
36508
+ await rm10(temporary, { force: true });
36179
36509
  }
36180
36510
  }
36181
36511
  async function writeAtomicExecutable(filePath, sourcePath) {
36182
- await mkdir9(path22.dirname(filePath), { recursive: true, mode: 448 });
36183
- const temporary = path22.join(
36184
- path22.dirname(filePath),
36185
- `.${path22.basename(filePath)}.${process.pid}.${randomUUID13()}.tmp`
36512
+ await mkdir10(path24.dirname(filePath), { recursive: true, mode: 448 });
36513
+ const temporary = path24.join(
36514
+ path24.dirname(filePath),
36515
+ `.${path24.basename(filePath)}.${process.pid}.${randomUUID14()}.tmp`
36186
36516
  );
36187
36517
  try {
36188
36518
  await copyFile3(sourcePath, temporary);
36189
36519
  await chmod4(temporary, 448);
36190
36520
  try {
36191
- await rename6(temporary, filePath);
36521
+ await rename7(temporary, filePath);
36192
36522
  } catch (error51) {
36193
36523
  if (process.platform !== "win32") throw error51;
36194
- await rm9(filePath, { force: true });
36195
- await rename6(temporary, filePath);
36524
+ await rm10(filePath, { force: true });
36525
+ await rename7(temporary, filePath);
36196
36526
  }
36197
36527
  } finally {
36198
- await rm9(temporary, { force: true });
36528
+ await rm10(temporary, { force: true });
36199
36529
  }
36200
36530
  }
36201
36531
  function managedBlockRange(contents) {
@@ -36223,15 +36553,14 @@ function removeManagedProfileBlock(contents) {
36223
36553
  function installManagedProfileBlock(contents, manifest) {
36224
36554
  const base = removeManagedProfileBlock(contents);
36225
36555
  const environment = [
36226
- `export CODEX_INSTALL_DIR=${shellQuote(path22.dirname(manifest.wrapperPath))}`,
36227
- `export PATH=${shellQuote(path22.dirname(manifest.wrapperPath))}:${shellQuote(path22.dirname(manifest.nodePath))}:${shellQuote(path22.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
36556
+ `export CODEX_INSTALL_DIR=${shellQuote(path24.dirname(manifest.wrapperPath))}`,
36557
+ `export PATH=${shellQuote(path24.dirname(manifest.wrapperPath))}:${shellQuote(path24.dirname(manifest.nodePath))}:${shellQuote(path24.dirname(manifest.stockCodexPath))}:"\${PATH:-/usr/local/bin:/usr/bin:/bin}"`,
36228
36558
  `export CODEXHOST_STOCK_CODEX_PATH=${shellQuote(manifest.stockCodexPath)}`,
36229
36559
  `export CODEXHOST_HOST_NODE_PATH=${shellQuote(manifest.nodePath)}`,
36230
36560
  `export CODEXHOST_HOST_RUNTIME_PATH=${shellQuote(manifest.hostRuntimePath)}`,
36231
36561
  `export CODEXHOST_DATA_DIR=${shellQuote(manifest.dataDirectory)}`,
36232
36562
  "export CODEXHOST_DEFAULT_AGENT='codex'",
36233
- "export CODEXHOST_REMOTE_SSH_MANAGED='1'",
36234
- ...manifest.claudeCommand ? [`export CODEXHOST_CLAUDE_COMMAND=${shellQuote(manifest.claudeCommand)}`] : []
36563
+ "export CODEXHOST_REMOTE_SSH_MANAGED='1'"
36235
36564
  ];
36236
36565
  const block = [
36237
36566
  PROFILE_START,
@@ -36241,7 +36570,7 @@ function installManagedProfileBlock(contents, manifest) {
36241
36570
  PROFILE_END,
36242
36571
  ""
36243
36572
  ].join("\n");
36244
- if (path22.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
36573
+ if (path24.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
36245
36574
  const separator = base.length > 0 && !base.endsWith("\n") ? "\n" : "";
36246
36575
  return `${base}${separator}${block}`;
36247
36576
  }
@@ -36253,16 +36582,16 @@ async function managedEntrypointState(manifest) {
36253
36582
  if (metadata === null) return "missing";
36254
36583
  if (!metadata.isFile()) return "modified";
36255
36584
  if (process.platform !== "win32" && (metadata.mode & 73) === 0) return "modified";
36256
- const entrypoint = await readFile8(manifest.wrapperPath);
36585
+ const entrypoint = await readFile10(manifest.wrapperPath);
36257
36586
  if (entrypoint.subarray(0, 256).toString("utf8").startsWith(`#!/usr/bin/env sh
36258
36587
  ${WRAPPER_MARKER}
36259
36588
  `)) {
36260
36589
  return "legacy-wrapper";
36261
36590
  }
36262
36591
  if (manifest.entrypointSha256 !== void 0) {
36263
- return createHash9("sha256").update(entrypoint).digest("hex") === manifest.entrypointSha256 ? "native" : "modified";
36592
+ return createHash10("sha256").update(entrypoint).digest("hex") === manifest.entrypointSha256 ? "native" : "modified";
36264
36593
  }
36265
- const shim = await readFile8(manifest.shimPath).catch((error51) => {
36594
+ const shim = await readFile10(manifest.shimPath).catch((error51) => {
36266
36595
  if (error51.code === "ENOENT") return null;
36267
36596
  throw error51;
36268
36597
  });
@@ -36293,6 +36622,7 @@ async function readManifest(filePath) {
36293
36622
  "dataDirectory",
36294
36623
  "entrypointSha256",
36295
36624
  "claudeCommand",
36625
+ // Inert metadata accepted from older format-1 manifests.
36296
36626
  "profileBackupPath"
36297
36627
  ]);
36298
36628
  const requiredPaths = [
@@ -36306,9 +36636,9 @@ async function readManifest(filePath) {
36306
36636
  ];
36307
36637
  const optionalPaths = ["claudeCommand", "profileBackupPath"];
36308
36638
  if (manifest.format !== MANIFEST_FORMAT || Object.keys(manifest).some((key) => !allowed.has(key)) || requiredPaths.some(
36309
- (key) => typeof manifest[key] !== "string" || !path22.isAbsolute(manifest[key])
36639
+ (key) => typeof manifest[key] !== "string" || !path24.isAbsolute(manifest[key])
36310
36640
  ) || optionalPaths.some(
36311
- (key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path22.isAbsolute(manifest[key]))
36641
+ (key) => manifest[key] !== void 0 && (typeof manifest[key] !== "string" || !path24.isAbsolute(manifest[key]))
36312
36642
  ) || manifest.entrypointSha256 !== void 0 && (typeof manifest.entrypointSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(manifest.entrypointSha256))) {
36313
36643
  throw new Error("Remote Host manifest has an unsupported format");
36314
36644
  }
@@ -36317,7 +36647,7 @@ async function readManifest(filePath) {
36317
36647
  async function backupProfile(profilePath, contents, action) {
36318
36648
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(/[-:.TZ]/gu, "");
36319
36649
  const backupPath = `${profilePath}.codexhost-${action}-${timestamp}.bak`;
36320
- const metadata = await stat4(profilePath).catch(() => null);
36650
+ const metadata = await stat5(profilePath).catch(() => null);
36321
36651
  await writeAtomic(backupPath, contents, metadata?.mode ?? 384);
36322
36652
  return backupPath;
36323
36653
  }
@@ -36330,8 +36660,8 @@ async function installRemoteHost(options2) {
36330
36660
  const paths = resolvePaths(options2);
36331
36661
  const previousManifest = await readManifest(paths.manifestPath);
36332
36662
  const previousManifestFile = previousManifest ? {
36333
- contents: await readFile8(paths.manifestPath),
36334
- mode: (await stat4(paths.manifestPath)).mode & 511
36663
+ contents: await readFile10(paths.manifestPath),
36664
+ mode: (await stat5(paths.manifestPath)).mode & 511
36335
36665
  } : null;
36336
36666
  const existingEntrypoint = await lstat8(paths.wrapperPath).catch(
36337
36667
  (error51) => {
@@ -36355,7 +36685,7 @@ async function installRemoteHost(options2) {
36355
36685
  }
36356
36686
  const profilePath = previousManifest?.profilePath ?? paths.profilePath;
36357
36687
  const previousEntrypoint = existingEntrypoint?.isFile() ? {
36358
- contents: await readFile8(paths.wrapperPath),
36688
+ contents: await readFile10(paths.wrapperPath),
36359
36689
  mode: existingEntrypoint.mode & 511
36360
36690
  } : null;
36361
36691
  const discoveredStock = options2.stockCodexPath ?? previousManifest?.stockCodexPath ?? await discoverExecutable("codex", environment);
@@ -36372,8 +36702,6 @@ async function installRemoteHost(options2) {
36372
36702
  const nodePath2 = await executable(options2.nodePath, "Node runtime");
36373
36703
  const shimPath = await executable(options2.shimPath, "codexhost Shim");
36374
36704
  const hostRuntimePath = await existingFile(options2.hostRuntimePath, "codexhost Host Runtime");
36375
- const discoveredClaude = options2.claudeCommand ?? previousManifest?.claudeCommand ?? await discoverExecutable("claude", environment);
36376
- const claudeCommand = discoveredClaude ? await executable(discoveredClaude, "Claude Code command") : void 0;
36377
36705
  let manifest = {
36378
36706
  format: MANIFEST_FORMAT,
36379
36707
  wrapperPath: paths.wrapperPath,
@@ -36383,21 +36711,20 @@ async function installRemoteHost(options2) {
36383
36711
  shimPath,
36384
36712
  hostRuntimePath,
36385
36713
  dataDirectory: paths.dataDirectory,
36386
- ...claudeCommand ? { claudeCommand } : {},
36387
36714
  ...previousManifest?.profileBackupPath ? { profileBackupPath: previousManifest.profileBackupPath } : {}
36388
36715
  };
36389
36716
  const existingProfileSource = await existingText(profilePath);
36390
36717
  const existingProfile = existingProfileSource ?? "";
36391
36718
  const nextProfile = installManagedProfileBlock(existingProfile, manifest);
36392
36719
  const profileChanged = nextProfile !== existingProfile;
36393
- const profileMetadata = await stat4(profilePath).catch(() => null);
36720
+ const profileMetadata = await stat5(profilePath).catch(() => null);
36394
36721
  try {
36395
36722
  if (profileChanged) {
36396
36723
  const profileBackupPath = await backupProfile(profilePath, existingProfile, "install");
36397
36724
  manifest = { ...manifest, profileBackupPath };
36398
36725
  await writeAtomic(profilePath, nextProfile, profileMetadata?.mode ?? 384);
36399
36726
  }
36400
- await mkdir9(paths.dataDirectory, { recursive: true, mode: 448 });
36727
+ await mkdir10(paths.dataDirectory, { recursive: true, mode: 448 });
36401
36728
  await chmod4(paths.dataDirectory, 448);
36402
36729
  await writeAtomicExecutable(paths.wrapperPath, manifest.shimPath);
36403
36730
  manifest = { ...manifest, entrypointSha256: await fileSha256(paths.wrapperPath) };
@@ -36410,7 +36737,7 @@ async function installRemoteHost(options2) {
36410
36737
  if (previousEntrypoint) {
36411
36738
  await writeAtomic(paths.wrapperPath, previousEntrypoint.contents, previousEntrypoint.mode);
36412
36739
  } else {
36413
- await rm9(paths.wrapperPath, { force: true });
36740
+ await rm10(paths.wrapperPath, { force: true });
36414
36741
  }
36415
36742
  } catch (rollbackError) {
36416
36743
  rollbackErrors.push(rollbackError);
@@ -36418,7 +36745,7 @@ async function installRemoteHost(options2) {
36418
36745
  if (profileChanged) {
36419
36746
  try {
36420
36747
  if (existingProfileSource === null) {
36421
- await rm9(profilePath, { force: true });
36748
+ await rm10(profilePath, { force: true });
36422
36749
  } else {
36423
36750
  await writeAtomic(profilePath, existingProfile, profileMetadata?.mode ?? 384);
36424
36751
  }
@@ -36434,7 +36761,7 @@ async function installRemoteHost(options2) {
36434
36761
  previousManifestFile.mode
36435
36762
  );
36436
36763
  } else {
36437
- await rm9(paths.manifestPath, { force: true });
36764
+ await rm10(paths.manifestPath, { force: true });
36438
36765
  }
36439
36766
  } catch (rollbackError) {
36440
36767
  rollbackErrors.push(rollbackError);
@@ -36481,7 +36808,7 @@ async function inspectRemoteHostInstallation(options2) {
36481
36808
  if (!profileMatches && profileIssue === null)
36482
36809
  profileIssue = "shell profile does not configure the managed native entrypoint";
36483
36810
  if (profileIssue !== null) issues.push(profileIssue);
36484
- const dataDirectory = await stat4(manifest.dataDirectory).catch(() => null);
36811
+ const dataDirectory = await stat5(manifest.dataDirectory).catch(() => null);
36485
36812
  if (!dataDirectory?.isDirectory()) issues.push("remote Host data directory is unavailable");
36486
36813
  for (const [label, filePath, requiresExecutable] of [
36487
36814
  ["stock Codex", manifest.stockCodexPath, true],
@@ -36491,7 +36818,7 @@ async function inspectRemoteHostInstallation(options2) {
36491
36818
  ]) {
36492
36819
  try {
36493
36820
  if (requiresExecutable) await executable(filePath, label);
36494
- else if (!(await stat4(filePath)).isFile()) throw new Error("not a regular file");
36821
+ else if (!(await stat5(filePath)).isFile()) throw new Error("not a regular file");
36495
36822
  } catch {
36496
36823
  issues.push(`${label} is unavailable`);
36497
36824
  }
@@ -36520,11 +36847,11 @@ async function uninstallRemoteHost(options2) {
36520
36847
  const nextProfile = removeManagedProfileBlock(profile);
36521
36848
  if (nextProfile !== profile) {
36522
36849
  await backupProfile(manifest.profilePath, profile, "uninstall");
36523
- const metadata = await stat4(manifest.profilePath).catch(() => null);
36850
+ const metadata = await stat5(manifest.profilePath).catch(() => null);
36524
36851
  await writeAtomic(manifest.profilePath, nextProfile, metadata?.mode ?? 384);
36525
36852
  }
36526
- await rm9(manifest.wrapperPath, { force: true });
36527
- await rm9(paths.manifestPath, { force: true });
36853
+ await rm10(manifest.wrapperPath, { force: true });
36854
+ await rm10(paths.manifestPath, { force: true });
36528
36855
  await rmdir(paths.binDirectory).catch((error51) => {
36529
36856
  if (error51.code !== "ENOENT" && error51.code !== "ENOTEMPTY") throw error51;
36530
36857
  });
@@ -36535,9 +36862,9 @@ async function uninstallRemoteHost(options2) {
36535
36862
 
36536
36863
  // packages/host-runtime/src/remote-host-lifecycle.ts
36537
36864
  import { spawn as spawn5 } from "node:child_process";
36538
- import { stat as stat5 } from "node:fs/promises";
36865
+ import { stat as stat6 } from "node:fs/promises";
36539
36866
  import net3 from "node:net";
36540
- import path23 from "node:path";
36867
+ import path25 from "node:path";
36541
36868
  import { Duplex } from "node:stream";
36542
36869
 
36543
36870
  // packages/host-runtime/src/app-server-websocket-options.ts
@@ -36564,12 +36891,12 @@ function classifyRemoteHostProbeResponse(response, socketPath) {
36564
36891
  }
36565
36892
  var lifecycleDependencyOverrides = {};
36566
36893
  function socketPathFor(environment) {
36567
- const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path23.join(environment.HOME, ".codex") : void 0);
36894
+ const codexHome = environment.CODEX_HOME ?? (environment.HOME ? path25.join(environment.HOME, ".codex") : void 0);
36568
36895
  if (!codexHome) throw new Error("CODEX_HOME or HOME is required for remote Host lifecycle");
36569
- return path23.join(codexHome, "app-server-control", "app-server-control.sock");
36896
+ return path25.join(codexHome, "app-server-control", "app-server-control.sock");
36570
36897
  }
36571
36898
  async function defaultSocketExists(socketPath) {
36572
- const metadata = await stat5(socketPath).catch((error51) => {
36899
+ const metadata = await stat6(socketPath).catch((error51) => {
36573
36900
  if (error51.code === "ENOENT") return null;
36574
36901
  throw error51;
36575
36902
  });
@@ -36696,15 +37023,14 @@ function installedManifest(status) {
36696
37023
  function managedEnvironment(manifest, environment) {
36697
37024
  return {
36698
37025
  ...environment,
36699
- CODEX_INSTALL_DIR: path23.dirname(manifest.wrapperPath),
37026
+ CODEX_INSTALL_DIR: path25.dirname(manifest.wrapperPath),
36700
37027
  CODEXHOST_STOCK_CODEX_PATH: manifest.stockCodexPath,
36701
37028
  CODEXHOST_HOST_NODE_PATH: manifest.nodePath,
36702
37029
  CODEXHOST_HOST_RUNTIME_PATH: manifest.hostRuntimePath,
36703
37030
  CODEXHOST_DATA_DIR: manifest.dataDirectory,
36704
37031
  CODEXHOST_DEFAULT_AGENT: "codex",
36705
37032
  CODEXHOST_REMOTE_SSH_MANAGED: "1",
36706
- ...manifest.claudeCommand ? { CODEXHOST_CLAUDE_COMMAND: manifest.claudeCommand } : {},
36707
- PATH: `${path23.dirname(manifest.wrapperPath)}${path23.delimiter}${path23.dirname(manifest.stockCodexPath)}${path23.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
37033
+ PATH: `${path25.dirname(manifest.wrapperPath)}${path25.delimiter}${path25.dirname(manifest.stockCodexPath)}${path25.delimiter}${environment.PATH ?? "/usr/bin:/bin"}`
36708
37034
  };
36709
37035
  }
36710
37036
  async function defaultRunTerminator(manifest, socketPath, role, environment) {
@@ -36852,9 +37178,6 @@ function parseRemoteCliArguments(arguments_2) {
36852
37178
  case "--stock-codex":
36853
37179
  options2.stockCodexPath = value2;
36854
37180
  break;
36855
- case "--claude-command":
36856
- options2.claudeCommand = value2;
36857
- break;
36858
37181
  case "--node":
36859
37182
  resources.nodePath = value2;
36860
37183
  break;
@@ -36881,7 +37204,7 @@ async function runRemoteHostCli(input) {
36881
37204
  output.write(
36882
37205
  [
36883
37206
  "usage:",
36884
- " boft remote install [--stock-codex PATH] [--claude-command PATH]",
37207
+ " boft remote install [--stock-codex PATH]",
36885
37208
  " boft remote start",
36886
37209
  " boft remote stop",
36887
37210
  " boft remote status",
@@ -37045,26 +37368,26 @@ function consumeBrokerFrames(socket, onFrame, onError) {
37045
37368
  }
37046
37369
 
37047
37370
  // packages/harness-broker/dist/paths.js
37048
- import os5 from "node:os";
37049
- import path24 from "node:path";
37371
+ import os7 from "node:os";
37372
+ import path26 from "node:path";
37050
37373
  var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
37051
37374
  var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
37052
37375
  var HARNESS_BROKER_SOCKET_FILE = "claude-code-broker-v1.sock";
37053
37376
  function defaultHarnessBrokerDirectory(environment = process.env) {
37054
- const home = environment.HOME || os5.homedir();
37055
- return path24.join(home, ".codexhost", "harness-broker");
37377
+ const home = environment.HOME || os7.homedir();
37378
+ return path26.join(home, ".codexhost", "harness-broker");
37056
37379
  }
37057
37380
  function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
37058
37381
  harnessPluginIdSchema.parse(harnessId);
37059
37382
  if (harnessId !== "claude-code")
37060
- return path24.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
37061
- return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path24.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
37383
+ return path26.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
37384
+ return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path26.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
37062
37385
  }
37063
37386
  function defaultHarnessBrokerSocketPath(environment = process.env, harnessId = "claude-code") {
37064
37387
  harnessPluginIdSchema.parse(harnessId);
37065
37388
  if (harnessId !== "claude-code")
37066
- return path24.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.sock`);
37067
- return path24.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
37389
+ return path26.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.sock`);
37390
+ return path26.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_SOCKET_FILE);
37068
37391
  }
37069
37392
 
37070
37393
  // packages/harness-broker/dist/validation.js
@@ -37298,10 +37621,10 @@ var harnessOutputSchema = external_exports.custom((value2) => {
37298
37621
  });
37299
37622
 
37300
37623
  // packages/harness-broker/dist/server.js
37301
- import { randomBytes as randomBytes3, randomUUID as randomUUID14 } from "node:crypto";
37302
- import { chmod as chmod5, lstat as lstat9, mkdir as mkdir10, open as open8, readFile as readFile9, rename as rename7, rm as rm10 } from "node:fs/promises";
37624
+ import { randomBytes as randomBytes3, randomUUID as randomUUID15 } from "node:crypto";
37625
+ import { chmod as chmod5, lstat as lstat9, mkdir as mkdir11, open as open8, readFile as readFile11, rename as rename8, rm as rm11 } from "node:fs/promises";
37303
37626
  import net4, {} from "node:net";
37304
- import path25 from "node:path";
37627
+ import path27 from "node:path";
37305
37628
  function harnessError(message, retryable = true) {
37306
37629
  return { code: "unavailable", message, retryable, stage: "harnessBroker" };
37307
37630
  }
@@ -37312,7 +37635,7 @@ function nativeWriterKey(nativeSessionId) {
37312
37635
  return nativeSessionId;
37313
37636
  }
37314
37637
  async function privateDirectory(directory) {
37315
- await mkdir10(directory, { recursive: true, mode: 448 });
37638
+ await mkdir11(directory, { recursive: true, mode: 448 });
37316
37639
  if (process.platform === "win32")
37317
37640
  return;
37318
37641
  const metadata = await lstat9(directory);
@@ -37347,7 +37670,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
37347
37670
  throw new Error("Harness broker descriptor is not owner-only");
37348
37671
  }
37349
37672
  }
37350
- const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile9(descriptorPath, "utf8")));
37673
+ const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile11(descriptorPath, "utf8")));
37351
37674
  if (processIsAlive2(descriptor.ownerPid)) {
37352
37675
  throw new Error("Harness broker descriptor already has a live owner");
37353
37676
  }
@@ -37357,7 +37680,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
37357
37680
  }
37358
37681
  }
37359
37682
  async function publishDescriptor(descriptorPath, descriptor) {
37360
- const temporary = `${descriptorPath}.${process.pid}.${randomUUID14()}.tmp`;
37683
+ const temporary = `${descriptorPath}.${process.pid}.${randomUUID15()}.tmp`;
37361
37684
  const handle = await open8(temporary, "wx", 384);
37362
37685
  try {
37363
37686
  await handle.writeFile(`${JSON.stringify(descriptor)}
@@ -37366,7 +37689,7 @@ async function publishDescriptor(descriptorPath, descriptor) {
37366
37689
  } finally {
37367
37690
  await handle.close();
37368
37691
  }
37369
- await rename7(temporary, descriptorPath);
37692
+ await rename8(temporary, descriptorPath);
37370
37693
  if (process.platform !== "win32")
37371
37694
  await chmod5(descriptorPath, 384);
37372
37695
  }
@@ -37416,7 +37739,7 @@ async function prepareUnixSocketPath(socketPath) {
37416
37739
  if (await socketAcceptsConnections(socketPath)) {
37417
37740
  throw new Error("Harness broker socket is already active");
37418
37741
  }
37419
- await rm10(socketPath);
37742
+ await rm11(socketPath);
37420
37743
  } catch (error51) {
37421
37744
  if (error51.code !== "ENOENT")
37422
37745
  throw error51;
@@ -37424,17 +37747,17 @@ async function prepareUnixSocketPath(socketPath) {
37424
37747
  }
37425
37748
  async function startHarnessBrokerServer(input) {
37426
37749
  harnessPluginIdSchema.parse(input.adapter.harnessId);
37427
- if (process.platform !== "win32" && path25.dirname(input.descriptorPath) !== path25.dirname(input.socketPath)) {
37750
+ if (process.platform !== "win32" && path27.dirname(input.descriptorPath) !== path27.dirname(input.socketPath)) {
37428
37751
  throw new Error("Harness broker descriptor and socket must share one private directory");
37429
37752
  }
37430
37753
  if (process.platform === "darwin" && Buffer.byteLength(input.socketPath) > 103) {
37431
37754
  throw new Error("Harness broker Unix socket path is too long for macOS");
37432
37755
  }
37433
- await privateDirectory(path25.dirname(input.descriptorPath));
37756
+ await privateDirectory(path27.dirname(input.descriptorPath));
37434
37757
  await assertNoLiveDescriptor(input.descriptorPath);
37435
37758
  if (process.platform !== "win32")
37436
37759
  await prepareUnixSocketPath(input.socketPath);
37437
- const generation = input.generation ?? randomUUID14();
37760
+ const generation = input.generation ?? randomUUID15();
37438
37761
  const token = input.token ?? randomBytes3(32).toString("hex");
37439
37762
  const descriptor = {
37440
37763
  schemaVersion: 1,
@@ -37452,7 +37775,7 @@ async function startHarnessBrokerServer(input) {
37452
37775
  let closed = false;
37453
37776
  const server = net4.createServer((socket) => {
37454
37777
  const state = {
37455
- id: randomUUID14(),
37778
+ id: randomUUID15(),
37456
37779
  socket,
37457
37780
  authenticated: false,
37458
37781
  inputSequence: 0,
@@ -37711,7 +38034,7 @@ async function startHarnessBrokerServer(input) {
37711
38034
  }
37712
38035
  };
37713
38036
  }
37714
- const openReservation = randomUUID14();
38037
+ const openReservation = randomUUID15();
37715
38038
  if (sourceKey)
37716
38039
  nativeWriters.set(sourceKey, openReservation);
37717
38040
  const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
@@ -37991,7 +38314,7 @@ async function startHarnessBrokerServer(input) {
37991
38314
  }
37992
38315
  state.authenticated = true;
37993
38316
  state.inputSequence = 1;
37994
- await send({ kind: "response", id: randomUUID14(), ok: true, value: { ready: true } });
38317
+ await send({ kind: "response", id: randomUUID15(), ok: true, value: { ready: true } });
37995
38318
  return;
37996
38319
  }
37997
38320
  const parsed = harnessBrokerRequestSchema.safeParse(raw);
@@ -38039,7 +38362,7 @@ async function startHarnessBrokerServer(input) {
38039
38362
  } catch (error51) {
38040
38363
  await new Promise((resolve) => server.close(() => resolve()));
38041
38364
  if (process.platform !== "win32")
38042
- await rm10(input.socketPath, { force: true });
38365
+ await rm11(input.socketPath, { force: true });
38043
38366
  throw error51;
38044
38367
  }
38045
38368
  return {
@@ -38057,8 +38380,8 @@ async function startHarnessBrokerServer(input) {
38057
38380
  await input.adapter.close().catch(() => void 0);
38058
38381
  await new Promise((resolve) => server.close(() => resolve()));
38059
38382
  if (process.platform !== "win32")
38060
- await rm10(input.socketPath, { force: true });
38061
- await rm10(input.descriptorPath, { force: true });
38383
+ await rm11(input.socketPath, { force: true });
38384
+ await rm11(input.descriptorPath, { force: true });
38062
38385
  }
38063
38386
  };
38064
38387
  }