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
|
|
11
|
+
import { spawn as spawn6 } from "child_process";
|
|
12
12
|
import fs26 from "fs";
|
|
13
|
-
import
|
|
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:
|
|
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
|
|
2330
|
-
if (pathChunkIndex <
|
|
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) &&
|
|
2339
|
-
const objectName =
|
|
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
|
|
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 =
|
|
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,
|
|
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 (
|
|
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((
|
|
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
|
|
13710
|
-
if (toolIsLowInformationPatch(normalized, state, input, patchText,
|
|
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(
|
|
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 ?? (
|
|
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
|
|
13730
|
-
const text2 = displayPath(
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -20397,35 +20403,15 @@ endobj
|
|
|
20397
20403
|
`
|
|
20398
20404
|
);
|
|
20399
20405
|
}
|
|
20400
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
20717
|
-
const extension =
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
20859
|
+
const resolved = path16.resolve(absPath);
|
|
20791
20860
|
if (await pathExists2(resolved)) {
|
|
20792
20861
|
return fs13.realpath(resolved);
|
|
20793
20862
|
}
|
|
20794
|
-
const parentPath =
|
|
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
|
|
20868
|
+
return path16.join(resolvedParent, path16.basename(resolved));
|
|
20800
20869
|
}
|
|
20801
20870
|
async function resolveImportedWorkspacePath(workspaceRoot, candidatePath) {
|
|
20802
|
-
if (!
|
|
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(
|
|
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:
|
|
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
|
|
22122
|
-
import
|
|
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(
|
|
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(
|
|
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 ?
|
|
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 (
|
|
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 =
|
|
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
|
|
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 =
|
|
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(() =>
|
|
23581
|
-
const workspacePrefix = resolvedWorkspaceRoot.endsWith(
|
|
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
|
|
23779
|
-
import
|
|
23780
|
-
import { spawn as
|
|
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 =
|
|
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 =
|
|
23914
|
-
return relative === "" ? "" : relative.split(
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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
|
|
24052
|
+
return path19.join(record.absPath, ".remote-codex", "artifacts");
|
|
23984
24053
|
}
|
|
23985
24054
|
function artifactFilePath(record, artifactId) {
|
|
23986
|
-
return
|
|
24055
|
+
return path19.join(artifactRoot(record), artifactId, "artifact.bin");
|
|
23987
24056
|
}
|
|
23988
24057
|
function artifactMetadataPath(record, artifactId) {
|
|
23989
|
-
return
|
|
24058
|
+
return path19.join(artifactRoot(record), artifactId, "metadata.json");
|
|
23990
24059
|
}
|
|
23991
24060
|
function safeArtifactFileName(value) {
|
|
23992
|
-
return
|
|
24061
|
+
return path19.basename(value).replace(/[^a-zA-Z0-9_. -]/g, "_") || "artifact.bin";
|
|
23993
24062
|
}
|
|
23994
24063
|
function artifactIdFromName(name) {
|
|
23995
|
-
const base =
|
|
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 (
|
|
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 =
|
|
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,
|
|
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(
|
|
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(
|
|
24184
|
-
const zipPath =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 ?
|
|
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:
|
|
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 = `${
|
|
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 =
|
|
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:
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
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
|
|
24917
|
+
return path20.join(providerHome, name);
|
|
24849
24918
|
}
|
|
24850
24919
|
function resolveArchiveRoot(providerHome) {
|
|
24851
|
-
return
|
|
24920
|
+
return path20.join(providerHome, "supervisor-config-archives");
|
|
24852
24921
|
}
|
|
24853
24922
|
function resolveArchiveIndexPath(providerHome) {
|
|
24854
|
-
return
|
|
24923
|
+
return path20.join(resolveArchiveRoot(providerHome), "index.json");
|
|
24855
24924
|
}
|
|
24856
24925
|
function resolveArchivePath(providerHome, archiveId) {
|
|
24857
|
-
return
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
25069
|
-
import
|
|
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
|
|
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 =
|
|
25240
|
-
|
|
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
|
|
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: [
|
|
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 =
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
26500
|
-
import { spawn as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
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,
|
|
27552
|
+
function artifactPreviewKind(type, format, path27) {
|
|
27484
27553
|
const candidates = [
|
|
27485
27554
|
type,
|
|
27486
27555
|
format,
|
|
27487
|
-
|
|
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
|
|
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"]) ??
|
|
27564
|
+
const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path27 ?? "artifact";
|
|
27496
27565
|
return {
|
|
27497
27566
|
title,
|
|
27498
|
-
path:
|
|
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
|
|
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"]) ??
|
|
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:
|
|
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,
|
|
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(
|
|
27742
|
+
async fetchText(path27) {
|
|
27674
27743
|
const config = this.requireHarnessConfig();
|
|
27675
|
-
const response = await this.fetchImpl(`${config.baseUrl}${
|
|
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(
|
|
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}${
|
|
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(
|
|
27773
|
+
async fetchBinary(path27) {
|
|
27705
27774
|
const config = this.requireHarnessConfig();
|
|
27706
|
-
const response = await this.fetchImpl(`${config.baseUrl}${
|
|
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
|
|
28320
|
+
return path26.resolve(process.env.REMOTE_CODEX_REPO_ROOT);
|
|
28252
28321
|
}
|
|
28253
|
-
let current =
|
|
28254
|
-
while (current !==
|
|
28255
|
-
if (fs26.existsSync(
|
|
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 =
|
|
28327
|
+
current = path26.dirname(current);
|
|
28259
28328
|
}
|
|
28260
|
-
return
|
|
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 =
|
|
28273
|
-
if (!fs26.existsSync(restartScript) || !fs26.existsSync(
|
|
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 =
|
|
28348
|
+
const child = spawn6(process.execPath, [restartScript, "launch"], {
|
|
28280
28349
|
cwd: repoRoot,
|
|
28281
28350
|
detached: true,
|
|
28282
28351
|
env: process.env,
|