remote-codex 0.11.11 → 0.11.12

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.
@@ -8,9 +8,9 @@ var __export = (target, all) => {
8
8
  import Fastify from "fastify";
9
9
  import multipart from "@fastify/multipart";
10
10
  import websocket from "@fastify/websocket";
11
- import { spawn as spawn5 } from "child_process";
11
+ import { spawn as spawn6 } from "child_process";
12
12
  import fs26 from "fs";
13
- import path25 from "path";
13
+ import path26 from "path";
14
14
  import { ZodError } from "zod";
15
15
 
16
16
  // ../../packages/config/src/index.ts
@@ -2316,7 +2316,7 @@ Subquery.prototype.getSQL = function() {
2316
2316
  function mapResultRow(columns, row, joinsNotNullableMap) {
2317
2317
  const nullifyMap = {};
2318
2318
  const result = columns.reduce(
2319
- (result2, { path: path26, field }, columnIndex) => {
2319
+ (result2, { path: path27, field }, columnIndex) => {
2320
2320
  let decoder;
2321
2321
  if (is(field, Column)) {
2322
2322
  decoder = field;
@@ -2326,8 +2326,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
2326
2326
  decoder = field.sql.decoder;
2327
2327
  }
2328
2328
  let node = result2;
2329
- for (const [pathChunkIndex, pathChunk] of path26.entries()) {
2330
- if (pathChunkIndex < path26.length - 1) {
2329
+ for (const [pathChunkIndex, pathChunk] of path27.entries()) {
2330
+ if (pathChunkIndex < path27.length - 1) {
2331
2331
  if (!(pathChunk in node)) {
2332
2332
  node[pathChunk] = {};
2333
2333
  }
@@ -2335,8 +2335,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
2335
2335
  } else {
2336
2336
  const rawValue = row[columnIndex];
2337
2337
  const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
2338
- if (joinsNotNullableMap && is(field, Column) && path26.length === 2) {
2339
- const objectName = path26[0];
2338
+ if (joinsNotNullableMap && is(field, Column) && path27.length === 2) {
2339
+ const objectName = path27[0];
2340
2340
  if (!(objectName in nullifyMap)) {
2341
2341
  nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
2342
2342
  } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
@@ -9151,7 +9151,7 @@ function extractFileChangeEntries(item) {
9151
9151
  isRecord4(entry.summary) ? entry.summary : null,
9152
9152
  isRecord4(entry.diff) ? entry.diff : null
9153
9153
  ].filter((candidate) => Boolean(candidate));
9154
- const path26 = uniqueStrings([
9154
+ const path27 = uniqueStrings([
9155
9155
  stringOrNull(valueFromRecords(nestedRecords, ["path", "filePath", "targetPath"])),
9156
9156
  stringOrNull(
9157
9157
  valueFromRecords(nestedRecords, [
@@ -9198,7 +9198,7 @@ function extractFileChangeEntries(item) {
9198
9198
  const diffStats = explicitAdditions === 0 && explicitDeletions === 0 && diffText ? countUnifiedDiffStats(diffText) : null;
9199
9199
  const additions = explicitAdditions || diffStats?.additions || 0;
9200
9200
  const deletions = explicitDeletions || diffStats?.deletions || 0;
9201
- const normalizedPath = path26 ?? (diffText ? projectRelativePathLabel(extractPathFromDiffText(diffText)) : null);
9201
+ const normalizedPath = path27 ?? (diffText ? projectRelativePathLabel(extractPathFromDiffText(diffText)) : null);
9202
9202
  if (!normalizedPath && additions === 0 && deletions === 0) {
9203
9203
  return null;
9204
9204
  }
@@ -13508,14 +13508,14 @@ function displayPath(pathValue, options) {
13508
13508
  }
13509
13509
  return relativePath;
13510
13510
  }
13511
- function toolIsLowInformationPatch(normalized, state, input, patchText, path26, metadataStats) {
13511
+ function toolIsLowInformationPatch(normalized, state, input, patchText, path27, metadataStats) {
13512
13512
  if (normalized !== "applypatch" && normalized !== "patch") {
13513
13513
  return false;
13514
13514
  }
13515
13515
  if (toolStateStatus(state) !== "running") {
13516
13516
  return false;
13517
13517
  }
13518
- if (path26 || patchText || metadataStats || stringValue2(state.output)) {
13518
+ if (path27 || patchText || metadataStats || stringValue2(state.output)) {
13519
13519
  return false;
13520
13520
  }
13521
13521
  return !isRecord9(input) || Object.keys(input).length === 0;
@@ -13558,7 +13558,7 @@ function fileChangeStatsFromMetadata(metadata) {
13558
13558
  if (files.length === 0) {
13559
13559
  return null;
13560
13560
  }
13561
- const paths = files.map((file) => stringValue2(file.filePath) ?? stringValue2(file.path) ?? stringValue2(file.relativePath)).filter((path26) => Boolean(path26));
13561
+ const paths = files.map((file) => stringValue2(file.filePath) ?? stringValue2(file.path) ?? stringValue2(file.relativePath)).filter((path27) => Boolean(path27));
13562
13562
  const addedLines = files.reduce((total, file) => total + (numberValue(file.additions) ?? numberValue(file.addedLines) ?? numberValue(file.added) ?? 0), 0);
13563
13563
  const removedLines = files.reduce((total, file) => total + (numberValue(file.deletions) ?? numberValue(file.removedLines) ?? numberValue(file.removed) ?? 0), 0);
13564
13564
  return {
@@ -13706,28 +13706,28 @@ function mapAssistantTool(messageId2, tool, options) {
13706
13706
  ].includes(normalized)) {
13707
13707
  const metadataStats = fileChangeStatsFromMetadata(state.metadata);
13708
13708
  const patchText = isRecord9(input) ? stringValue2(input.patchText) ?? stringValue2(input.patch) ?? stringValue2(input.diff) : null;
13709
- const path26 = metadataStats?.path ?? filePathFromInput(input) ?? extractPathFromPatchText(patchText);
13710
- if (toolIsLowInformationPatch(normalized, state, input, patchText, path26, metadataStats)) {
13709
+ const path27 = metadataStats?.path ?? filePathFromInput(input) ?? extractPathFromPatchText(patchText);
13710
+ if (toolIsLowInformationPatch(normalized, state, input, patchText, path27, metadataStats)) {
13711
13711
  return null;
13712
13712
  }
13713
13713
  const output = stringValue2(state.output);
13714
13714
  const diffStats = countUnifiedDiffStats2(patchText);
13715
- const displayFilePath = displayPath(path26, options);
13715
+ const displayFilePath = displayPath(path27, options);
13716
13716
  return {
13717
13717
  id,
13718
13718
  kind: "fileChange",
13719
13719
  text: metadataStats ? metadataStats.changedFiles > 1 ? `${metadataStats.changedFiles} changed files` : displayFilePath ?? metadataStats.previewText : displayFilePath ?? output ?? summary ?? name,
13720
13720
  previewText: metadataStats ? metadataStats.changedFiles > 1 ? `${metadataStats.changedFiles} changed files` : displayFilePath ?? metadataStats.previewText : displayFilePath ? `${name}: ${displayFilePath}` : output ?? summary ?? name,
13721
13721
  detailText,
13722
- changedFiles: metadataStats?.changedFiles ?? (path26 ? 1 : null),
13722
+ changedFiles: metadataStats?.changedFiles ?? (path27 ? 1 : null),
13723
13723
  addedLines: metadataStats?.addedLines ?? diffStats?.addedLines ?? null,
13724
13724
  removedLines: metadataStats?.removedLines ?? diffStats?.removedLines ?? null,
13725
13725
  status: toolStateStatus(state)
13726
13726
  };
13727
13727
  }
13728
13728
  if (["read", "grep", "glob", "list", "ls", "bashoutput"].includes(normalized)) {
13729
- const path26 = filePathFromInput(input);
13730
- const text2 = displayPath(path26, options) ?? summary ?? name;
13729
+ const path27 = filePathFromInput(input);
13730
+ const text2 = displayPath(path27, options) ?? summary ?? name;
13731
13731
  return {
13732
13732
  id,
13733
13733
  kind: "fileRead",
@@ -19357,7 +19357,11 @@ var ThreadDeletionCoordinator = class {
19357
19357
  };
19358
19358
 
19359
19359
  // src/exports/thread-pdf-export.ts
19360
+ import { spawn as spawn2 } from "child_process";
19360
19361
  import fs11 from "fs";
19362
+ import os3 from "os";
19363
+ import path14 from "path";
19364
+ import { pathToFileURL as pathToFileURL3 } from "url";
19361
19365
  import puppeteer from "puppeteer-core";
19362
19366
  import { marked } from "marked";
19363
19367
  var MAX_TEXT_CHARS = 12e3;
@@ -19371,6 +19375,8 @@ var EMBEDDED_CJK_FONT_CANDIDATES = [
19371
19375
  { path: "/mnt/c/Windows/Fonts/msyh.ttc", format: "truetype", weight: 400 }
19372
19376
  ];
19373
19377
  var PUPPETEER_CHANNEL = "chrome";
19378
+ var PDF_EXPORT_TIMEOUT_MS = 45e3;
19379
+ var MAX_CHROME_STDERR_CHARS = 4e3;
19374
19380
  var embeddedCjkFontCss = null;
19375
19381
  function escapeHtml(value) {
19376
19382
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
@@ -20397,35 +20403,15 @@ endobj
20397
20403
  `
20398
20404
  );
20399
20405
  }
20400
- const browser = await launchPdfBrowser();
20401
- try {
20402
- const page = await browser.newPage();
20403
- await page.setContent(renderThreadExportHtml(snapshot), {
20404
- waitUntil: "load"
20405
- });
20406
- return Buffer.from(
20407
- await page.pdf({
20408
- format: "Letter",
20409
- printBackground: true,
20410
- preferCSSPageSize: true
20411
- })
20412
- );
20413
- } finally {
20414
- await browser.close();
20415
- }
20406
+ return renderPdfWithChromeCli(renderThreadExportHtml(snapshot));
20416
20407
  }
20417
- async function launchPdfBrowser() {
20418
- const launchOptions = {
20419
- headless: true,
20420
- args: ["--no-sandbox", "--disable-setuid-sandbox", "--font-render-hinting=none"]
20421
- };
20422
- if (process.env.PUPPETEER_EXECUTABLE_PATH) {
20423
- launchOptions.executablePath = process.env.PUPPETEER_EXECUTABLE_PATH;
20424
- } else {
20425
- launchOptions.channel = PUPPETEER_CHANNEL;
20426
- }
20408
+ function resolvePdfBrowserExecutablePath() {
20427
20409
  try {
20428
- return await puppeteer.launch(launchOptions);
20410
+ const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH ? process.env.PUPPETEER_EXECUTABLE_PATH : puppeteer.executablePath(PUPPETEER_CHANNEL);
20411
+ if (!fs11.existsSync(executablePath)) {
20412
+ throw new Error(`Browser executable was not found at ${executablePath}`);
20413
+ }
20414
+ return executablePath;
20429
20415
  } catch (error) {
20430
20416
  const detail = error instanceof Error ? error.message : String(error);
20431
20417
  throw new Error(
@@ -20433,6 +20419,89 @@ async function launchPdfBrowser() {
20433
20419
  );
20434
20420
  }
20435
20421
  }
20422
+ async function renderPdfWithChromeCli(html) {
20423
+ const executablePath = resolvePdfBrowserExecutablePath();
20424
+ const tempDir = await fs11.promises.mkdtemp(path14.join(os3.tmpdir(), "remote-codex-pdf-"));
20425
+ const htmlPath = path14.join(tempDir, "thread-export.html");
20426
+ const pdfPath = path14.join(tempDir, "thread-export.pdf");
20427
+ try {
20428
+ await fs11.promises.writeFile(htmlPath, html, "utf8");
20429
+ await printHtmlToPdf({
20430
+ executablePath,
20431
+ htmlPath,
20432
+ pdfPath
20433
+ });
20434
+ const pdf = await fs11.promises.readFile(pdfPath);
20435
+ if (pdf.length === 0 || !pdf.subarray(0, 4).equals(Buffer.from("%PDF"))) {
20436
+ throw new Error("Chrome did not produce a valid PDF file.");
20437
+ }
20438
+ return pdf;
20439
+ } finally {
20440
+ await fs11.promises.rm(tempDir, { force: true, recursive: true });
20441
+ }
20442
+ }
20443
+ async function printHtmlToPdf(input) {
20444
+ const args = [
20445
+ "--headless",
20446
+ "--disable-gpu",
20447
+ "--disable-dev-shm-usage",
20448
+ "--no-sandbox",
20449
+ "--disable-setuid-sandbox",
20450
+ "--font-render-hinting=none",
20451
+ "--no-pdf-header-footer",
20452
+ "--print-to-pdf-no-header",
20453
+ `--print-to-pdf=${input.pdfPath}`,
20454
+ pathToFileURL3(input.htmlPath).href
20455
+ ];
20456
+ await new Promise((resolve, reject) => {
20457
+ const child = spawn2(input.executablePath, args, {
20458
+ stdio: ["ignore", "ignore", "pipe"]
20459
+ });
20460
+ let settled = false;
20461
+ let stderr = "";
20462
+ const complete = (error) => {
20463
+ if (settled) {
20464
+ return;
20465
+ }
20466
+ settled = true;
20467
+ clearTimeout(timeout);
20468
+ child.kill("SIGTERM");
20469
+ if (error) {
20470
+ reject(error);
20471
+ } else {
20472
+ resolve();
20473
+ }
20474
+ };
20475
+ const timeout = setTimeout(() => {
20476
+ child.kill("SIGKILL");
20477
+ complete(new Error(`Chrome PDF export timed out after ${PDF_EXPORT_TIMEOUT_MS}ms.`));
20478
+ }, PDF_EXPORT_TIMEOUT_MS);
20479
+ child.stderr.on("data", (chunk) => {
20480
+ stderr = truncateChromeStderr(`${stderr}${chunk.toString("utf8")}`);
20481
+ if (stderr.includes("bytes written to file")) {
20482
+ complete();
20483
+ }
20484
+ });
20485
+ child.on("error", (error) => {
20486
+ complete(error);
20487
+ });
20488
+ child.on("close", (code, signal) => {
20489
+ if (code === 0) {
20490
+ complete();
20491
+ return;
20492
+ }
20493
+ const reason = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
20494
+ const detail = stderr ? ` ${stderr}` : "";
20495
+ complete(new Error(`Chrome PDF export failed with ${reason}.${detail}`));
20496
+ });
20497
+ });
20498
+ }
20499
+ function truncateChromeStderr(value) {
20500
+ if (value.length <= MAX_CHROME_STDERR_CHARS) {
20501
+ return value;
20502
+ }
20503
+ return value.slice(value.length - MAX_CHROME_STDERR_CHARS);
20504
+ }
20436
20505
 
20437
20506
  // src/thread-export-coordinator.ts
20438
20507
  function userPromptPreviewFromTurn(turn) {
@@ -20703,7 +20772,7 @@ var ThreadForkCoordinator = class {
20703
20772
  // src/thread-attachment-coordinator.ts
20704
20773
  import { randomUUID as randomUUID3 } from "crypto";
20705
20774
  import fs12 from "fs/promises";
20706
- import path14 from "path";
20775
+ import path15 from "path";
20707
20776
  async function pathExists(absPath) {
20708
20777
  try {
20709
20778
  await fs12.access(absPath);
@@ -20713,8 +20782,8 @@ async function pathExists(absPath) {
20713
20782
  }
20714
20783
  }
20715
20784
  function sanitizeAttachmentFileName(originalName) {
20716
- const basename = path14.basename(originalName).trim() || "attachment";
20717
- const extension = path14.extname(basename).replace(/[^a-zA-Z0-9.]/g, "");
20785
+ const basename = path15.basename(originalName).trim() || "attachment";
20786
+ const extension = path15.extname(basename).replace(/[^a-zA-Z0-9.]/g, "");
20718
20787
  const rawStem = extension ? basename.slice(0, -extension.length) : basename;
20719
20788
  const sanitizedStem = rawStem.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
20720
20789
  const stem = sanitizedStem || "attachment";
@@ -20722,7 +20791,7 @@ function sanitizeAttachmentFileName(originalName) {
20722
20791
  return `${stem}-${randomUUID3().slice(0, 8)}${normalizedExtension}`;
20723
20792
  }
20724
20793
  function threadTempDirectoryPath2(workspacePath, localThreadId) {
20725
- return path14.join(workspacePath, ".temp", "threads", localThreadId);
20794
+ return path15.join(workspacePath, ".temp", "threads", localThreadId);
20726
20795
  }
20727
20796
  var ThreadAttachmentCoordinator = class {
20728
20797
  constructor(db) {
@@ -20763,7 +20832,7 @@ var ThreadAttachmentCoordinator = class {
20763
20832
  const savedFileName = sanitizeAttachmentFileName(
20764
20833
  attachment.manifest.originalName
20765
20834
  );
20766
- await fs12.writeFile(path14.join(tempDirectory, savedFileName), attachment.buffer);
20835
+ await fs12.writeFile(path15.join(tempDirectory, savedFileName), attachment.buffer);
20767
20836
  const relativePath = `./.temp/threads/${localThreadId}/${savedFileName}`;
20768
20837
  const replacementToken = attachment.manifest.kind === "photo" ? `[PHOTO ${relativePath}]` : `[FILE ${relativePath}]`;
20769
20838
  rewrittenPrompt = rewrittenPrompt.split(attachment.manifest.placeholder).join(replacementToken);
@@ -20777,7 +20846,7 @@ var ThreadAttachmentCoordinator = class {
20777
20846
 
20778
20847
  // src/thread-import-coordinator.ts
20779
20848
  import fs13 from "fs/promises";
20780
- import path15 from "path";
20849
+ import path16 from "path";
20781
20850
  async function pathExists2(absPath) {
20782
20851
  try {
20783
20852
  await fs13.access(absPath);
@@ -20787,19 +20856,19 @@ async function pathExists2(absPath) {
20787
20856
  }
20788
20857
  }
20789
20858
  async function resolveComparablePath2(absPath) {
20790
- const resolved = path15.resolve(absPath);
20859
+ const resolved = path16.resolve(absPath);
20791
20860
  if (await pathExists2(resolved)) {
20792
20861
  return fs13.realpath(resolved);
20793
20862
  }
20794
- const parentPath = path15.dirname(resolved);
20863
+ const parentPath = path16.dirname(resolved);
20795
20864
  if (parentPath === resolved) {
20796
20865
  return resolved;
20797
20866
  }
20798
20867
  const resolvedParent = await resolveComparablePath2(parentPath);
20799
- return path15.join(resolvedParent, path15.basename(resolved));
20868
+ return path16.join(resolvedParent, path16.basename(resolved));
20800
20869
  }
20801
20870
  async function resolveImportedWorkspacePath(workspaceRoot, candidatePath) {
20802
- if (!path15.isAbsolute(candidatePath)) {
20871
+ if (!path16.isAbsolute(candidatePath)) {
20803
20872
  throw new HttpError(400, {
20804
20873
  code: "bad_request",
20805
20874
  message: "Imported session path must be absolute."
@@ -20807,7 +20876,7 @@ async function resolveImportedWorkspacePath(workspaceRoot, candidatePath) {
20807
20876
  }
20808
20877
  const resolvedRoot = await resolveComparablePath2(workspaceRoot);
20809
20878
  const resolvedCandidate = await resolveComparablePath2(candidatePath);
20810
- const normalizedRoot = resolvedRoot.endsWith(path15.sep) ? resolvedRoot : `${resolvedRoot}${path15.sep}`;
20879
+ const normalizedRoot = resolvedRoot.endsWith(path16.sep) ? resolvedRoot : `${resolvedRoot}${path16.sep}`;
20811
20880
  if (resolvedCandidate !== resolvedRoot && !resolvedCandidate.startsWith(normalizedRoot)) {
20812
20881
  throw new HttpError(403, {
20813
20882
  code: "forbidden",
@@ -20860,7 +20929,7 @@ var ThreadImportCoordinator = class {
20860
20929
  if (!workspace) {
20861
20930
  workspace = createWorkspaceRecord(this.db, {
20862
20931
  absPath: importedPath,
20863
- label: path15.basename(importedPath) || "workspace"
20932
+ label: path16.basename(importedPath) || "workspace"
20864
20933
  });
20865
20934
  }
20866
20935
  const created = createThreadRecord(this.db, {
@@ -22118,8 +22187,8 @@ var ThreadService = class {
22118
22187
 
22119
22188
  // src/routes/agent-runtimes.ts
22120
22189
  import fs15 from "fs/promises";
22121
- import { spawn as spawn2 } from "child_process";
22122
- import path16 from "path";
22190
+ import { spawn as spawn3 } from "child_process";
22191
+ import path17 from "path";
22123
22192
  import { z as z3 } from "zod";
22124
22193
 
22125
22194
  // src/provider-schemas.ts
@@ -22340,7 +22409,7 @@ async function refreshBackendInstallation(app, runtime) {
22340
22409
  async function installedPackageVersion(packageName) {
22341
22410
  const globalRoot = await npmGlobalRoot3();
22342
22411
  if (globalRoot) {
22343
- const global = await packageVersionFromPath(path16.join(globalRoot, packageName, "package.json"));
22412
+ const global = await packageVersionFromPath(path17.join(globalRoot, packageName, "package.json"));
22344
22413
  if (global) {
22345
22414
  return global;
22346
22415
  }
@@ -22391,7 +22460,7 @@ function versionStringContains(installedVersion, latestVersion) {
22391
22460
  return Boolean(installedVersion && latestVersion && installedVersion.includes(latestVersion));
22392
22461
  }
22393
22462
  async function packageVersionFromNode(packageName) {
22394
- return packageVersionFromPath(path16.resolve("node_modules", packageName, "package.json"));
22463
+ return packageVersionFromPath(path17.resolve("node_modules", packageName, "package.json"));
22395
22464
  }
22396
22465
  async function packageVersionFromPath(packageJsonPath) {
22397
22466
  try {
@@ -22418,14 +22487,14 @@ async function npmGlobalBin() {
22418
22487
  return firstLine(result.stdout);
22419
22488
  }
22420
22489
  const prefix = await npmGlobalPrefix();
22421
- return prefix ? path16.join(prefix, "bin") : null;
22490
+ return prefix ? path17.join(prefix, "bin") : null;
22422
22491
  }
22423
22492
  async function npmGlobalPrefix() {
22424
22493
  const result = await runShellCommand("npm prefix -g", 3e3);
22425
22494
  return result.code === 0 ? firstLine(result.stdout) : null;
22426
22495
  }
22427
22496
  async function commandPathFor(command) {
22428
- if (path16.isAbsolute(command)) {
22497
+ if (path17.isAbsolute(command)) {
22429
22498
  return command;
22430
22499
  }
22431
22500
  const result = await runShellCommand(`command -v ${shellQuote(command)}`, 3e3);
@@ -22450,7 +22519,7 @@ function commandFailureMessage(command, result) {
22450
22519
  }
22451
22520
  function runShellCommand(command, timeoutMs = 0) {
22452
22521
  return new Promise((resolve) => {
22453
- const child = spawn2(command, {
22522
+ const child = spawn3(command, {
22454
22523
  shell: true,
22455
22524
  stdio: ["ignore", "pipe", "pipe"]
22456
22525
  });
@@ -23097,7 +23166,7 @@ async function registerSystemRoutes(app) {
23097
23166
 
23098
23167
  // src/routes/threads.ts
23099
23168
  import fs17 from "fs/promises";
23100
- import path17 from "path";
23169
+ import path18 from "path";
23101
23170
  import { z as z5 } from "zod";
23102
23171
 
23103
23172
  // src/worker-identity.ts
@@ -23569,7 +23638,7 @@ async function registerThreadRoutes(app) {
23569
23638
  message: "Workspace was not found for this thread."
23570
23639
  });
23571
23640
  }
23572
- const candidatePath = path17.isAbsolute(query.path) ? query.path : path17.resolve(workspace.absPath, query.path);
23641
+ const candidatePath = path18.isAbsolute(query.path) ? query.path : path18.resolve(workspace.absPath, query.path);
23573
23642
  const requestedPath = await fs17.realpath(candidatePath).catch(() => null);
23574
23643
  if (!requestedPath) {
23575
23644
  throw new HttpError(404, {
@@ -23577,8 +23646,8 @@ async function registerThreadRoutes(app) {
23577
23646
  message: "Image file was not found."
23578
23647
  });
23579
23648
  }
23580
- const resolvedWorkspaceRoot = await fs17.realpath(app.services.config.workspaceRoot).catch(() => path17.resolve(app.services.config.workspaceRoot));
23581
- const workspacePrefix = resolvedWorkspaceRoot.endsWith(path17.sep) ? resolvedWorkspaceRoot : `${resolvedWorkspaceRoot}${path17.sep}`;
23649
+ const resolvedWorkspaceRoot = await fs17.realpath(app.services.config.workspaceRoot).catch(() => path18.resolve(app.services.config.workspaceRoot));
23650
+ const workspacePrefix = resolvedWorkspaceRoot.endsWith(path18.sep) ? resolvedWorkspaceRoot : `${resolvedWorkspaceRoot}${path18.sep}`;
23582
23651
  if (requestedPath !== resolvedWorkspaceRoot && !requestedPath.startsWith(workspacePrefix)) {
23583
23652
  throw new HttpError(403, {
23584
23653
  code: "forbidden",
@@ -23775,9 +23844,9 @@ async function registerThreadRoutes(app) {
23775
23844
  // src/routes/workspaces.ts
23776
23845
  import fs18 from "fs/promises";
23777
23846
  import { createReadStream } from "fs";
23778
- import os3 from "os";
23779
- import path18 from "path";
23780
- import { spawn as spawn3 } from "child_process";
23847
+ import os4 from "os";
23848
+ import path19 from "path";
23849
+ import { spawn as spawn4 } from "child_process";
23781
23850
  import { Readable } from "stream";
23782
23851
  import { z as z6 } from "zod";
23783
23852
  var createWorkspaceSchema = z6.union([
@@ -23864,7 +23933,7 @@ function toWorkspaceFileDto(file) {
23864
23933
  };
23865
23934
  }
23866
23935
  function languageForPath(filePath) {
23867
- const extension = path18.extname(filePath).slice(1).toLowerCase();
23936
+ const extension = path19.extname(filePath).slice(1).toLowerCase();
23868
23937
  switch (extension) {
23869
23938
  case "js":
23870
23939
  case "jsx":
@@ -23910,18 +23979,18 @@ function languageForPath(filePath) {
23910
23979
  }
23911
23980
  }
23912
23981
  function relativeWorkspacePath(rootPath, absPath) {
23913
- const relative = path18.relative(rootPath, absPath);
23914
- return relative === "" ? "" : relative.split(path18.sep).join("/");
23982
+ const relative = path19.relative(rootPath, absPath);
23983
+ return relative === "" ? "" : relative.split(path19.sep).join("/");
23915
23984
  }
23916
23985
  async function resolveWorkspaceItemPath(rootPath, relativePath = "") {
23917
- const candidate = path18.resolve(rootPath, relativePath || ".");
23986
+ const candidate = path19.resolve(rootPath, relativePath || ".");
23918
23987
  const comparable = await assertPathWithinRoot(rootPath, candidate);
23919
23988
  return comparable;
23920
23989
  }
23921
23990
  async function buildWorkspaceTreeNode(rootPath, absPath, depth = 0) {
23922
23991
  const stats = await fs18.stat(absPath);
23923
23992
  const relativePath = relativeWorkspacePath(rootPath, absPath);
23924
- const name = relativePath ? path18.basename(absPath) : path18.basename(rootPath);
23993
+ const name = relativePath ? path19.basename(absPath) : path19.basename(rootPath);
23925
23994
  if (!stats.isDirectory()) {
23926
23995
  return {
23927
23996
  name,
@@ -23956,7 +24025,7 @@ async function buildWorkspaceTreeNode(rootPath, absPath, depth = 0) {
23956
24025
  }).slice(0, 400);
23957
24026
  node.children = (await Promise.all(
23958
24027
  visible.map(async (entry) => {
23959
- const childPath = path18.join(absPath, entry.name);
24028
+ const childPath = path19.join(absPath, entry.name);
23960
24029
  try {
23961
24030
  if (!entry.isDirectory() && !entry.isFile()) {
23962
24031
  return null;
@@ -23980,19 +24049,19 @@ function requireWorkspaceRecord(app, workspaceId) {
23980
24049
  return record;
23981
24050
  }
23982
24051
  function artifactRoot(record) {
23983
- return path18.join(record.absPath, ".remote-codex", "artifacts");
24052
+ return path19.join(record.absPath, ".remote-codex", "artifacts");
23984
24053
  }
23985
24054
  function artifactFilePath(record, artifactId) {
23986
- return path18.join(artifactRoot(record), artifactId, "artifact.bin");
24055
+ return path19.join(artifactRoot(record), artifactId, "artifact.bin");
23987
24056
  }
23988
24057
  function artifactMetadataPath(record, artifactId) {
23989
- return path18.join(artifactRoot(record), artifactId, "metadata.json");
24058
+ return path19.join(artifactRoot(record), artifactId, "metadata.json");
23990
24059
  }
23991
24060
  function safeArtifactFileName(value) {
23992
- return path18.basename(value).replace(/[^a-zA-Z0-9_. -]/g, "_") || "artifact.bin";
24061
+ return path19.basename(value).replace(/[^a-zA-Z0-9_. -]/g, "_") || "artifact.bin";
23993
24062
  }
23994
24063
  function artifactIdFromName(name) {
23995
- const base = path18.basename(name).replace(/[^a-zA-Z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 96);
24064
+ const base = path19.basename(name).replace(/[^a-zA-Z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 96);
23996
24065
  return `${base || "artifact"}-${Date.now().toString(36)}`;
23997
24066
  }
23998
24067
  async function readArtifactMetadata(record, artifactId) {
@@ -24035,7 +24104,7 @@ async function listWorkspaceArtifacts(record) {
24035
24104
  return artifacts.sort((left, right) => right.createdAt.localeCompare(left.createdAt));
24036
24105
  }
24037
24106
  function contentTypeForPath(filePath) {
24038
- switch (path18.extname(filePath).slice(1).toLowerCase()) {
24107
+ switch (path19.extname(filePath).slice(1).toLowerCase()) {
24039
24108
  case "png":
24040
24109
  return "image/png";
24041
24110
  case "jpg":
@@ -24065,7 +24134,7 @@ function contentTypeForPath(filePath) {
24065
24134
  }
24066
24135
  }
24067
24136
  async function collectFolderZipEntries(rootPath, folderPath) {
24068
- const folderName = path18.basename(folderPath) || "workspace-folder";
24137
+ const folderName = path19.basename(folderPath) || "workspace-folder";
24069
24138
  const entries = [];
24070
24139
  let totalBytes = 0;
24071
24140
  const pending = [folderPath];
@@ -24073,7 +24142,7 @@ async function collectFolderZipEntries(rootPath, folderPath) {
24073
24142
  const current = pending.pop();
24074
24143
  const children = await fs18.readdir(current, { withFileTypes: true });
24075
24144
  for (const child of children) {
24076
- const childPath = await resolveWorkspaceItemPath(rootPath, path18.relative(rootPath, path18.join(current, child.name)));
24145
+ const childPath = await resolveWorkspaceItemPath(rootPath, path19.relative(rootPath, path19.join(current, child.name)));
24077
24146
  if (child.isDirectory()) {
24078
24147
  pending.push(childPath);
24079
24148
  continue;
@@ -24133,7 +24202,7 @@ async function createFolderZipFile(rootPath, folderPath) {
24133
24202
  let offset = 0;
24134
24203
  for (const entry of entries) {
24135
24204
  const data = await fs18.readFile(entry.absPath);
24136
- const name = Buffer.from(entry.archivePath.split(path18.sep).join("/"), "utf8");
24205
+ const name = Buffer.from(entry.archivePath.split(path19.sep).join("/"), "utf8");
24137
24206
  const checksum = crc32(data);
24138
24207
  const { dosDate, dosTime } = zipDosDateTime(entry.updatedAt);
24139
24208
  const localHeader = Buffer.alloc(30);
@@ -24180,8 +24249,8 @@ async function createFolderZipFile(rootPath, folderPath) {
24180
24249
  endRecord.writeUInt32LE(centralSize, 12);
24181
24250
  endRecord.writeUInt32LE(offset, 16);
24182
24251
  endRecord.writeUInt16LE(0, 20);
24183
- const tempDir = await fs18.mkdtemp(path18.join(os3.tmpdir(), "remote-codex-folder-download-"));
24184
- const zipPath = path18.join(tempDir, `${path18.basename(folderPath) || "workspace-folder"}.zip`);
24252
+ const tempDir = await fs18.mkdtemp(path19.join(os4.tmpdir(), "remote-codex-folder-download-"));
24253
+ const zipPath = path19.join(tempDir, `${path19.basename(folderPath) || "workspace-folder"}.zip`);
24185
24254
  await fs18.writeFile(zipPath, Buffer.concat([...localParts, ...centralParts, endRecord]));
24186
24255
  return { zipPath, tempDir };
24187
24256
  }
@@ -24192,7 +24261,7 @@ function cleanupTemporaryZip(zipPath, tempDir) {
24192
24261
  };
24193
24262
  }
24194
24263
  function sanitizeUploadFilename(filename) {
24195
- const baseName = path18.basename(filename?.trim() || "upload");
24264
+ const baseName = path19.basename(filename?.trim() || "upload");
24196
24265
  if (!baseName || baseName === "." || baseName === "..") {
24197
24266
  return "upload";
24198
24267
  }
@@ -24204,7 +24273,7 @@ function inferGitRepoName(gitUrl) {
24204
24273
  const normalized = withoutQuery.replace(/[\\/]+$/, "");
24205
24274
  const rawName = normalized.split(/[/:]/).filter(Boolean).at(-1) ?? "";
24206
24275
  const repoName = rawName.endsWith(".git") ? rawName.slice(0, -4) : rawName;
24207
- if (!repoName || repoName === "." || repoName === ".." || repoName.includes(path18.sep)) {
24276
+ if (!repoName || repoName === "." || repoName === ".." || repoName.includes(path19.sep)) {
24208
24277
  throw new HttpError(400, {
24209
24278
  code: "bad_request",
24210
24279
  message: "Unable to infer a target directory from the Git URL."
@@ -24225,7 +24294,7 @@ async function pathExists4(absPath) {
24225
24294
  }
24226
24295
  function cloneRepository(gitUrl, targetPath) {
24227
24296
  return new Promise((resolve, reject) => {
24228
- const child = spawn3("git", ["clone", gitUrl, targetPath], {
24297
+ const child = spawn4("git", ["clone", gitUrl, targetPath], {
24229
24298
  stdio: ["ignore", "ignore", "pipe"]
24230
24299
  });
24231
24300
  let stderr = "";
@@ -24269,7 +24338,7 @@ async function registerWorkspaceRoutes(app) {
24269
24338
  });
24270
24339
  app.get("/api/workspaces/tree", async (request) => {
24271
24340
  const query = treeQuerySchema.parse(request.query);
24272
- const requestedPath = query.path ? path18.resolve(query.path) : app.services.config.workspaceRoot;
24341
+ const requestedPath = query.path ? path19.resolve(query.path) : app.services.config.workspaceRoot;
24273
24342
  const tree = await readWorkspaceTree({
24274
24343
  rootPath: app.services.config.workspaceRoot,
24275
24344
  targetPath: requestedPath,
@@ -24335,7 +24404,7 @@ async function registerWorkspaceRoutes(app) {
24335
24404
  const nextOffset = offset + read.bytesRead;
24336
24405
  return {
24337
24406
  path: relativeWorkspacePath(rootPath, filePath),
24338
- name: path18.basename(filePath),
24407
+ name: path19.basename(filePath),
24339
24408
  content: buffer.subarray(0, read.bytesRead).toString("utf8"),
24340
24409
  language: languageForPath(filePath),
24341
24410
  size: stats.size,
@@ -24371,7 +24440,7 @@ async function registerWorkspaceRoutes(app) {
24371
24440
  const stats = await fs18.stat(itemPath);
24372
24441
  if (stats.isDirectory()) {
24373
24442
  const { zipPath, tempDir } = await createFolderZipFile(rootPath, itemPath);
24374
- const filename2 = `${path18.basename(itemPath) || "workspace-folder"}.zip`;
24443
+ const filename2 = `${path19.basename(itemPath) || "workspace-folder"}.zip`;
24375
24444
  const cleanup = cleanupTemporaryZip(zipPath, tempDir);
24376
24445
  reply.raw.once("finish", () => void cleanup());
24377
24446
  reply.raw.once("close", () => void cleanup());
@@ -24387,7 +24456,7 @@ async function registerWorkspaceRoutes(app) {
24387
24456
  message: "Only file and folder downloads are supported from this endpoint."
24388
24457
  });
24389
24458
  }
24390
- const filename = path18.basename(itemPath);
24459
+ const filename = path19.basename(itemPath);
24391
24460
  reply.header("content-type", contentTypeForPath(itemPath)).header(
24392
24461
  "content-disposition",
24393
24462
  `attachment; filename="${filename}"; filename*=UTF-8''${encodeURIComponent(filename)}`
@@ -24453,7 +24522,7 @@ async function registerWorkspaceRoutes(app) {
24453
24522
  kind: "file",
24454
24523
  file: {
24455
24524
  path: file.path,
24456
- name: path18.basename(file.path),
24525
+ name: path19.basename(file.path),
24457
24526
  size: file.size
24458
24527
  }
24459
24528
  };
@@ -24495,7 +24564,7 @@ async function registerWorkspaceRoutes(app) {
24495
24564
  message: "Artifact content must not be empty."
24496
24565
  });
24497
24566
  }
24498
- const dir = path18.dirname(artifactFilePath(record, artifactId));
24567
+ const dir = path19.dirname(artifactFilePath(record, artifactId));
24499
24568
  await fs18.mkdir(dir, { recursive: true, mode: 448 });
24500
24569
  const filePath = artifactFilePath(record, artifactId);
24501
24570
  await fs18.writeFile(filePath, content, { flag: "wx" }).catch((error) => {
@@ -24558,7 +24627,7 @@ async function registerWorkspaceRoutes(app) {
24558
24627
  const params = z6.object({ id: z6.string().uuid(), artifactId: workspaceArtifactIdSchema }).parse(request.params);
24559
24628
  const record = requireWorkspaceRecord(app, params.id);
24560
24629
  const artifact = await readArtifactMetadata(record, params.artifactId);
24561
- await fs18.rm(path18.dirname(artifactFilePath(record, params.artifactId)), {
24630
+ await fs18.rm(path19.dirname(artifactFilePath(record, params.artifactId)), {
24562
24631
  recursive: true,
24563
24632
  force: true
24564
24633
  });
@@ -24573,7 +24642,7 @@ async function registerWorkspaceRoutes(app) {
24573
24642
  let validated;
24574
24643
  if ("gitUrl" in body) {
24575
24644
  const repoName = inferGitRepoName(body.gitUrl);
24576
- const targetPath = path18.join(settings.devHome, repoName);
24645
+ const targetPath = path19.join(settings.devHome, repoName);
24577
24646
  if (await pathExists4(targetPath)) {
24578
24647
  throw new HttpError(409, {
24579
24648
  code: "conflict",
@@ -24837,7 +24906,7 @@ async function registerAuthRoutes(app) {
24837
24906
 
24838
24907
  // src/provider-host-config-service.ts
24839
24908
  import fs19 from "fs/promises";
24840
- import path19 from "path";
24909
+ import path20 from "path";
24841
24910
  import { randomUUID as randomUUID4 } from "crypto";
24842
24911
  function providerError(message, statusCode = 404) {
24843
24912
  const error = new Error(message);
@@ -24845,16 +24914,16 @@ function providerError(message, statusCode = 404) {
24845
24914
  return error;
24846
24915
  }
24847
24916
  function resolveProviderHostFilePath(providerHome, name) {
24848
- return path19.join(providerHome, name);
24917
+ return path20.join(providerHome, name);
24849
24918
  }
24850
24919
  function resolveArchiveRoot(providerHome) {
24851
- return path19.join(providerHome, "supervisor-config-archives");
24920
+ return path20.join(providerHome, "supervisor-config-archives");
24852
24921
  }
24853
24922
  function resolveArchiveIndexPath(providerHome) {
24854
- return path19.join(resolveArchiveRoot(providerHome), "index.json");
24923
+ return path20.join(resolveArchiveRoot(providerHome), "index.json");
24855
24924
  }
24856
24925
  function resolveArchivePath(providerHome, archiveId) {
24857
- return path19.join(resolveArchiveRoot(providerHome), archiveId);
24926
+ return path20.join(resolveArchiveRoot(providerHome), archiveId);
24858
24927
  }
24859
24928
  function defaultArchiveLabel(createdAt) {
24860
24929
  return `Backup ${createdAt.replace("T", " ").replace(/\.\d{3}Z$/, " UTC")}`;
@@ -24970,7 +25039,7 @@ var ProviderHostConfigService = class {
24970
25039
  const providerHome = this.providerHome(provider2);
24971
25040
  const fileName = this.assertHostFile(provider2, name);
24972
25041
  const filePath = resolveProviderHostFilePath(providerHome, fileName);
24973
- await fs19.mkdir(path19.dirname(filePath), { recursive: true });
25042
+ await fs19.mkdir(path20.dirname(filePath), { recursive: true });
24974
25043
  await fs19.writeFile(filePath, input.content, "utf8");
24975
25044
  return this.readFile(provider2, fileName);
24976
25045
  }
@@ -25005,7 +25074,7 @@ var ProviderHostConfigService = class {
25005
25074
  exists: hostFile.exists
25006
25075
  };
25007
25076
  if (hostFile.exists) {
25008
- await fs19.writeFile(path19.join(archivePath, name), hostFile.content, "utf8");
25077
+ await fs19.writeFile(path20.join(archivePath, name), hostFile.content, "utf8");
25009
25078
  }
25010
25079
  }
25011
25080
  const archive = {
@@ -25045,7 +25114,7 @@ var ProviderHostConfigService = class {
25045
25114
  for (const name of fileNames) {
25046
25115
  const hostPath = resolveProviderHostFilePath(providerHome, name);
25047
25116
  if (archive.files[name]?.exists) {
25048
- const content = await fs19.readFile(path19.join(archivePath, name), "utf8");
25117
+ const content = await fs19.readFile(path20.join(archivePath, name), "utf8");
25049
25118
  await fs19.writeFile(hostPath, content, "utf8");
25050
25119
  } else {
25051
25120
  await fs19.rm(hostPath, { force: true });
@@ -25065,8 +25134,8 @@ import fs21 from "fs/promises";
25065
25134
 
25066
25135
  // src/shell/shell-prompt.ts
25067
25136
  import fs20 from "fs/promises";
25068
- import os4 from "os";
25069
- import path20 from "path";
25137
+ import os5 from "os";
25138
+ import path21 from "path";
25070
25139
  function basenameFromPath2(filePath) {
25071
25140
  if (!filePath) {
25072
25141
  return "";
@@ -25075,7 +25144,7 @@ function basenameFromPath2(filePath) {
25075
25144
  if (!normalized) {
25076
25145
  return "";
25077
25146
  }
25078
- return path20.basename(normalized) || normalized;
25147
+ return path21.basename(normalized) || normalized;
25079
25148
  }
25080
25149
  function isInteractiveShellCommand(command) {
25081
25150
  const normalized = (command ?? "").trim().toLowerCase();
@@ -25236,8 +25305,8 @@ function buildShellPromptInitScriptContents(command) {
25236
25305
  async function ensureShellPromptInitScript(command) {
25237
25306
  const normalized = command.trim().toLowerCase();
25238
25307
  const extension = normalized === "zsh" ? "zsh" : "sh";
25239
- const filePath = path20.join(
25240
- os4.tmpdir(),
25308
+ const filePath = path21.join(
25309
+ os5.tmpdir(),
25241
25310
  `remote-codex-shell-prompt.${extension}`
25242
25311
  );
25243
25312
  await fs20.writeFile(filePath, buildShellPromptInitScriptContents(command), "utf8");
@@ -25919,7 +25988,7 @@ var builtinPlugins = [
25919
25988
 
25920
25989
  // src/plugins/plugin-service.ts
25921
25990
  import fs22 from "fs/promises";
25922
- import path21 from "path";
25991
+ import path22 from "path";
25923
25992
  var MANAGED_CODEX_MCP_BEGIN = "# BEGIN remote-codex managed plugin MCP servers";
25924
25993
  var MANAGED_CODEX_MCP_END = "# END remote-codex managed plugin MCP servers";
25925
25994
  var REMOTE_CODEX_MOLECULE_MCP_TOOL_NAME = "remote_codex_render_molecule";
@@ -25931,7 +26000,7 @@ function normalizeManagedCommand(server, repoRoot) {
25931
26000
  if (server.name === "remote_codex_plugins") {
25932
26001
  return {
25933
26002
  command: process.execPath,
25934
- args: [path21.join(repoRoot, "bin", "remote-codex-plugin-mcp.mjs")]
26003
+ args: [path22.join(repoRoot, "bin", "remote-codex-plugin-mcp.mjs")]
25935
26004
  };
25936
26005
  }
25937
26006
  return {
@@ -26118,7 +26187,7 @@ var PluginService = class {
26118
26187
  if (!input.codexHome) {
26119
26188
  return;
26120
26189
  }
26121
- const configPath = path21.join(input.codexHome, "config.toml");
26190
+ const configPath = path22.join(input.codexHome, "config.toml");
26122
26191
  let current = "";
26123
26192
  try {
26124
26193
  current = await fs22.readFile(configPath, "utf8");
@@ -26136,7 +26205,7 @@ var PluginService = class {
26136
26205
  if (next === current) {
26137
26206
  return;
26138
26207
  }
26139
- await fs22.mkdir(path21.dirname(configPath), { recursive: true });
26208
+ await fs22.mkdir(path22.dirname(configPath), { recursive: true });
26140
26209
  await fs22.writeFile(configPath, next, "utf8");
26141
26210
  }
26142
26211
  async importPlugin(input) {
@@ -26377,7 +26446,7 @@ var PluginSettingsStore = class {
26377
26446
 
26378
26447
  // src/worker-bootstrap.ts
26379
26448
  import fs23 from "fs/promises";
26380
- import path22 from "path";
26449
+ import path23 from "path";
26381
26450
  function trimTrailingSlash(value) {
26382
26451
  return value.replace(/\/+$/, "");
26383
26452
  }
@@ -26388,7 +26457,7 @@ function tomlString(value) {
26388
26457
  return JSON.stringify(value);
26389
26458
  }
26390
26459
  async function writePrivateFile(filePath, content) {
26391
- await fs23.mkdir(path22.dirname(filePath), { recursive: true, mode: 448 });
26460
+ await fs23.mkdir(path23.dirname(filePath), { recursive: true, mode: 448 });
26392
26461
  await fs23.writeFile(filePath, content, { encoding: "utf8", mode: 384 });
26393
26462
  await fs23.chmod(filePath, 384);
26394
26463
  }
@@ -26404,7 +26473,7 @@ async function configureWorkerProviderGateway(config) {
26404
26473
  process.env.ANTHROPIC_BASE_URL = anthropicBaseUrl;
26405
26474
  if (config.agentProviders.codex.enabled) {
26406
26475
  await writePrivateFile(
26407
- path22.join(config.agentProviders.codex.home, "config.toml"),
26476
+ path23.join(config.agentProviders.codex.home, "config.toml"),
26408
26477
  [
26409
26478
  'model_provider = "sub2api"',
26410
26479
  'forced_login_method = "api"',
@@ -26420,7 +26489,7 @@ async function configureWorkerProviderGateway(config) {
26420
26489
  ].join("\n")
26421
26490
  );
26422
26491
  await writePrivateFile(
26423
- path22.join(config.agentProviders.codex.home, "auth.json"),
26492
+ path23.join(config.agentProviders.codex.home, "auth.json"),
26424
26493
  `${JSON.stringify(
26425
26494
  {
26426
26495
  OPENAI_API_KEY: config.llmGatewayToken
@@ -26433,7 +26502,7 @@ async function configureWorkerProviderGateway(config) {
26433
26502
  }
26434
26503
  if (config.agentProviders.claude.enabled) {
26435
26504
  await writePrivateFile(
26436
- path22.join(config.agentProviders.claude.home, "settings.json"),
26505
+ path23.join(config.agentProviders.claude.home, "settings.json"),
26437
26506
  `${JSON.stringify(
26438
26507
  {
26439
26508
  env: {
@@ -26449,7 +26518,7 @@ async function configureWorkerProviderGateway(config) {
26449
26518
  }
26450
26519
  if (config.agentProviders.opencode.enabled) {
26451
26520
  await writePrivateFile(
26452
- path22.join(config.agentProviders.opencode.home, "opencode.json"),
26521
+ path23.join(config.agentProviders.opencode.home, "opencode.json"),
26453
26522
  `${JSON.stringify(
26454
26523
  {
26455
26524
  provider: {
@@ -26496,8 +26565,8 @@ var BackendPluginHost = class {
26496
26565
  };
26497
26566
 
26498
26567
  // src/shell/pty-shell-backend.ts
26499
- import path23 from "path";
26500
- import { spawn as spawn4 } from "@homebridge/node-pty-prebuilt-multiarch";
26568
+ import path24 from "path";
26569
+ import { spawn as spawn5 } from "@homebridge/node-pty-prebuilt-multiarch";
26501
26570
 
26502
26571
  // src/shell/default-shell.ts
26503
26572
  import fs24 from "fs";
@@ -26516,7 +26585,7 @@ function resolveDefaultShell(env = process.env) {
26516
26585
  var MAX_SCROLLBACK_BYTES = 512 * 1024;
26517
26586
  var ANSI_ESCAPE_PATTERN = new RegExp(String.raw`\u001B\[[0-?]*[ -/]*[@-~]`, "g");
26518
26587
  function shellArgs(shell) {
26519
- const shellName = path23.basename(shell).toLowerCase();
26588
+ const shellName = path24.basename(shell).toLowerCase();
26520
26589
  if (process.platform === "win32") {
26521
26590
  return [];
26522
26591
  }
@@ -26538,7 +26607,7 @@ function lastVisibleLine(snapshot) {
26538
26607
  }
26539
26608
  function inferRuntime(session) {
26540
26609
  const promptLine = lastVisibleLine(session.scrollback);
26541
- const shell = path23.basename(session.shell);
26610
+ const shell = path24.basename(session.shell);
26542
26611
  const isCommandRunning = session.exitCode !== null ? false : !/[$#>]\s*$/.test(promptLine.trimEnd());
26543
26612
  return {
26544
26613
  panePid: session.pty.pid,
@@ -26566,7 +26635,7 @@ var PtyShellBackend = class {
26566
26635
  if (this.sessions.has(input.sessionId)) {
26567
26636
  return;
26568
26637
  }
26569
- const pty = spawn4(this.shell, shellArgs(this.shell), {
26638
+ const pty = spawn5(this.shell, shellArgs(this.shell), {
26570
26639
  name: "xterm-256color",
26571
26640
  cwd: input.cwd,
26572
26641
  cols: input.cols ?? 120,
@@ -26685,7 +26754,7 @@ var PtyShellBackend = class {
26685
26754
 
26686
26755
  // src/shell/tmux-manager.ts
26687
26756
  import fs25 from "fs";
26688
- import path24 from "path";
26757
+ import path25 from "path";
26689
26758
  import { spawn as spawnChild } from "child_process";
26690
26759
  async function defaultExecCommand(command, args) {
26691
26760
  return await new Promise((resolve, reject) => {
@@ -26712,16 +26781,16 @@ async function defaultExecCommand(command, args) {
26712
26781
  });
26713
26782
  }
26714
26783
  function resolveExecutablePath(command) {
26715
- if (command.includes(path24.sep)) {
26784
+ if (command.includes(path25.sep)) {
26716
26785
  return command;
26717
26786
  }
26718
26787
  const searchPath = process.env.PATH ?? "";
26719
- for (const entry of searchPath.split(path24.delimiter)) {
26788
+ for (const entry of searchPath.split(path25.delimiter)) {
26720
26789
  const trimmed = entry.trim();
26721
26790
  if (!trimmed) {
26722
26791
  continue;
26723
26792
  }
26724
- const candidate = path24.join(trimmed, command);
26793
+ const candidate = path25.join(trimmed, command);
26725
26794
  if (fs25.existsSync(candidate)) {
26726
26795
  return candidate;
26727
26796
  }
@@ -27480,22 +27549,22 @@ function payloadItems(payload, fields) {
27480
27549
  const record = recordFrom(payload);
27481
27550
  return arrayField(record, fields) ?? (record ? [record] : []);
27482
27551
  }
27483
- function artifactPreviewKind(type, format, path26) {
27552
+ function artifactPreviewKind(type, format, path27) {
27484
27553
  const candidates = [
27485
27554
  type,
27486
27555
  format,
27487
- path26?.split(".").pop() ?? null
27556
+ path27?.split(".").pop() ?? null
27488
27557
  ].map((value) => value?.trim().toLowerCase()).filter(Boolean);
27489
27558
  return candidates.some((value) => MOLECULE_ARTIFACT_TYPES.has(value)) ? "molecule" : "file";
27490
27559
  }
27491
27560
  function normalizeArtifactRef(value) {
27492
27561
  const record = recordFrom(value);
27493
- const path26 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27562
+ const path27 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27494
27563
  const type = stringField3(record, ["type", "artifactType", "artifact_type", "format", "extension"]);
27495
- const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path26 ?? "artifact";
27564
+ const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path27 ?? "artifact";
27496
27565
  return {
27497
27566
  title,
27498
- path: path26,
27567
+ path: path27,
27499
27568
  type,
27500
27569
  downloadUrl: stringField3(record, ["downloadUrl", "download_url", "url", "href"])
27501
27570
  };
@@ -27529,21 +27598,21 @@ function normalizeArtifact(module, runId, value) {
27529
27598
  if (!record) {
27530
27599
  return null;
27531
27600
  }
27532
- const path26 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27601
+ const path27 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27533
27602
  const type = stringField3(record, ["type", "artifactType", "artifact_type"]);
27534
27603
  const format = stringField3(record, ["format", "fileFormat", "file_format", "extension"]) ?? type;
27535
- const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path26 ?? `${module} artifact`;
27604
+ const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path27 ?? `${module} artifact`;
27536
27605
  return {
27537
27606
  module,
27538
27607
  runId,
27539
27608
  title,
27540
- path: path26,
27609
+ path: path27,
27541
27610
  type,
27542
27611
  format,
27543
27612
  mimeType: stringField3(record, ["mimeType", "mime_type", "contentType", "content_type"]),
27544
27613
  sizeBytes: numberField2(record, ["sizeBytes", "size_bytes", "bytes"]),
27545
27614
  downloadUrl: stringField3(record, ["downloadUrl", "download_url", "url", "href"]),
27546
- previewKind: artifactPreviewKind(type, format, path26)
27615
+ previewKind: artifactPreviewKind(type, format, path27)
27547
27616
  };
27548
27617
  }
27549
27618
  function normalizeRuns(module, result) {
@@ -27670,9 +27739,9 @@ var WorkerHarnessClient = class {
27670
27739
  }
27671
27740
  return { baseUrl, apiKey };
27672
27741
  }
27673
- async fetchText(path26) {
27742
+ async fetchText(path27) {
27674
27743
  const config = this.requireHarnessConfig();
27675
- const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
27744
+ const response = await this.fetchImpl(`${config.baseUrl}${path27}`, {
27676
27745
  headers: {
27677
27746
  "x-api-key": config.apiKey
27678
27747
  }
@@ -27683,11 +27752,11 @@ var WorkerHarnessClient = class {
27683
27752
  }
27684
27753
  return { text: text2 };
27685
27754
  }
27686
- async fetchPayload(path26, init = {}) {
27755
+ async fetchPayload(path27, init = {}) {
27687
27756
  const config = this.requireHarnessConfig();
27688
27757
  const headers = new Headers(init.headers);
27689
27758
  headers.set("x-api-key", config.apiKey);
27690
- const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
27759
+ const response = await this.fetchImpl(`${config.baseUrl}${path27}`, {
27691
27760
  ...init,
27692
27761
  headers
27693
27762
  });
@@ -27701,9 +27770,9 @@ var WorkerHarnessClient = class {
27701
27770
  return { text: text2 };
27702
27771
  }
27703
27772
  }
27704
- async fetchBinary(path26) {
27773
+ async fetchBinary(path27) {
27705
27774
  const config = this.requireHarnessConfig();
27706
- const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
27775
+ const response = await this.fetchImpl(`${config.baseUrl}${path27}`, {
27707
27776
  headers: {
27708
27777
  "x-api-key": config.apiKey
27709
27778
  }
@@ -28248,16 +28317,16 @@ var HttpError = class extends Error {
28248
28317
  };
28249
28318
  function findRepoRoot(start = process.cwd()) {
28250
28319
  if (process.env.REMOTE_CODEX_REPO_ROOT) {
28251
- return path25.resolve(process.env.REMOTE_CODEX_REPO_ROOT);
28320
+ return path26.resolve(process.env.REMOTE_CODEX_REPO_ROOT);
28252
28321
  }
28253
- let current = path25.resolve(start);
28254
- while (current !== path25.dirname(current)) {
28255
- if (fs26.existsSync(path25.join(current, "pnpm-workspace.yaml")) && fs26.existsSync(path25.join(current, "scripts", "service-restart.mjs"))) {
28322
+ let current = path26.resolve(start);
28323
+ while (current !== path26.dirname(current)) {
28324
+ if (fs26.existsSync(path26.join(current, "pnpm-workspace.yaml")) && fs26.existsSync(path26.join(current, "scripts", "service-restart.mjs"))) {
28256
28325
  return current;
28257
28326
  }
28258
- current = path25.dirname(current);
28327
+ current = path26.dirname(current);
28259
28328
  }
28260
- return path25.resolve(process.cwd());
28329
+ return path26.resolve(process.cwd());
28261
28330
  }
28262
28331
  function createServiceLifecycle() {
28263
28332
  return {
@@ -28269,14 +28338,14 @@ function createServiceLifecycle() {
28269
28338
  });
28270
28339
  }
28271
28340
  const repoRoot = findRepoRoot();
28272
- const restartScript = path25.join(repoRoot, "scripts", "service-restart.mjs");
28273
- if (!fs26.existsSync(restartScript) || !fs26.existsSync(path25.join(repoRoot, "pnpm-workspace.yaml"))) {
28341
+ const restartScript = path26.join(repoRoot, "scripts", "service-restart.mjs");
28342
+ if (!fs26.existsSync(restartScript) || !fs26.existsSync(path26.join(repoRoot, "pnpm-workspace.yaml"))) {
28274
28343
  throw new HttpError(503, {
28275
28344
  code: "service_unavailable",
28276
28345
  message: "Build and restart requires a Remote Codex source checkout. Set REMOTE_CODEX_REPO_ROOT to the checkout path, or update the npm package with npm install -g remote-codex@latest."
28277
28346
  });
28278
28347
  }
28279
- const child = spawn5(process.execPath, [restartScript, "launch"], {
28348
+ const child = spawn6(process.execPath, [restartScript, "launch"], {
28280
28349
  cwd: repoRoot,
28281
28350
  detached: true,
28282
28351
  env: process.env,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildApp
3
- } from "./chunk-2QAVWDYV.js";
3
+ } from "./chunk-TQUNANIS.js";
4
4
 
5
5
  // src/index.ts
6
6
  import fs from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildApp
3
- } from "./chunk-2QAVWDYV.js";
3
+ } from "./chunk-TQUNANIS.js";
4
4
 
5
5
  // src/worker-index.ts
6
6
  import fs2 from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remote-codex",
3
- "version": "0.11.11",
3
+ "version": "0.11.12",
4
4
  "description": "Local web supervisor for Codex workspaces and threads.",
5
5
  "license": "MIT",
6
6
  "type": "module",