cxstatusline 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -9
- package/dist/cxstatusline.js +577 -285
- package/package.json +1 -1
- package/patches/codex-0.157.0.patch +1683 -0
- package/patches/codex-0.158.0.patch +1683 -0
- package/patches/codex-0.159.0.patch +1683 -0
- package/patches/codex-0.159.3.patch +1683 -0
- package/patches/manifest.json +73 -10
package/dist/cxstatusline.js
CHANGED
|
@@ -27133,7 +27133,7 @@ var require_jsx_dev_runtime = __commonJS(function(exports, module) {
|
|
|
27133
27133
|
});
|
|
27134
27134
|
|
|
27135
27135
|
// src/cli.ts
|
|
27136
|
-
import { readFileSync as
|
|
27136
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
27137
27137
|
|
|
27138
27138
|
// src/main.ts
|
|
27139
27139
|
import { freemem, platform as platform3, totalmem } from "node:os";
|
|
@@ -56307,7 +56307,14 @@ function resolveLiveSpeedMetrics(context, windowSeconds) {
|
|
|
56307
56307
|
totalTokens: 0,
|
|
56308
56308
|
requestCount: 0
|
|
56309
56309
|
},
|
|
56310
|
-
lastActiveTimeMs: nowMs
|
|
56310
|
+
lastActiveTimeMs: nowMs,
|
|
56311
|
+
sessionCumulativeMetrics: {
|
|
56312
|
+
totalDurationMs: 0,
|
|
56313
|
+
inputTokens: 0,
|
|
56314
|
+
outputTokens: 0,
|
|
56315
|
+
totalTokens: 0,
|
|
56316
|
+
requestCount: 0
|
|
56317
|
+
}
|
|
56311
56318
|
};
|
|
56312
56319
|
writeCache(context.commandCacheDir, initialCache);
|
|
56313
56320
|
return {
|
|
@@ -56329,18 +56336,29 @@ function resolveLiveSpeedMetrics(context, windowSeconds) {
|
|
|
56329
56336
|
});
|
|
56330
56337
|
let nextLastActiveMetrics = { ...cached2.lastActiveMetrics };
|
|
56331
56338
|
let nextLastActiveTimeMs = cached2.lastActiveTimeMs;
|
|
56339
|
+
let nextSessionCumulative = cached2.sessionCumulativeMetrics ? { ...cached2.sessionCumulativeMetrics } : { ...cached2.lastActiveMetrics };
|
|
56332
56340
|
let nextLastSample = cached2.lastSample;
|
|
56333
56341
|
if ((deltaInput > 0 || deltaOutput > 0) && elapsedSinceLastSec >= 0.2) {
|
|
56334
56342
|
const instInput = deltaInput > 0 ? deltaInput / elapsedSinceLastSec : 0;
|
|
56335
56343
|
const instOutput = deltaOutput > 0 ? deltaOutput / elapsedSinceLastSec : 0;
|
|
56336
56344
|
if (instOutput <= MAX_PLAUSIBLE_OUTPUT_SPEED && instInput <= MAX_PLAUSIBLE_INPUT_SPEED) {
|
|
56345
|
+
const deltaDurationMs = Math.round(elapsedSinceLastSec * 1000);
|
|
56346
|
+
const validDeltaIn = Math.max(0, deltaInput);
|
|
56347
|
+
const validDeltaOut = Math.max(0, deltaOutput);
|
|
56337
56348
|
nextLastActiveMetrics = {
|
|
56338
|
-
totalDurationMs:
|
|
56339
|
-
inputTokens:
|
|
56340
|
-
outputTokens:
|
|
56341
|
-
totalTokens:
|
|
56349
|
+
totalDurationMs: deltaDurationMs,
|
|
56350
|
+
inputTokens: validDeltaIn,
|
|
56351
|
+
outputTokens: validDeltaOut,
|
|
56352
|
+
totalTokens: validDeltaIn + validDeltaOut,
|
|
56342
56353
|
requestCount: cached2.lastActiveMetrics.requestCount + 1
|
|
56343
56354
|
};
|
|
56355
|
+
nextSessionCumulative = {
|
|
56356
|
+
totalDurationMs: nextSessionCumulative.totalDurationMs + deltaDurationMs,
|
|
56357
|
+
inputTokens: nextSessionCumulative.inputTokens + validDeltaIn,
|
|
56358
|
+
outputTokens: nextSessionCumulative.outputTokens + validDeltaOut,
|
|
56359
|
+
totalTokens: nextSessionCumulative.totalTokens + validDeltaIn + validDeltaOut,
|
|
56360
|
+
requestCount: nextSessionCumulative.requestCount + 1
|
|
56361
|
+
};
|
|
56344
56362
|
nextLastActiveTimeMs = nowMs;
|
|
56345
56363
|
nextLastSample = {
|
|
56346
56364
|
timeMs: nowMs,
|
|
@@ -56348,13 +56366,20 @@ function resolveLiveSpeedMetrics(context, windowSeconds) {
|
|
|
56348
56366
|
outputTokens: rawOutput
|
|
56349
56367
|
};
|
|
56350
56368
|
}
|
|
56369
|
+
} else if (deltaInput === 0 && deltaOutput === 0 && (session?.run_state === "ready" || elapsedSinceLastSec >= 5)) {
|
|
56370
|
+
nextLastSample = {
|
|
56371
|
+
timeMs: nowMs,
|
|
56372
|
+
inputTokens: rawInput,
|
|
56373
|
+
outputTokens: rawOutput
|
|
56374
|
+
};
|
|
56351
56375
|
}
|
|
56352
56376
|
const updatedCache = {
|
|
56353
56377
|
...cached2,
|
|
56354
56378
|
lastSample: nextLastSample,
|
|
56355
56379
|
samples,
|
|
56356
56380
|
lastActiveMetrics: nextLastActiveMetrics,
|
|
56357
|
-
lastActiveTimeMs: nextLastActiveTimeMs
|
|
56381
|
+
lastActiveTimeMs: nextLastActiveTimeMs,
|
|
56382
|
+
sessionCumulativeMetrics: nextSessionCumulative
|
|
56358
56383
|
};
|
|
56359
56384
|
writeCache(context.commandCacheDir, updatedCache);
|
|
56360
56385
|
if (windowSeconds && windowSeconds > 0) {
|
|
@@ -56382,7 +56407,10 @@ function resolveLiveSpeedMetrics(context, windowSeconds) {
|
|
|
56382
56407
|
requestCount: 0
|
|
56383
56408
|
};
|
|
56384
56409
|
}
|
|
56385
|
-
if (
|
|
56410
|
+
if (nextSessionCumulative.totalDurationMs > 0) {
|
|
56411
|
+
return nextSessionCumulative;
|
|
56412
|
+
}
|
|
56413
|
+
if (nextLastActiveMetrics.totalDurationMs > 0) {
|
|
56386
56414
|
return nextLastActiveMetrics;
|
|
56387
56415
|
}
|
|
56388
56416
|
return {
|
|
@@ -59007,8 +59035,8 @@ function runRefreshCommand(cacheKey2, deps) {
|
|
|
59007
59035
|
return 0;
|
|
59008
59036
|
}
|
|
59009
59037
|
// src/version-info.ts
|
|
59010
|
-
var VERSION = "0.
|
|
59011
|
-
var SOURCE_COMMIT = /^[0-9a-f]{40}$/.test("
|
|
59038
|
+
var VERSION = "0.12.0";
|
|
59039
|
+
var SOURCE_COMMIT = /^[0-9a-f]{40}$/.test("69ccf6828b54b05fb135f113c3b0bf3a56ce8b35") ? "69ccf6828b54b05fb135f113c3b0bf3a56ce8b35" : null;
|
|
59012
59040
|
var SOURCE_DIRTY = false;
|
|
59013
59041
|
|
|
59014
59042
|
// src/context.ts
|
|
@@ -59018,8 +59046,81 @@ import { fileURLToPath } from "node:url";
|
|
|
59018
59046
|
|
|
59019
59047
|
// src/patch/preflight.ts
|
|
59020
59048
|
import { accessSync, constants as constants2, existsSync as existsSync2, statfsSync } from "node:fs";
|
|
59021
|
-
import { dirname as dirname4, join as
|
|
59049
|
+
import { dirname as dirname4, join as join8 } from "node:path";
|
|
59022
59050
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
59051
|
+
|
|
59052
|
+
// src/patch/package-assemble.ts
|
|
59053
|
+
import { join as join7 } from "node:path";
|
|
59054
|
+
var PYTHON_CANDIDATES = ["python3.13", "python3.12", "python3.11", "python3.10", "python3"];
|
|
59055
|
+
var PYTHON_VERSION_CHECK = "import sys; sys.exit(sys.version_info < (3, 10))";
|
|
59056
|
+
function assembleArgs(input2) {
|
|
59057
|
+
const args = [
|
|
59058
|
+
join7(input2.upstream, "scripts", "build_codex_package.py"),
|
|
59059
|
+
"--variant",
|
|
59060
|
+
"codex",
|
|
59061
|
+
"--target",
|
|
59062
|
+
input2.target,
|
|
59063
|
+
"--package-version",
|
|
59064
|
+
input2.codexVersion,
|
|
59065
|
+
"--entrypoint-bin",
|
|
59066
|
+
input2.codex,
|
|
59067
|
+
"--code-mode-host-bin",
|
|
59068
|
+
input2.codeModeHost,
|
|
59069
|
+
"--cargo",
|
|
59070
|
+
input2.cargo,
|
|
59071
|
+
"--cargo-profile",
|
|
59072
|
+
"release",
|
|
59073
|
+
"--package-dir",
|
|
59074
|
+
input2.packageDir
|
|
59075
|
+
];
|
|
59076
|
+
if (input2.bwrapBin)
|
|
59077
|
+
args.push("--bwrap-bin", input2.bwrapBin);
|
|
59078
|
+
if (input2.force)
|
|
59079
|
+
args.push("--force");
|
|
59080
|
+
return args;
|
|
59081
|
+
}
|
|
59082
|
+
function assembleEnv(input2, base2 = process.env) {
|
|
59083
|
+
const keep = ["PATH", "HOME", "CARGO_HOME", "RUSTUP_HOME", "HTTPS_PROXY", "HTTP_PROXY", "NO_PROXY", "https_proxy", "http_proxy", "no_proxy", "SSL_CERT_FILE", "RUSTC_WRAPPER", "SCCACHE_DIR"];
|
|
59084
|
+
const env3 = {};
|
|
59085
|
+
for (const key of keep)
|
|
59086
|
+
if (base2[key] !== undefined)
|
|
59087
|
+
env3[key] = base2[key];
|
|
59088
|
+
env3.CODEX_REPO_ROOT = input2.upstream;
|
|
59089
|
+
env3.TMPDIR = input2.tmpDir;
|
|
59090
|
+
return env3;
|
|
59091
|
+
}
|
|
59092
|
+
function assemblePackage(input2, run, log) {
|
|
59093
|
+
const args = assembleArgs(input2);
|
|
59094
|
+
log(`$ ${[input2.python, ...args].join(" ")}`);
|
|
59095
|
+
const r = run(input2.python, args, { cwd: input2.upstream, env: assembleEnv(input2) });
|
|
59096
|
+
for (const line of `${r.stdout}${r.stderr}`.split(`
|
|
59097
|
+
`).filter(Boolean))
|
|
59098
|
+
log(line);
|
|
59099
|
+
if (r.status !== 0) {
|
|
59100
|
+
throw new Error(`build_codex_package.py failed (exit ${String(r.status)}): ${(r.stderr || r.stdout).trim().split(`
|
|
59101
|
+
`).slice(-12).join(`
|
|
59102
|
+
`)}`);
|
|
59103
|
+
}
|
|
59104
|
+
}
|
|
59105
|
+
function findPython(which, run) {
|
|
59106
|
+
for (const candidate of PYTHON_CANDIDATES) {
|
|
59107
|
+
const bin = which(candidate);
|
|
59108
|
+
if (bin === null)
|
|
59109
|
+
continue;
|
|
59110
|
+
if (run(bin, ["-c", PYTHON_VERSION_CHECK]).status === 0)
|
|
59111
|
+
return bin;
|
|
59112
|
+
}
|
|
59113
|
+
return null;
|
|
59114
|
+
}
|
|
59115
|
+
function rustcHostTarget(run) {
|
|
59116
|
+
const r = run("rustc", ["-vV"]);
|
|
59117
|
+
const host = /^host:\s*(\S+)\s*$/m.exec(r.stdout)?.[1];
|
|
59118
|
+
if (r.status !== 0 || !host)
|
|
59119
|
+
throw new Error(`rustc -vV did not report a host target: ${(r.stderr || r.stdout).trim().slice(0, 200)}`);
|
|
59120
|
+
return host;
|
|
59121
|
+
}
|
|
59122
|
+
|
|
59123
|
+
// src/patch/preflight.ts
|
|
59023
59124
|
var MIN_FREE_BYTES = 20 * 1024 ** 3;
|
|
59024
59125
|
var MIN_STAGING_FREE_BYTES = 2 * 1024 ** 3;
|
|
59025
59126
|
var REQUIRED_TOOLCHAIN = "1.95.0";
|
|
@@ -59056,6 +59157,15 @@ function preflight(deps, shareDir) {
|
|
|
59056
59157
|
const toolchain = checkToolchain(deps);
|
|
59057
59158
|
if (!toolchain.ok)
|
|
59058
59159
|
return toolchain;
|
|
59160
|
+
if (findPython(deps.which, deps.run) === null) {
|
|
59161
|
+
return no("Python >= 3.10 is not on PATH; Codex's package is assembled by upstream's Python packager", "brew install python (or apt install python3), then reopen your shell");
|
|
59162
|
+
}
|
|
59163
|
+
if (process.platform === "linux" && !deps.which("bwrap")) {
|
|
59164
|
+
const libcap = deps.run("pkg-config", ["--exists", "libcap"]);
|
|
59165
|
+
if (!deps.which("pkg-config") || libcap.status !== 0) {
|
|
59166
|
+
return no("bubblewrap is not on PATH and libcap-dev is not installed; Codex's Linux package needs one of them for its sandbox", "apt install bubblewrap (or apt install libcap-dev pkg-config), then re-run");
|
|
59167
|
+
}
|
|
59168
|
+
}
|
|
59059
59169
|
const free = deps.freeBytes(shareDir);
|
|
59060
59170
|
if (free < MIN_FREE_BYTES) {
|
|
59061
59171
|
return no(`${gib(free)} free at ${shareDir}; a Codex release build needs 20 GiB`, "free disk space or point XDG_DATA_HOME elsewhere");
|
|
@@ -59079,7 +59189,7 @@ function prebuiltPreflight(deps, paths) {
|
|
|
59079
59189
|
}
|
|
59080
59190
|
function whichReal(cmd) {
|
|
59081
59191
|
for (const dir of (process.env.PATH ?? "").split(":").filter(Boolean)) {
|
|
59082
|
-
const p =
|
|
59192
|
+
const p = join8(dir, cmd);
|
|
59083
59193
|
try {
|
|
59084
59194
|
accessSync(p, constants2.X_OK);
|
|
59085
59195
|
return p;
|
|
@@ -59149,8 +59259,8 @@ function realContext(env3, io) {
|
|
|
59149
59259
|
}
|
|
59150
59260
|
|
|
59151
59261
|
// src/patch/run.ts
|
|
59152
|
-
import { appendFileSync, mkdirSync as
|
|
59153
|
-
import { join as
|
|
59262
|
+
import { appendFileSync, mkdirSync as mkdirSync9, rmSync as rmSync6 } from "node:fs";
|
|
59263
|
+
import { join as join19 } from "node:path";
|
|
59154
59264
|
|
|
59155
59265
|
// src/lock.ts
|
|
59156
59266
|
import { closeSync, existsSync as existsSync4, mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4, unlinkSync as unlinkSync3, writeSync } from "node:fs";
|
|
@@ -59204,11 +59314,6 @@ function acquireLock(file2, isAlive = pidAlive) {
|
|
|
59204
59314
|
return null;
|
|
59205
59315
|
}
|
|
59206
59316
|
|
|
59207
|
-
// src/distribution/files.ts
|
|
59208
|
-
var GENERATION_EXECUTABLES = ["codex", "codex-code-mode-host"];
|
|
59209
|
-
var GENERATION_LEGAL_FILES = ["LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.md"];
|
|
59210
|
-
var ARTIFACT_FILES = [...GENERATION_EXECUTABLES, ...GENERATION_LEGAL_FILES];
|
|
59211
|
-
|
|
59212
59317
|
// src/version.ts
|
|
59213
59318
|
var POLICIES = ["every", "stable-minors", "manual"];
|
|
59214
59319
|
var SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
@@ -59258,20 +59363,95 @@ function behindWithinMinor(upstream, patched) {
|
|
|
59258
59363
|
}
|
|
59259
59364
|
|
|
59260
59365
|
// src/distribution/prebuilt.ts
|
|
59261
|
-
import {
|
|
59262
|
-
import {
|
|
59263
|
-
import { join as join11 } from "node:path";
|
|
59366
|
+
import { chmodSync as chmodSync2, copyFileSync, mkdirSync as mkdirSync6, mkdtempSync, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync2 } from "node:fs";
|
|
59367
|
+
import { join as join12 } from "node:path";
|
|
59264
59368
|
|
|
59265
59369
|
// src/patch/generation.ts
|
|
59266
|
-
import { chmodSync,
|
|
59267
|
-
import {
|
|
59268
|
-
import { dirname as dirname6, isAbsolute, join as
|
|
59269
|
-
|
|
59270
|
-
|
|
59370
|
+
import { chmodSync, cpSync, existsSync as existsSync5, lstatSync as lstatSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync2, readlinkSync, realpathSync as realpathSync2, renameSync as renameSync2, rmSync, statSync, symlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
59371
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
59372
|
+
import { dirname as dirname6, isAbsolute, join as join9, relative, resolve as resolve2, sep } from "node:path";
|
|
59373
|
+
|
|
59374
|
+
// src/digest.ts
|
|
59375
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
59376
|
+
import { createReadStream, readFileSync as readFileSync5 } from "node:fs";
|
|
59271
59377
|
function digestOf(file2) {
|
|
59272
59378
|
const buf = readFileSync5(file2);
|
|
59273
59379
|
return { sha256: createHash2("sha256").update(buf).digest("hex"), size: buf.length };
|
|
59274
59380
|
}
|
|
59381
|
+
|
|
59382
|
+
// src/patch/generation.ts
|
|
59383
|
+
var INSTALLATION_FILE = "installation.json";
|
|
59384
|
+
var GENERATION_EXECUTABLES = ["codex", "codex-code-mode-host"];
|
|
59385
|
+
var GENERATION_LEGAL_FILES = ["LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.md"];
|
|
59386
|
+
var SAFE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;
|
|
59387
|
+
var ROOT_ALIAS = "codex";
|
|
59388
|
+
function isPackageLayout(dir) {
|
|
59389
|
+
return existsSync5(join9(dir, "bin", "codex")) && existsSync5(join9(dir, "codex-package.json"));
|
|
59390
|
+
}
|
|
59391
|
+
function executablePath(dir, name) {
|
|
59392
|
+
return isPackageLayout(dir) ? join9(dir, "bin", name) : join9(dir, name);
|
|
59393
|
+
}
|
|
59394
|
+
var PackageMetadata = exports_external.object({
|
|
59395
|
+
version: exports_external.string(),
|
|
59396
|
+
target: exports_external.string(),
|
|
59397
|
+
entrypoint: exports_external.string()
|
|
59398
|
+
}).passthrough();
|
|
59399
|
+
function verifyPackage(dir, files, expect) {
|
|
59400
|
+
for (const [name, want] of Object.entries(files)) {
|
|
59401
|
+
const file2 = join9(dir, name);
|
|
59402
|
+
let st;
|
|
59403
|
+
try {
|
|
59404
|
+
st = lstatSync3(file2);
|
|
59405
|
+
} catch {
|
|
59406
|
+
return `${name} is missing`;
|
|
59407
|
+
}
|
|
59408
|
+
if (!st.isFile())
|
|
59409
|
+
return `${name} is not a regular file`;
|
|
59410
|
+
const executable = (st.mode & 73) !== 0;
|
|
59411
|
+
if (executable !== (modeFor(name) === 493))
|
|
59412
|
+
return `${name} has the wrong executable bit`;
|
|
59413
|
+
const got = digestOf(file2);
|
|
59414
|
+
if (got.sha256 !== want.sha256 || got.size !== want.size)
|
|
59415
|
+
return `${name} does not match its recorded digest`;
|
|
59416
|
+
}
|
|
59417
|
+
let metadata;
|
|
59418
|
+
try {
|
|
59419
|
+
metadata = PackageMetadata.parse(JSON.parse(readFileSync6(join9(dir, "codex-package.json"), "utf8")));
|
|
59420
|
+
} catch (e) {
|
|
59421
|
+
return `codex-package.json is unreadable: ${e instanceof Error ? e.message.split(`
|
|
59422
|
+
`)[0] : String(e)}`;
|
|
59423
|
+
}
|
|
59424
|
+
if (metadata.entrypoint !== "bin/codex")
|
|
59425
|
+
return `codex-package.json entrypoint is ${JSON.stringify(metadata.entrypoint)}, not "bin/codex"`;
|
|
59426
|
+
if (metadata.target !== expect.target)
|
|
59427
|
+
return `codex-package.json target is ${metadata.target}, expected ${expect.target}`;
|
|
59428
|
+
if (metadata.version !== expect.codexVersion)
|
|
59429
|
+
return `codex-package.json version is ${metadata.version}, expected ${expect.codexVersion}`;
|
|
59430
|
+
return null;
|
|
59431
|
+
}
|
|
59432
|
+
function packageFiles(dir) {
|
|
59433
|
+
const out = {};
|
|
59434
|
+
const walk = (current) => {
|
|
59435
|
+
for (const name of readdirSync2(current).sort()) {
|
|
59436
|
+
const path = join9(current, name);
|
|
59437
|
+
const rel = relative(dir, path).split(sep).join("/");
|
|
59438
|
+
const st = lstatSync3(path);
|
|
59439
|
+
if (rel === INSTALLATION_FILE || rel === ROOT_ALIAS && st.isSymbolicLink())
|
|
59440
|
+
continue;
|
|
59441
|
+
if (st.isSymbolicLink())
|
|
59442
|
+
throw new Error(`${rel} is a symbolic link; a Codex package may only contain regular files`);
|
|
59443
|
+
if (st.isDirectory()) {
|
|
59444
|
+
walk(path);
|
|
59445
|
+
continue;
|
|
59446
|
+
}
|
|
59447
|
+
if (!st.isFile())
|
|
59448
|
+
throw new Error(`${rel} is not a regular file`);
|
|
59449
|
+
out[rel] = digestOf(path);
|
|
59450
|
+
}
|
|
59451
|
+
};
|
|
59452
|
+
walk(dir);
|
|
59453
|
+
return out;
|
|
59454
|
+
}
|
|
59275
59455
|
function stamp(installedAt) {
|
|
59276
59456
|
const parsed = new Date(installedAt);
|
|
59277
59457
|
const when = Number.isNaN(parsed.getTime()) ? new Date : parsed;
|
|
@@ -59302,40 +59482,31 @@ function validateStaging(pair) {
|
|
|
59302
59482
|
if (!SAFE_SEGMENT.test(pair.codexVersion)) {
|
|
59303
59483
|
throw new Error(`prepared pair has an unusable codexVersion "${pair.codexVersion}"`);
|
|
59304
59484
|
}
|
|
59305
|
-
|
|
59306
|
-
|
|
59307
|
-
|
|
59308
|
-
throw new Error(`staged pair is missing ${name}`);
|
|
59309
|
-
const want = pair.provenance.executables[name];
|
|
59310
|
-
const got = digestOf(file2);
|
|
59311
|
-
if (got.sha256 !== want.sha256 || got.size !== want.size) {
|
|
59312
|
-
throw new Error(`staged ${name} does not match its recorded digest; refusing to install it`);
|
|
59313
|
-
}
|
|
59314
|
-
}
|
|
59485
|
+
const problem = verifyPackage(pair.directory, pair.provenance.files, { target: pair.provenance.target, codexVersion: pair.codexVersion });
|
|
59486
|
+
if (problem !== null)
|
|
59487
|
+
throw new Error(`staged package is not the one its provenance describes: ${problem}; refusing to install it`);
|
|
59315
59488
|
if (pair.provenance.source === "prebuilt") {
|
|
59316
59489
|
for (const name of GENERATION_LEGAL_FILES) {
|
|
59317
|
-
if (!existsSync5(
|
|
59490
|
+
if (!(name in pair.provenance.files) || !existsSync5(join9(pair.directory, name)))
|
|
59318
59491
|
throw new Error(`prebuilt pair is missing ${name}`);
|
|
59319
59492
|
}
|
|
59320
59493
|
}
|
|
59494
|
+
for (const name of GENERATION_EXECUTABLES) {
|
|
59495
|
+
const want = pair.provenance.files[`bin/${name}`];
|
|
59496
|
+
if (!want)
|
|
59497
|
+
throw new Error(`staged pair is missing bin/${name}`);
|
|
59498
|
+
const got = digestOf(join9(pair.directory, "bin", name));
|
|
59499
|
+
if (got.sha256 !== want.sha256 || got.size !== want.size) {
|
|
59500
|
+
throw new Error(`staged bin/${name} does not match its recorded digest; refusing to install it`);
|
|
59501
|
+
}
|
|
59502
|
+
}
|
|
59321
59503
|
}
|
|
59322
59504
|
function installationRecord(pair) {
|
|
59323
59505
|
const { directory: _staging, ...record2 } = pair;
|
|
59324
59506
|
return record2;
|
|
59325
59507
|
}
|
|
59326
|
-
function copyInto(from, into, name, mode, expected) {
|
|
59327
|
-
const target = join8(into, name);
|
|
59328
|
-
copyFileSync(join8(from, name), target);
|
|
59329
|
-
chmodSync(target, mode);
|
|
59330
|
-
if (!expected)
|
|
59331
|
-
return;
|
|
59332
|
-
const got = digestOf(target);
|
|
59333
|
-
if (got.sha256 !== expected.sha256 || got.size !== expected.size) {
|
|
59334
|
-
throw new Error(`${name} did not survive the copy into the new generation intact`);
|
|
59335
|
-
}
|
|
59336
|
-
}
|
|
59337
59508
|
function commitJson(file2, value, rename2) {
|
|
59338
|
-
const tmp =
|
|
59509
|
+
const tmp = join9(dirname6(file2), `.${process.pid}.${randomBytes2(4).toString("hex")}.tmp`);
|
|
59339
59510
|
try {
|
|
59340
59511
|
writeFileSync2(tmp, `${JSON.stringify(value, null, 2)}
|
|
59341
59512
|
`);
|
|
@@ -59345,27 +59516,30 @@ function commitJson(file2, value, rename2) {
|
|
|
59345
59516
|
throw e;
|
|
59346
59517
|
}
|
|
59347
59518
|
}
|
|
59348
|
-
|
|
59519
|
+
var GENERATION_NAME = /^\d+\.\d+\.\d+-\d{8}T\d{6}-[0-9a-f]{6}$/;
|
|
59520
|
+
function freshName(pair, paths) {
|
|
59349
59521
|
mkdirSync4(paths.generationsDir, { recursive: true });
|
|
59350
59522
|
for (;; ) {
|
|
59351
|
-
const dir =
|
|
59352
|
-
if (existsSync5(dir))
|
|
59353
|
-
|
|
59354
|
-
mkdirSync4(dir);
|
|
59355
|
-
return dir;
|
|
59523
|
+
const dir = join9(paths.generationsDir, `${pair.codexVersion}-${stamp(pair.provenance.installedAt)}-${randomBytes2(3).toString("hex")}`);
|
|
59524
|
+
if (!existsSync5(dir))
|
|
59525
|
+
return dir;
|
|
59356
59526
|
}
|
|
59357
59527
|
}
|
|
59358
59528
|
function createGeneration(pair, paths, rename2 = renameSync2) {
|
|
59359
59529
|
validateStaging(pair);
|
|
59360
|
-
const dir =
|
|
59530
|
+
const dir = freshName(pair, paths);
|
|
59361
59531
|
try {
|
|
59362
|
-
|
|
59363
|
-
|
|
59364
|
-
|
|
59365
|
-
|
|
59366
|
-
|
|
59367
|
-
}
|
|
59368
|
-
|
|
59532
|
+
rename2(pair.directory, dir);
|
|
59533
|
+
} catch (e) {
|
|
59534
|
+
if (e.code !== "EXDEV")
|
|
59535
|
+
throw e;
|
|
59536
|
+
cpSync(pair.directory, dir, { recursive: true, verbatimSymlinks: true });
|
|
59537
|
+
rmSync(pair.directory, { recursive: true, force: true });
|
|
59538
|
+
}
|
|
59539
|
+
try {
|
|
59540
|
+
chmodSync(dir, 493);
|
|
59541
|
+
symlinkSync("bin/codex", join9(dir, ROOT_ALIAS));
|
|
59542
|
+
commitJson(join9(dir, INSTALLATION_FILE), installationRecord(pair), rename2);
|
|
59369
59543
|
} catch (e) {
|
|
59370
59544
|
rmSync(dir, { recursive: true, force: true });
|
|
59371
59545
|
throw e;
|
|
@@ -59373,11 +59547,11 @@ function createGeneration(pair, paths, rename2 = renameSync2) {
|
|
|
59373
59547
|
return dir;
|
|
59374
59548
|
}
|
|
59375
59549
|
function isGenerationDir(dir) {
|
|
59376
|
-
return existsSync5(
|
|
59550
|
+
return existsSync5(join9(dir, INSTALLATION_FILE)) && isPackageLayout(dir);
|
|
59377
59551
|
}
|
|
59378
59552
|
function listGenerations(paths) {
|
|
59379
59553
|
try {
|
|
59380
|
-
return readdirSync2(paths.generationsDir).map((name) =>
|
|
59554
|
+
return readdirSync2(paths.generationsDir).map((name) => join9(paths.generationsDir, name)).sort();
|
|
59381
59555
|
} catch {
|
|
59382
59556
|
return [];
|
|
59383
59557
|
}
|
|
@@ -59441,7 +59615,9 @@ var RecordSchema = exports_external.object({
|
|
|
59441
59615
|
sourceCommit: exports_external.string().regex(HEX40, "sourceCommit must be 40 lowercase hex chars").nullable(),
|
|
59442
59616
|
sourceDirty: exports_external.boolean(),
|
|
59443
59617
|
installedAt: exports_external.string(),
|
|
59444
|
-
|
|
59618
|
+
target: exports_external.string().optional(),
|
|
59619
|
+
files: exports_external.record(exports_external.string(), DigestSchema).optional(),
|
|
59620
|
+
executables: exports_external.object({ codex: DigestSchema, "codex-code-mode-host": DigestSchema }).optional(),
|
|
59445
59621
|
release: exports_external.object({
|
|
59446
59622
|
tag: exports_external.string(),
|
|
59447
59623
|
archiveSha256: exports_external.string().regex(HEX64, "archiveSha256 must be 64 lowercase hex chars"),
|
|
@@ -59475,7 +59651,7 @@ function readInstallation(paths) {
|
|
|
59475
59651
|
if (dir === null)
|
|
59476
59652
|
return null;
|
|
59477
59653
|
try {
|
|
59478
|
-
const raw = JSON.parse(
|
|
59654
|
+
const raw = JSON.parse(readFileSync6(join9(dir, INSTALLATION_FILE), "utf8"));
|
|
59479
59655
|
return checkedRecord(raw);
|
|
59480
59656
|
} catch {
|
|
59481
59657
|
return null;
|
|
@@ -59483,8 +59659,8 @@ function readInstallation(paths) {
|
|
|
59483
59659
|
}
|
|
59484
59660
|
|
|
59485
59661
|
// src/distribution/archive.ts
|
|
59486
|
-
import { createReadStream, createWriteStream } from "node:fs";
|
|
59487
|
-
import { join as
|
|
59662
|
+
import { createReadStream as createReadStream2, createWriteStream, mkdirSync as mkdirSync5 } from "node:fs";
|
|
59663
|
+
import { dirname as dirname7, join as join10 } from "node:path";
|
|
59488
59664
|
import { createGunzip } from "node:zlib";
|
|
59489
59665
|
|
|
59490
59666
|
// node_modules/tar/dist/esm/index.min.js
|
|
@@ -62710,13 +62886,12 @@ var To = (s3) => {
|
|
|
62710
62886
|
};
|
|
62711
62887
|
|
|
62712
62888
|
// src/distribution/archive.ts
|
|
62713
|
-
var ALLOWED = ARTIFACT_FILES;
|
|
62714
62889
|
var EXTRACTED_TOTAL_LIMIT = 2 * 1024 * 1024 * 1024;
|
|
62715
62890
|
var LEGAL_TOTAL_LIMIT = 16 * 1024 * 1024;
|
|
62716
62891
|
var EXECUTABLE_MODE = 493;
|
|
62717
62892
|
var LEGAL_MODE = 420;
|
|
62718
62893
|
function isExecutable(name) {
|
|
62719
|
-
return
|
|
62894
|
+
return modeFor(name) === 493;
|
|
62720
62895
|
}
|
|
62721
62896
|
function quoteName(name) {
|
|
62722
62897
|
return JSON.stringify(name.replace(/[\u0000-\u001f\u007f]/g, "?").slice(0, 120));
|
|
@@ -62724,13 +62899,13 @@ function quoteName(name) {
|
|
|
62724
62899
|
function toError(cause) {
|
|
62725
62900
|
return cause instanceof Error ? cause : new Error(String(cause));
|
|
62726
62901
|
}
|
|
62727
|
-
function rejectionReason(entry, seen, budget) {
|
|
62902
|
+
function rejectionReason(entry, seen, budget, expected) {
|
|
62728
62903
|
const name = entry.path;
|
|
62729
62904
|
if (entry.type !== "File") {
|
|
62730
62905
|
return `archive entry ${quoteName(name)} is a ${entry.type}, not a regular file`;
|
|
62731
62906
|
}
|
|
62732
|
-
if (!
|
|
62733
|
-
return `archive entry ${quoteName(name)} is not
|
|
62907
|
+
if (!Object.hasOwn(expected, name) || entry.header.path !== name) {
|
|
62908
|
+
return `archive entry ${quoteName(name)} is not listed in the release manifest`;
|
|
62734
62909
|
}
|
|
62735
62910
|
if (seen.has(name))
|
|
62736
62911
|
return `archive contains ${quoteName(name)} more than once`;
|
|
@@ -62739,6 +62914,9 @@ function rejectionReason(entry, seen, budget) {
|
|
|
62739
62914
|
const size2 = entry.size;
|
|
62740
62915
|
if (!Number.isSafeInteger(size2) || size2 < 0)
|
|
62741
62916
|
return `archive entry ${quoteName(name)} declares an unusable size`;
|
|
62917
|
+
if (size2 !== expected[name].size) {
|
|
62918
|
+
return `archive entry ${quoteName(name)} declares ${size2} bytes but the manifest records ${expected[name].size}`;
|
|
62919
|
+
}
|
|
62742
62920
|
const executable = isExecutable(name);
|
|
62743
62921
|
if (executable && size2 === 0)
|
|
62744
62922
|
return `archive entry ${quoteName(name)} is an empty executable`;
|
|
@@ -62756,10 +62934,13 @@ function rejectionReason(entry, seen, budget) {
|
|
|
62756
62934
|
budget.legal += size2;
|
|
62757
62935
|
return null;
|
|
62758
62936
|
}
|
|
62759
|
-
function writeEntry(entry, staging) {
|
|
62937
|
+
function writeEntry(entry, staging, expected) {
|
|
62760
62938
|
const name = entry.path;
|
|
62761
62939
|
const mode = isExecutable(name) ? EXECUTABLE_MODE : LEGAL_MODE;
|
|
62762
|
-
const
|
|
62940
|
+
const target = join10(staging, name);
|
|
62941
|
+
if (name.includes("/"))
|
|
62942
|
+
mkdirSync5(dirname7(target), { recursive: true });
|
|
62943
|
+
const sink = createWriteStream(target, { mode, flags: "wx" });
|
|
62763
62944
|
const done = new Promise((resolve3, reject2) => {
|
|
62764
62945
|
sink.on("error", reject2);
|
|
62765
62946
|
entry.on("error", reject2);
|
|
@@ -62780,11 +62961,11 @@ function writeEntry(entry, staging) {
|
|
|
62780
62961
|
}
|
|
62781
62962
|
};
|
|
62782
62963
|
}
|
|
62783
|
-
function parseArchive(archivePath, staging, writes) {
|
|
62964
|
+
function parseArchive(archivePath, staging, writes, expected) {
|
|
62784
62965
|
const seen = new Set;
|
|
62785
62966
|
const budget = { total: 0, legal: 0 };
|
|
62786
62967
|
return new Promise((resolve3, reject2) => {
|
|
62787
|
-
const source =
|
|
62968
|
+
const source = createReadStream2(archivePath);
|
|
62788
62969
|
const gunzip = createGunzip();
|
|
62789
62970
|
let settled = false;
|
|
62790
62971
|
const fail = (cause) => {
|
|
@@ -62804,14 +62985,14 @@ function parseArchive(archivePath, staging, writes) {
|
|
|
62804
62985
|
entry.resume();
|
|
62805
62986
|
return;
|
|
62806
62987
|
}
|
|
62807
|
-
const reason = rejectionReason(entry, seen, budget);
|
|
62988
|
+
const reason = rejectionReason(entry, seen, budget, expected);
|
|
62808
62989
|
if (reason !== null) {
|
|
62809
62990
|
fail(new Error(reason));
|
|
62810
62991
|
entry.resume();
|
|
62811
62992
|
return;
|
|
62812
62993
|
}
|
|
62813
62994
|
seen.add(entry.path);
|
|
62814
|
-
writes.push(writeEntry(entry, staging));
|
|
62995
|
+
writes.push(writeEntry(entry, staging, expected));
|
|
62815
62996
|
});
|
|
62816
62997
|
parser.on("error", fail);
|
|
62817
62998
|
gunzip.on("error", fail);
|
|
@@ -62820,7 +63001,7 @@ function parseArchive(archivePath, staging, writes) {
|
|
|
62820
63001
|
if (settled)
|
|
62821
63002
|
return;
|
|
62822
63003
|
settled = true;
|
|
62823
|
-
const missing =
|
|
63004
|
+
const missing = Object.keys(expected).filter((name) => !seen.has(name));
|
|
62824
63005
|
if (missing.length > 0) {
|
|
62825
63006
|
reject2(new Error(`archive is missing ${missing.join(", ")}`));
|
|
62826
63007
|
return;
|
|
@@ -62830,10 +63011,11 @@ function parseArchive(archivePath, staging, writes) {
|
|
|
62830
63011
|
source.pipe(gunzip).pipe(parser);
|
|
62831
63012
|
});
|
|
62832
63013
|
}
|
|
62833
|
-
async function extractArchive(archivePath, staging) {
|
|
63014
|
+
async function extractArchive(archivePath, staging, files) {
|
|
63015
|
+
const expected = files;
|
|
62834
63016
|
const writes = [];
|
|
62835
63017
|
try {
|
|
62836
|
-
await parseArchive(archivePath, staging, writes);
|
|
63018
|
+
await parseArchive(archivePath, staging, writes, expected);
|
|
62837
63019
|
} catch (e) {
|
|
62838
63020
|
await Promise.allSettled(writes.map((w2) => w2.done));
|
|
62839
63021
|
throw e;
|
|
@@ -62843,9 +63025,9 @@ async function extractArchive(archivePath, staging) {
|
|
|
62843
63025
|
|
|
62844
63026
|
// src/distribution/transport.ts
|
|
62845
63027
|
import { createHash as createHash3 } from "node:crypto";
|
|
62846
|
-
import { createReadStream as
|
|
63028
|
+
import { createReadStream as createReadStream3, existsSync as existsSync6, renameSync as renameSync3 } from "node:fs";
|
|
62847
63029
|
import { open as open2 } from "node:fs/promises";
|
|
62848
|
-
import { dirname as
|
|
63030
|
+
import { dirname as dirname8, join as join11 } from "node:path";
|
|
62849
63031
|
var PUBLIC_BASE = "https://github.com/adrijshikhar/cxstatusline/releases/download";
|
|
62850
63032
|
var REPO = "adrijshikhar/cxstatusline";
|
|
62851
63033
|
var MAX_REDIRECTS = 5;
|
|
@@ -62893,7 +63075,7 @@ function nextUrl(current, location, allowHttp, asset) {
|
|
|
62893
63075
|
async function hashExistingFile(file2, maxBytes, asset) {
|
|
62894
63076
|
const hash2 = createHash3("sha256");
|
|
62895
63077
|
let size2 = 0;
|
|
62896
|
-
for await (const chunk2 of
|
|
63078
|
+
for await (const chunk2 of createReadStream3(file2)) {
|
|
62897
63079
|
const buf = chunk2;
|
|
62898
63080
|
size2 += buf.length;
|
|
62899
63081
|
if (size2 > maxBytes)
|
|
@@ -63091,7 +63273,7 @@ async function ghDownload(ctx, tag, asset, dest, maxBytes) {
|
|
|
63091
63273
|
if (ctx.which("gh") === null) {
|
|
63092
63274
|
throw new GhMissingError(`${asset} is not public for release ${tag} and GitHub CLI (gh) is not installed`);
|
|
63093
63275
|
}
|
|
63094
|
-
const targetDir =
|
|
63276
|
+
const targetDir = dirname8(dest);
|
|
63095
63277
|
const result2 = ctx.run("gh", ["release", "download", tag, "--repo", REPO, "--pattern", asset, "--dir", targetDir], { timeoutMs: GH_TIMEOUT_MS });
|
|
63096
63278
|
if (result2.status !== 0) {
|
|
63097
63279
|
const detail = sanitize(result2.stderr || result2.stdout);
|
|
@@ -63100,7 +63282,7 @@ async function ghDownload(ctx, tag, asset, dest, maxBytes) {
|
|
|
63100
63282
|
}
|
|
63101
63283
|
throw new ReleaseUnavailableError(`release ${tag} not found or access denied: ${detail}`);
|
|
63102
63284
|
}
|
|
63103
|
-
const downloadedFile =
|
|
63285
|
+
const downloadedFile = join11(targetDir, asset);
|
|
63104
63286
|
if (!existsSync6(downloadedFile) && !existsSync6(dest)) {
|
|
63105
63287
|
throw new ReleaseUnavailableError(`release ${tag} not found or access denied: gh downloaded no ${asset}`);
|
|
63106
63288
|
}
|
|
@@ -63120,16 +63302,9 @@ async function downloadAsset(ctx, tag, asset, dest, maxBytes, opts = {}) {
|
|
|
63120
63302
|
// src/distribution/prebuilt.ts
|
|
63121
63303
|
var MANIFEST_ASSET = "manifest.json";
|
|
63122
63304
|
var PROBE_TIMEOUT_MS = 30000;
|
|
63123
|
-
function digestOf2(file2) {
|
|
63124
|
-
const bytes = readFileSync6(file2);
|
|
63125
|
-
return { sha256: createHash4("sha256").update(bytes).digest("hex"), size: bytes.length };
|
|
63126
|
-
}
|
|
63127
|
-
function sameDigest(a, b2) {
|
|
63128
|
-
return a.sha256 === b2.sha256 && a.size === b2.size;
|
|
63129
|
-
}
|
|
63130
63305
|
function privateTemp(ctx, prefix) {
|
|
63131
|
-
|
|
63132
|
-
const dir = mkdtempSync(
|
|
63306
|
+
mkdirSync6(ctx.paths.libexecDir, { recursive: true });
|
|
63307
|
+
const dir = mkdtempSync(join12(ctx.paths.libexecDir, prefix));
|
|
63133
63308
|
chmodSync2(dir, 448);
|
|
63134
63309
|
return dir;
|
|
63135
63310
|
}
|
|
@@ -63147,45 +63322,35 @@ function unchangedPair(ctx, manifest, artifact, tag) {
|
|
|
63147
63322
|
if (!release || release.tag !== tag || release.archiveSha256 !== artifact.sha256)
|
|
63148
63323
|
return null;
|
|
63149
63324
|
const installed = release.manifest;
|
|
63150
|
-
const identical = record2.codexVersion === manifest.codexVersion && record2.provenance.cxVersion === manifest.cxVersion && record2.provenance.platform === artifact.platform && record2.provenance.patchVersion === manifest.patchVersion && record2.provenance.patchSha256 === manifest.patchSha256 && record2.provenance.upstreamCommit === manifest.upstreamCommit && installed.cxVersion === manifest.cxVersion && installed.codexVersion === manifest.codexVersion && installed.patchSha256 === manifest.patchSha256 && installed.upstreamCommit === manifest.upstreamCommit;
|
|
63325
|
+
const identical = record2.codexVersion === manifest.codexVersion && (manifest.cxVersion === undefined || record2.provenance.cxVersion === manifest.cxVersion) && record2.provenance.platform === artifact.platform && record2.provenance.patchVersion === manifest.patchVersion && record2.provenance.patchSha256 === manifest.patchSha256 && record2.provenance.upstreamCommit === manifest.upstreamCommit && (manifest.cxVersion === undefined || installed.cxVersion === manifest.cxVersion) && installed.codexVersion === manifest.codexVersion && installed.patchSha256 === manifest.patchSha256 && installed.upstreamCommit === manifest.upstreamCommit;
|
|
63151
63326
|
if (!identical)
|
|
63152
63327
|
return null;
|
|
63153
63328
|
const directory = activeGeneration(ctx.paths);
|
|
63154
63329
|
if (directory === null)
|
|
63155
63330
|
return null;
|
|
63156
|
-
|
|
63157
|
-
|
|
63158
|
-
|
|
63159
|
-
|
|
63160
|
-
} catch {
|
|
63161
|
-
return null;
|
|
63162
|
-
}
|
|
63163
|
-
}
|
|
63331
|
+
if (record2.provenance.files === undefined || !isPackageLayout(directory))
|
|
63332
|
+
return null;
|
|
63333
|
+
if (verifyPackage(directory, artifact.files, { target: codexTarget(artifact.platform), codexVersion: manifest.codexVersion }) !== null)
|
|
63334
|
+
return null;
|
|
63164
63335
|
return { directory, codexVersion: record2.codexVersion, provenance: record2.provenance };
|
|
63165
63336
|
}
|
|
63166
|
-
function verifyStaged(staging, artifact) {
|
|
63167
|
-
|
|
63168
|
-
|
|
63169
|
-
const got = digestOf2(join11(staging, name));
|
|
63170
|
-
if (!sameDigest(got, artifact.files[name])) {
|
|
63171
|
-
throw new Error(`staged ${name} does not match the release manifest sha256`);
|
|
63172
|
-
}
|
|
63173
|
-
digests[name] = got;
|
|
63337
|
+
function verifyStaged(staging, manifest, artifact) {
|
|
63338
|
+
if (manifest.schema !== 3) {
|
|
63339
|
+
throw new Error(`release ${releaseTag(manifest.codexVersion)} predates cxstatusline 0.11 and has not been republished yet; use --compile or wait`);
|
|
63174
63340
|
}
|
|
63175
|
-
|
|
63176
|
-
|
|
63177
|
-
|
|
63178
|
-
};
|
|
63341
|
+
const problem = verifyPackage(staging, artifact.files, { target: codexTarget(artifact.platform), codexVersion: manifest.codexVersion });
|
|
63342
|
+
if (problem !== null)
|
|
63343
|
+
throw new Error(`staged package does not match the release manifest: ${problem}`);
|
|
63179
63344
|
}
|
|
63180
63345
|
function probeVersion(ctx, staging, codexVersion) {
|
|
63181
|
-
const probe = ctx.run(
|
|
63346
|
+
const probe = ctx.run(join12(staging, "bin", "codex"), ["--version"], { timeoutMs: PROBE_TIMEOUT_MS });
|
|
63182
63347
|
const reported = sanitize((probe.stdout || probe.stderr).slice(0, 512));
|
|
63183
63348
|
if (probe.status !== 0 || reported !== `codex-cli ${codexVersion}`) {
|
|
63184
63349
|
throw new Error(`staged codex reported version "${reported}" instead of "codex-cli ${codexVersion}"`);
|
|
63185
63350
|
}
|
|
63186
63351
|
}
|
|
63187
63352
|
function stagedPair(ctx, staging, manifest, artifact, tag) {
|
|
63188
|
-
|
|
63353
|
+
verifyStaged(staging, manifest, artifact);
|
|
63189
63354
|
probeVersion(ctx, staging, manifest.codexVersion);
|
|
63190
63355
|
return {
|
|
63191
63356
|
directory: staging,
|
|
@@ -63194,13 +63359,14 @@ function stagedPair(ctx, staging, manifest, artifact, tag) {
|
|
|
63194
63359
|
source: "prebuilt",
|
|
63195
63360
|
cxVersion: manifest.cxVersion ?? VERSION,
|
|
63196
63361
|
platform: artifact.platform,
|
|
63362
|
+
target: codexTarget(artifact.platform),
|
|
63197
63363
|
patchVersion: manifest.patchVersion,
|
|
63198
63364
|
patchSha256: manifest.patchSha256,
|
|
63199
63365
|
upstreamCommit: manifest.upstreamCommit,
|
|
63200
63366
|
sourceCommit: manifest.sourceCommit,
|
|
63201
63367
|
sourceDirty: false,
|
|
63202
63368
|
installedAt: ctx.now().toISOString(),
|
|
63203
|
-
|
|
63369
|
+
files: artifact.files,
|
|
63204
63370
|
release: { tag, archiveSha256: artifact.sha256, manifest }
|
|
63205
63371
|
}
|
|
63206
63372
|
};
|
|
@@ -63210,7 +63376,7 @@ function moveFile(src, dst) {
|
|
|
63210
63376
|
renameSync4(src, dst);
|
|
63211
63377
|
} catch (e) {
|
|
63212
63378
|
if (typeof e === "object" && e !== null && e.code === "EXDEV") {
|
|
63213
|
-
|
|
63379
|
+
copyFileSync(src, dst);
|
|
63214
63380
|
rmSync2(src, { force: true });
|
|
63215
63381
|
} else {
|
|
63216
63382
|
throw e;
|
|
@@ -63219,9 +63385,9 @@ function moveFile(src, dst) {
|
|
|
63219
63385
|
}
|
|
63220
63386
|
async function stageArchive(ctx, download, manifest, artifact, tag, opts) {
|
|
63221
63387
|
const cacheDir = ctx.paths.downloadCacheDir;
|
|
63222
|
-
|
|
63223
|
-
const partFile =
|
|
63224
|
-
const archive =
|
|
63388
|
+
mkdirSync6(cacheDir, { recursive: true });
|
|
63389
|
+
const partFile = join12(cacheDir, `${tag}-${artifact.filename}.part`);
|
|
63390
|
+
const archive = join12(download, artifact.filename);
|
|
63225
63391
|
opts.onStatus?.("download", `Downloading prebuilt archive (${artifact.filename})...`);
|
|
63226
63392
|
const got = await downloadAsset(ctx, tag, artifact.filename, partFile, ARCHIVE_MAX_BYTES, opts);
|
|
63227
63393
|
if (got.sha256 !== artifact.sha256 || got.size !== artifact.size) {
|
|
@@ -63233,7 +63399,7 @@ async function stageArchive(ctx, download, manifest, artifact, tag, opts) {
|
|
|
63233
63399
|
const staging = privateTemp(ctx, "staging-");
|
|
63234
63400
|
try {
|
|
63235
63401
|
opts.onStatus?.("extract", "Extracting and verifying executables...");
|
|
63236
|
-
await extractArchive(archive, staging);
|
|
63402
|
+
await extractArchive(archive, staging, artifact.files);
|
|
63237
63403
|
const pair = stagedPair(ctx, staging, manifest, artifact, tag);
|
|
63238
63404
|
opts.onStatus?.("extract-done", "Verified executables (codex, codex-code-mode-host)");
|
|
63239
63405
|
return pair;
|
|
@@ -63247,9 +63413,9 @@ async function preparePrebuilt(ctx, expected, opts = {}) {
|
|
|
63247
63413
|
opts.onStatus?.("manifest", `Checking release ${tag} for ${expected.platform}...`);
|
|
63248
63414
|
const download = privateTemp(ctx, "download-");
|
|
63249
63415
|
try {
|
|
63250
|
-
const manifestFile =
|
|
63416
|
+
const manifestFile = join12(download, MANIFEST_ASSET);
|
|
63251
63417
|
await downloadAsset(ctx, tag, MANIFEST_ASSET, manifestFile, MANIFEST_MAX_BYTES, opts);
|
|
63252
|
-
const manifest = validateManifest(JSON.parse(
|
|
63418
|
+
const manifest = validateManifest(JSON.parse(readFileSync7(manifestFile, "utf8")), expected);
|
|
63253
63419
|
const artifact = artifactFor(manifest, expected);
|
|
63254
63420
|
opts.onStatus?.("manifest-done", `Found release for Codex ${manifest.codexVersion} (${artifact.platform})`);
|
|
63255
63421
|
const unchanged = unchangedPair(ctx, manifest, artifact, tag);
|
|
@@ -63316,6 +63482,28 @@ var PLATFORMS = [
|
|
|
63316
63482
|
"linux-arm64"
|
|
63317
63483
|
];
|
|
63318
63484
|
var ARCHIVE_PREFIX = "cxstatusline-codex";
|
|
63485
|
+
function codexTarget(platform2) {
|
|
63486
|
+
switch (platform2) {
|
|
63487
|
+
case "darwin-arm64":
|
|
63488
|
+
return "aarch64-apple-darwin";
|
|
63489
|
+
case "darwin-x64":
|
|
63490
|
+
return "x86_64-apple-darwin";
|
|
63491
|
+
case "linux-x64":
|
|
63492
|
+
return "x86_64-unknown-linux-gnu";
|
|
63493
|
+
case "linux-arm64":
|
|
63494
|
+
return "aarch64-unknown-linux-gnu";
|
|
63495
|
+
}
|
|
63496
|
+
}
|
|
63497
|
+
var PACKAGE_PATH = /^(bin|codex-path|codex-resources)(\/[A-Za-z0-9][A-Za-z0-9._+-]*){1,4}$/;
|
|
63498
|
+
var PACKAGE_ROOT_FILES = ["codex-package.json", "LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.md"];
|
|
63499
|
+
var PACKAGE_MAX_FILES = 64;
|
|
63500
|
+
function packageRequiredFiles(platform2) {
|
|
63501
|
+
const base2 = ["codex-package.json", "bin/codex", "bin/codex-code-mode-host", "codex-path/rg", "LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.md"];
|
|
63502
|
+
return platform2.startsWith("linux-") ? [...base2, "codex-resources/bwrap"] : base2;
|
|
63503
|
+
}
|
|
63504
|
+
function modeFor(path) {
|
|
63505
|
+
return /^(bin|codex-path|codex-resources)\//.test(path) ? 493 : 420;
|
|
63506
|
+
}
|
|
63319
63507
|
var HEX402 = /^[0-9a-f]{40}$/;
|
|
63320
63508
|
var HEX642 = /^[0-9a-f]{64}$/;
|
|
63321
63509
|
var ISO_8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
|
|
@@ -63347,8 +63535,7 @@ var FileDigestSchema = exports_external.object({
|
|
|
63347
63535
|
sha256: exports_external.string().regex(HEX642, "sha256 must be 64 lowercase hex chars"),
|
|
63348
63536
|
size: exports_external.number().refine(safePositiveInt, "size must be a finite positive safe integer")
|
|
63349
63537
|
}).strict();
|
|
63350
|
-
var
|
|
63351
|
-
var FilesSchema = exports_external.object(filesShape).strict();
|
|
63538
|
+
var FilesSchema = exports_external.record(exports_external.string(), FileDigestSchema);
|
|
63352
63539
|
var ArtifactSchema = exports_external.object({
|
|
63353
63540
|
platform: exports_external.enum(["darwin-arm64", "darwin-x64", "linux-x64", "linux-arm64"]),
|
|
63354
63541
|
filename: exports_external.string(),
|
|
@@ -63357,8 +63544,8 @@ var ArtifactSchema = exports_external.object({
|
|
|
63357
63544
|
files: FilesSchema
|
|
63358
63545
|
}).strict();
|
|
63359
63546
|
var ManifestShapeSchema = exports_external.object({
|
|
63360
|
-
schema: exports_external.
|
|
63361
|
-
patchVersion: exports_external.number().refine(safePositiveInt)
|
|
63547
|
+
schema: exports_external.literal(3),
|
|
63548
|
+
patchVersion: exports_external.number().refine(safePositiveInt),
|
|
63362
63549
|
cxVersion: exports_external.string().optional(),
|
|
63363
63550
|
codexVersion: exports_external.string(),
|
|
63364
63551
|
upstreamTag: exports_external.string(),
|
|
@@ -63370,12 +63557,38 @@ var ManifestShapeSchema = exports_external.object({
|
|
|
63370
63557
|
createdAt: exports_external.string().regex(ISO_8601, "createdAt must be an ISO 8601 timestamp"),
|
|
63371
63558
|
artifacts: exports_external.array(ArtifactSchema).min(1).max(4)
|
|
63372
63559
|
}).strict();
|
|
63560
|
+
function checkPackageFiles(platform2, files) {
|
|
63561
|
+
const keys2 = Object.keys(files);
|
|
63562
|
+
if (keys2.length > PACKAGE_MAX_FILES)
|
|
63563
|
+
return `files lists more than ${PACKAGE_MAX_FILES} members`;
|
|
63564
|
+
for (const key of keys2) {
|
|
63565
|
+
if (!PACKAGE_PATH.test(key) && !PACKAGE_ROOT_FILES.includes(key))
|
|
63566
|
+
return `files has unexpected member ${key}`;
|
|
63567
|
+
}
|
|
63568
|
+
for (const name of packageRequiredFiles(platform2))
|
|
63569
|
+
if (!(name in files))
|
|
63570
|
+
return `files is missing ${name}`;
|
|
63571
|
+
const lower = new Set;
|
|
63572
|
+
for (const key of keys2) {
|
|
63573
|
+
const folded = key.toLowerCase();
|
|
63574
|
+
if (lower.has(folded))
|
|
63575
|
+
return `files has members that differ only by case: ${key}`;
|
|
63576
|
+
lower.add(folded);
|
|
63577
|
+
for (const other of keys2)
|
|
63578
|
+
if (other !== key && other.startsWith(`${key}/`))
|
|
63579
|
+
return `files member ${key} is also a directory of ${other}`;
|
|
63580
|
+
}
|
|
63581
|
+
return null;
|
|
63582
|
+
}
|
|
63373
63583
|
function checkArtifacts(m2, expected) {
|
|
63374
63584
|
const seen = new Set;
|
|
63375
63585
|
for (const artifact of m2.artifacts) {
|
|
63376
63586
|
if (seen.has(artifact.platform))
|
|
63377
63587
|
return "duplicate platform in artifacts";
|
|
63378
63588
|
seen.add(artifact.platform);
|
|
63589
|
+
const files = checkPackageFiles(artifact.platform, artifact.files);
|
|
63590
|
+
if (files)
|
|
63591
|
+
return files;
|
|
63379
63592
|
if (artifact.filename.includes("/") || artifact.filename.includes("\\") || artifact.filename.includes("..")) {
|
|
63380
63593
|
return "artifact filename contains illegal path characters";
|
|
63381
63594
|
}
|
|
@@ -63388,10 +63601,6 @@ function checkArtifacts(m2, expected) {
|
|
|
63388
63601
|
return null;
|
|
63389
63602
|
}
|
|
63390
63603
|
function checkBusinessRules(m2, expected) {
|
|
63391
|
-
if (m2.schema === 2 && m2.patchVersion === undefined)
|
|
63392
|
-
return "patchVersion is required for schema 2";
|
|
63393
|
-
if (m2.schema === 1 && m2.patchVersion !== undefined)
|
|
63394
|
-
return "patchVersion requires schema 2";
|
|
63395
63604
|
if (m2.cxVersion !== undefined && !isStableVersion(m2.cxVersion)) {
|
|
63396
63605
|
return "cxVersion is not a valid semver";
|
|
63397
63606
|
}
|
|
@@ -63400,10 +63609,8 @@ function checkBusinessRules(m2, expected) {
|
|
|
63400
63609
|
}
|
|
63401
63610
|
if (m2.upstreamTag !== `rust-v${m2.codexVersion}`)
|
|
63402
63611
|
return "upstreamTag does not match codexVersion";
|
|
63403
|
-
if (
|
|
63612
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*\.patch$/.test(m2.patchFile))
|
|
63404
63613
|
return "patchFile must be a patch basename";
|
|
63405
|
-
if (m2.schema === 1 && m2.patchFile !== `codex-${m2.codexVersion}.patch`)
|
|
63406
|
-
return "patchFile does not match codexVersion";
|
|
63407
63614
|
if (Number.isNaN(Date.parse(m2.createdAt)))
|
|
63408
63615
|
return "createdAt is not a valid timestamp";
|
|
63409
63616
|
return checkArtifacts(m2, expected);
|
|
@@ -63418,6 +63625,13 @@ function validateManifest(raw, expected) {
|
|
|
63418
63625
|
if (!PLATFORMS.includes(expected.platform)) {
|
|
63419
63626
|
throw new Error("validateManifest: expected release platform is not supported");
|
|
63420
63627
|
}
|
|
63628
|
+
const rawSchema = typeof raw === "object" && raw !== null ? raw.schema : undefined;
|
|
63629
|
+
if (typeof rawSchema === "number" && rawSchema > 3) {
|
|
63630
|
+
throw new Error(`this release needs a newer cxstatusline (manifest schema ${rawSchema}); run npm i -g cxstatusline`);
|
|
63631
|
+
}
|
|
63632
|
+
if (typeof rawSchema === "number" && rawSchema < 3) {
|
|
63633
|
+
throw new Error(`release ${releaseTag(expected.codexVersion)} predates cxstatusline 0.11 and has not been republished yet; use --compile or wait`);
|
|
63634
|
+
}
|
|
63421
63635
|
const structural = ManifestShapeSchema.safeParse(raw);
|
|
63422
63636
|
if (!structural.success) {
|
|
63423
63637
|
const issue2 = structural.error.issues[0];
|
|
@@ -63431,7 +63645,7 @@ function validateManifest(raw, expected) {
|
|
|
63431
63645
|
}
|
|
63432
63646
|
|
|
63433
63647
|
// src/hook/install.ts
|
|
63434
|
-
import { existsSync as existsSync7, readFileSync as
|
|
63648
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "node:fs";
|
|
63435
63649
|
|
|
63436
63650
|
// src/sh.ts
|
|
63437
63651
|
var sq = (s3) => `'${s3.replace(/'/g, `'"'"'`)}'`;
|
|
@@ -63469,7 +63683,7 @@ function readHooksFile(path) {
|
|
|
63469
63683
|
return null;
|
|
63470
63684
|
let raw;
|
|
63471
63685
|
try {
|
|
63472
|
-
raw = JSON.parse(
|
|
63686
|
+
raw = JSON.parse(readFileSync8(path, "utf8"));
|
|
63473
63687
|
} catch {
|
|
63474
63688
|
throw new Error(`${path}: hooks.json is not valid JSON; fix it by hand before installing the hook`);
|
|
63475
63689
|
}
|
|
@@ -63501,7 +63715,7 @@ function uninstallHook(hooksFile) {
|
|
|
63501
63715
|
}
|
|
63502
63716
|
|
|
63503
63717
|
// src/state.ts
|
|
63504
|
-
import { existsSync as existsSync8, readFileSync as
|
|
63718
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
|
|
63505
63719
|
var RELEASE_UNAVAILABLE = "release-unavailable";
|
|
63506
63720
|
var RELEASE_RETRY_AFTER_MS = 24 * 60 * 60 * 1000;
|
|
63507
63721
|
var DEFAULT_STATE = {
|
|
@@ -63549,7 +63763,7 @@ function readValidated(file2) {
|
|
|
63549
63763
|
if (!existsSync8(file2))
|
|
63550
63764
|
return null;
|
|
63551
63765
|
try {
|
|
63552
|
-
return validate3(JSON.parse(
|
|
63766
|
+
return validate3(JSON.parse(readFileSync9(file2, "utf8")));
|
|
63553
63767
|
} catch {
|
|
63554
63768
|
return null;
|
|
63555
63769
|
}
|
|
@@ -63800,8 +64014,8 @@ function promptUpdate(options) {
|
|
|
63800
64014
|
import { rmSync as rmSync5 } from "node:fs";
|
|
63801
64015
|
|
|
63802
64016
|
// src/codex/upstream.ts
|
|
63803
|
-
import { accessSync as accessSync2, constants as constants3, lstatSync as
|
|
63804
|
-
import { dirname as
|
|
64017
|
+
import { accessSync as accessSync2, constants as constants3, lstatSync as lstatSync4, readlinkSync as readlinkSync2, realpathSync as realpathSync3, statSync as statSync2 } from "node:fs";
|
|
64018
|
+
import { dirname as dirname9, isAbsolute as isAbsolute2, join as join13, resolve as resolve3 } from "node:path";
|
|
63805
64019
|
function isExecutable2(p2) {
|
|
63806
64020
|
try {
|
|
63807
64021
|
accessSync2(p2, constants3.X_OK);
|
|
@@ -63822,13 +64036,13 @@ function isManaged(p2, paths, isOurWrapper) {
|
|
|
63822
64036
|
function inspectLauncher(paths, isOurWrapper) {
|
|
63823
64037
|
let st2;
|
|
63824
64038
|
try {
|
|
63825
|
-
st2 =
|
|
64039
|
+
st2 = lstatSync4(paths.wrapperPath);
|
|
63826
64040
|
} catch {
|
|
63827
64041
|
return null;
|
|
63828
64042
|
}
|
|
63829
64043
|
if (st2.isSymbolicLink()) {
|
|
63830
64044
|
const raw = readlinkSync2(paths.wrapperPath);
|
|
63831
|
-
const target = isAbsolute2(raw) ? raw : resolve3(
|
|
64045
|
+
const target = isAbsolute2(raw) ? raw : resolve3(dirname9(paths.wrapperPath), raw);
|
|
63832
64046
|
if (isManaged(target, paths, isOurWrapper))
|
|
63833
64047
|
return null;
|
|
63834
64048
|
return { kind: "found", bin: target, launcher_restore: { kind: "symlink", target } };
|
|
@@ -63841,7 +64055,7 @@ function walkPath(paths, env3, isOurWrapper) {
|
|
|
63841
64055
|
for (const dir of (env3.PATH ?? "").split(":").filter(Boolean)) {
|
|
63842
64056
|
if (resolve3(dir) === resolve3(paths.binDir))
|
|
63843
64057
|
continue;
|
|
63844
|
-
const candidate =
|
|
64058
|
+
const candidate = join13(dir, "codex");
|
|
63845
64059
|
if (isExecutable2(candidate) && !isManaged(candidate, paths, isOurWrapper))
|
|
63846
64060
|
return candidate;
|
|
63847
64061
|
}
|
|
@@ -63876,17 +64090,16 @@ function preserveLauncherRestore(recorded, found) {
|
|
|
63876
64090
|
}
|
|
63877
64091
|
|
|
63878
64092
|
// src/patch/compile.ts
|
|
63879
|
-
import { chmodSync as chmodSync3,
|
|
63880
|
-
import {
|
|
63881
|
-
import { join as join15 } from "node:path";
|
|
64093
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
64094
|
+
import { join as join16 } from "node:path";
|
|
63882
64095
|
|
|
63883
64096
|
// src/patch/build.ts
|
|
63884
|
-
import { existsSync as existsSync10, lstatSync as
|
|
63885
|
-
import { join as
|
|
64097
|
+
import { existsSync as existsSync10, lstatSync as lstatSync5, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
|
|
64098
|
+
import { join as join15 } from "node:path";
|
|
63886
64099
|
|
|
63887
64100
|
// src/patch/v8.ts
|
|
63888
64101
|
import { existsSync as existsSync9 } from "node:fs";
|
|
63889
|
-
import { join as
|
|
64102
|
+
import { join as join14 } from "node:path";
|
|
63890
64103
|
function defaultV8Target() {
|
|
63891
64104
|
const isArm = process.arch === "arm64";
|
|
63892
64105
|
if (process.platform === "darwin")
|
|
@@ -63917,7 +64130,7 @@ function resolveV8Env(sourceDir, run, log) {
|
|
|
63917
64130
|
RUSTY_V8_SRC_BINDING_PATH: process.env.RUSTY_V8_SRC_BINDING_PATH
|
|
63918
64131
|
};
|
|
63919
64132
|
}
|
|
63920
|
-
const v8Script =
|
|
64133
|
+
const v8Script = join14(sourceDir, "scripts", "codex_package", "v8.py");
|
|
63921
64134
|
if (!existsSync9(v8Script)) {
|
|
63922
64135
|
return {};
|
|
63923
64136
|
}
|
|
@@ -63989,14 +64202,14 @@ function headCommit(plan, run) {
|
|
|
63989
64202
|
}
|
|
63990
64203
|
function prepareCheckout(plan, run, log) {
|
|
63991
64204
|
const git = (step, ...args) => must(step, run, log, "git", ["-C", plan.sourceDir, ...args]);
|
|
63992
|
-
if (existsSync10(
|
|
64205
|
+
if (existsSync10(join15(plan.sourceDir, ".git"))) {
|
|
63993
64206
|
git("fetch", "fetch", "--tags", "--filter=blob:none", "origin");
|
|
63994
|
-
const snapshot =
|
|
63995
|
-
const st2 =
|
|
64207
|
+
const snapshot = join15(plan.sourceDir, SNAPSHOT);
|
|
64208
|
+
const st2 = lstatSync5(snapshot, { throwIfNoEntry: false });
|
|
63996
64209
|
if (st2) {
|
|
63997
64210
|
const tracked = run("git", ["-C", plan.sourceDir, "ls-files", "--error-unmatch", "--", SNAPSHOT]);
|
|
63998
64211
|
if (tracked.status !== 0) {
|
|
63999
|
-
if (!st2.isFile() ||
|
|
64212
|
+
if (!st2.isFile() || readFileSync10(snapshot, "utf8") !== SNAPSHOT_CONTENT) {
|
|
64000
64213
|
throw new BuildError("snapshot", `conflicting untracked snapshot ${snapshot}; move it aside before retrying`);
|
|
64001
64214
|
}
|
|
64002
64215
|
git("stage snapshot", "add", "--", SNAPSHOT);
|
|
@@ -64019,7 +64232,7 @@ function buildPatched(plan, run, log, which, onStatus) {
|
|
|
64019
64232
|
git("apply --check", "apply", "--index", "--check", plan.patchFile);
|
|
64020
64233
|
git("apply", "apply", "--index", plan.patchFile);
|
|
64021
64234
|
onStatus?.("patch-done", `Applied ${patchBase} cleanly`);
|
|
64022
|
-
const crateDir =
|
|
64235
|
+
const crateDir = join15(plan.sourceDir, "codex-rs");
|
|
64023
64236
|
const v8Env = resolveV8Env(plan.sourceDir, run, log);
|
|
64024
64237
|
onStatus?.("build", "Compiling release binaries (cargo build --release)... Note: this full compile typically takes 10 to 20 minutes.");
|
|
64025
64238
|
const buildStart = Date.now();
|
|
@@ -64028,7 +64241,7 @@ function buildPatched(plan, run, log, which, onStatus) {
|
|
|
64028
64241
|
const buildElapsedStr = buildElapsed >= 60 ? `${Math.floor(buildElapsed / 60)}m ${buildElapsed % 60}s` : `${buildElapsed}s`;
|
|
64029
64242
|
onStatus?.("build-done", `Release binaries compiled (codex, codex-code-mode-host in ${buildElapsedStr})`);
|
|
64030
64243
|
const [codex, codexCodeModeHost] = TARGETS.map((name) => {
|
|
64031
|
-
const bin =
|
|
64244
|
+
const bin = join15(crateDir, "target", "release", name);
|
|
64032
64245
|
if (!existsSync10(bin) || statSync3(bin).size === 0) {
|
|
64033
64246
|
throw new BuildError("cargo build", `cargo exited 0 but ${bin} is missing or empty`);
|
|
64034
64247
|
}
|
|
@@ -64045,9 +64258,6 @@ function buildPatched(plan, run, log, which, onStatus) {
|
|
|
64045
64258
|
|
|
64046
64259
|
// src/patch/compile.ts
|
|
64047
64260
|
var STAGING_PREFIX = "compiled-";
|
|
64048
|
-
function digestOf3(file2) {
|
|
64049
|
-
return { sha256: createHash5("sha256").update(readFileSync10(file2)).digest("hex"), size: statSync4(file2).size };
|
|
64050
|
-
}
|
|
64051
64261
|
function platformLabel() {
|
|
64052
64262
|
try {
|
|
64053
64263
|
return platformFor(process.platform, process.arch);
|
|
@@ -64055,62 +64265,68 @@ function platformLabel() {
|
|
|
64055
64265
|
return `${process.platform}-${process.arch}`;
|
|
64056
64266
|
}
|
|
64057
64267
|
}
|
|
64058
|
-
function
|
|
64059
|
-
|
|
64060
|
-
const
|
|
64268
|
+
function prepareCompiled(ctx, upstream, ref, onStatus) {
|
|
64269
|
+
const patchFile = join16(ctx.patchesDir, ref.file);
|
|
64270
|
+
const patchSha256 = digestOf(patchFile).sha256;
|
|
64271
|
+
const built = buildPatched({ tag: ref.tag, sourceDir: ctx.paths.sourceDir, patchFile }, ctx.run, ctx.log, ctx.which, onStatus);
|
|
64272
|
+
onStatus?.("stage", "Assembling the Codex package with upstream's packager...");
|
|
64273
|
+
const python = findPython(ctx.which, ctx.run);
|
|
64274
|
+
if (python === null)
|
|
64275
|
+
throw new Error("Python >= 3.10 is required to assemble the Codex package (brew install python / apt install python3)");
|
|
64276
|
+
const cargo = ctx.which("cargo");
|
|
64277
|
+
if (cargo === null)
|
|
64278
|
+
throw new Error("cargo is not on PATH");
|
|
64279
|
+
mkdirSync7(ctx.paths.libexecDir, { recursive: true });
|
|
64280
|
+
const directory = mkdtempSync2(join16(ctx.paths.libexecDir, STAGING_PREFIX));
|
|
64061
64281
|
chmodSync3(directory, 448);
|
|
64062
|
-
const
|
|
64063
|
-
|
|
64064
|
-
|
|
64065
|
-
};
|
|
64066
|
-
const executables = {};
|
|
64282
|
+
const tmpDir = mkdtempSync2(join16(ctx.paths.libexecDir, "download-"));
|
|
64283
|
+
chmodSync3(tmpDir, 448);
|
|
64284
|
+
let target;
|
|
64067
64285
|
try {
|
|
64068
|
-
|
|
64069
|
-
|
|
64070
|
-
|
|
64071
|
-
|
|
64072
|
-
|
|
64073
|
-
|
|
64286
|
+
target = rustcHostTarget(ctx.run);
|
|
64287
|
+
assemblePackage({
|
|
64288
|
+
upstream: ctx.paths.sourceDir,
|
|
64289
|
+
target,
|
|
64290
|
+
codexVersion: upstream.raw,
|
|
64291
|
+
codex: built.codex,
|
|
64292
|
+
codeModeHost: built.codexCodeModeHost,
|
|
64293
|
+
packageDir: directory,
|
|
64294
|
+
python,
|
|
64295
|
+
cargo,
|
|
64296
|
+
bwrapBin: process.platform === "linux" ? ctx.which("bwrap") : null,
|
|
64297
|
+
tmpDir,
|
|
64298
|
+
force: false
|
|
64299
|
+
}, ctx.run, ctx.log);
|
|
64074
64300
|
} catch (e) {
|
|
64075
64301
|
rmSync3(directory, { recursive: true, force: true });
|
|
64076
64302
|
throw e;
|
|
64303
|
+
} finally {
|
|
64304
|
+
rmSync3(tmpDir, { recursive: true, force: true });
|
|
64077
64305
|
}
|
|
64306
|
+
const files = packageFiles(directory);
|
|
64307
|
+
onStatus?.("stage-done", "Codex package assembled and verified");
|
|
64078
64308
|
return {
|
|
64079
64309
|
directory,
|
|
64080
|
-
executables: {
|
|
64081
|
-
codex: executables.codex,
|
|
64082
|
-
"codex-code-mode-host": executables["codex-code-mode-host"]
|
|
64083
|
-
}
|
|
64084
|
-
};
|
|
64085
|
-
}
|
|
64086
|
-
function prepareCompiled(ctx, upstream, ref, onStatus) {
|
|
64087
|
-
const patchFile = join15(ctx.patchesDir, ref.file);
|
|
64088
|
-
const patchSha256 = digestOf3(patchFile).sha256;
|
|
64089
|
-
const built = buildPatched({ tag: ref.tag, sourceDir: ctx.paths.sourceDir, patchFile }, ctx.run, ctx.log, ctx.which, onStatus);
|
|
64090
|
-
onStatus?.("stage", "Staging generation and verifying binaries...");
|
|
64091
|
-
const staged = stage(ctx, built);
|
|
64092
|
-
onStatus?.("stage-done", "Generation staged and binaries verified");
|
|
64093
|
-
return {
|
|
64094
|
-
directory: staged.directory,
|
|
64095
64310
|
codexVersion: upstream.raw,
|
|
64096
64311
|
provenance: {
|
|
64097
64312
|
source: "compiled",
|
|
64098
64313
|
cxVersion: VERSION,
|
|
64099
64314
|
platform: platformLabel(),
|
|
64315
|
+
target,
|
|
64100
64316
|
patchVersion: ref.patchVersion,
|
|
64101
64317
|
patchSha256,
|
|
64102
64318
|
upstreamCommit: built.upstreamCommit,
|
|
64103
64319
|
sourceCommit: SOURCE_COMMIT,
|
|
64104
64320
|
sourceDirty: SOURCE_DIRTY,
|
|
64105
64321
|
installedAt: ctx.now().toISOString(),
|
|
64106
|
-
|
|
64322
|
+
files
|
|
64107
64323
|
}
|
|
64108
64324
|
};
|
|
64109
64325
|
}
|
|
64110
64326
|
|
|
64111
64327
|
// src/patch/manifest.ts
|
|
64112
64328
|
import { readFileSync as readFileSync11 } from "node:fs";
|
|
64113
|
-
import { join as
|
|
64329
|
+
import { join as join17 } from "node:path";
|
|
64114
64330
|
class ManifestError extends Error {
|
|
64115
64331
|
name = "ManifestError";
|
|
64116
64332
|
}
|
|
@@ -64129,7 +64345,7 @@ var isCandidate = (c) => {
|
|
|
64129
64345
|
return parsed !== null && parsed.pre === null;
|
|
64130
64346
|
};
|
|
64131
64347
|
function loadManifest(patchesDir) {
|
|
64132
|
-
const file2 =
|
|
64348
|
+
const file2 = join17(patchesDir, "manifest.json");
|
|
64133
64349
|
try {
|
|
64134
64350
|
const raw = JSON.parse(readFileSync11(file2, "utf8"));
|
|
64135
64351
|
const m2 = raw;
|
|
@@ -64190,9 +64406,9 @@ function isCodexVersionSupported(m2, version2) {
|
|
|
64190
64406
|
}
|
|
64191
64407
|
|
|
64192
64408
|
// src/patch/wrapper.ts
|
|
64193
|
-
import { chmodSync as chmodSync4, closeSync as closeSync2, existsSync as existsSync11, lstatSync as
|
|
64409
|
+
import { chmodSync as chmodSync4, closeSync as closeSync2, existsSync as existsSync11, lstatSync as lstatSync6, mkdirSync as mkdirSync8, openSync as openSync2, readFileSync as readFileSync12, readSync, renameSync as renameSync5, rmSync as rmSync4, statSync as statSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
64194
64410
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
64195
|
-
import { join as
|
|
64411
|
+
import { join as join18 } from "node:path";
|
|
64196
64412
|
var WRAPPER_MARKER = "# cxstatusline-wrapper v1";
|
|
64197
64413
|
var WRAPPER_MARKER_V2 = "# cxstatusline-wrapper v2";
|
|
64198
64414
|
var WRAPPER_MARKERS = [WRAPPER_MARKER, WRAPPER_MARKER_V2];
|
|
@@ -64222,6 +64438,9 @@ function generationWrapperScript(currentGeneration, cxBin) {
|
|
|
64222
64438
|
`CXSTATUSLINE_COMMAND=${sq(`${sq(cxBin)} render`)}`,
|
|
64223
64439
|
"export CXSTATUSLINE_COMMAND",
|
|
64224
64440
|
`generation=$(CDPATH= cd -P -- ${sq(currentGeneration)} && pwd -P) || exit 1`,
|
|
64441
|
+
`if [ -x "$generation/bin/codex" ]; then`,
|
|
64442
|
+
` exec "$generation/bin/codex" "$@"`,
|
|
64443
|
+
"fi",
|
|
64225
64444
|
`exec "$generation/codex" "$@"`,
|
|
64226
64445
|
""
|
|
64227
64446
|
].join(`
|
|
@@ -64245,18 +64464,18 @@ function isOurWrapper(path) {
|
|
|
64245
64464
|
}
|
|
64246
64465
|
function isSymlink(p2) {
|
|
64247
64466
|
try {
|
|
64248
|
-
return
|
|
64467
|
+
return lstatSync6(p2).isSymbolicLink();
|
|
64249
64468
|
} catch {
|
|
64250
64469
|
return false;
|
|
64251
64470
|
}
|
|
64252
64471
|
}
|
|
64253
64472
|
function stageExecutable(target, write) {
|
|
64254
|
-
|
|
64473
|
+
mkdirSync8(join18(target, ".."), { recursive: true });
|
|
64255
64474
|
const tmp = `${target}.tmp-${process.pid}`;
|
|
64256
64475
|
try {
|
|
64257
64476
|
write(tmp);
|
|
64258
64477
|
chmodSync4(tmp, 493);
|
|
64259
|
-
if (
|
|
64478
|
+
if (statSync4(tmp).size === 0)
|
|
64260
64479
|
throw new Error(`${target} staged as an empty file`);
|
|
64261
64480
|
return tmp;
|
|
64262
64481
|
} catch (e) {
|
|
@@ -64310,7 +64529,7 @@ function preserveStockLauncher(ctx) {
|
|
|
64310
64529
|
}
|
|
64311
64530
|
function stageWrapper(paths, cxBin) {
|
|
64312
64531
|
const want = generationWrapperScript(paths.currentGeneration, cxBin);
|
|
64313
|
-
|
|
64532
|
+
mkdirSync8(paths.binDir, { recursive: true });
|
|
64314
64533
|
const tmp = `${paths.wrapperPath}.tmp-${process.pid}-${randomBytes3(4).toString("hex")}`;
|
|
64315
64534
|
try {
|
|
64316
64535
|
writeFileSync3(tmp, want);
|
|
@@ -65006,11 +65225,37 @@ async function runUpdate(ctx, opts = {}, transport = {}) {
|
|
|
65006
65225
|
}
|
|
65007
65226
|
const installed = readInstallation(ctx.paths)?.codexVersion ?? loadState(ctx).patched_from;
|
|
65008
65227
|
const current = installed ? parseSemver(installed) : null;
|
|
65009
|
-
|
|
65228
|
+
const targetSemver = parseSemver(target);
|
|
65229
|
+
if (current && compareSemver(current, targetSemver) > 0) {
|
|
65010
65230
|
ctx.say(`Installed Codex ${installed} is newer than the latest supported ${opts.compile ? "patch" : "prebuilt"} (${target}); leaving it unchanged.`);
|
|
65011
65231
|
return 0;
|
|
65012
65232
|
}
|
|
65013
|
-
if (
|
|
65233
|
+
if (current && compareSemver(current, targetSemver) === 0 && !opts.force) {
|
|
65234
|
+
const record2 = readInstallation(ctx.paths);
|
|
65235
|
+
if (!opts.compile && record2 && record2.provenance.source === "prebuilt") {
|
|
65236
|
+
try {
|
|
65237
|
+
const expected = {
|
|
65238
|
+
codexVersion: target,
|
|
65239
|
+
platform: platformFor(process.platform, process.arch)
|
|
65240
|
+
};
|
|
65241
|
+
const prepared = await preparePrebuilt(ctx, expected, transport);
|
|
65242
|
+
if (prepared.kind === "unchanged") {
|
|
65243
|
+
ctx.say(`Codex is already up to date (${installed}).`);
|
|
65244
|
+
return 0;
|
|
65245
|
+
}
|
|
65246
|
+
rmSync6(prepared.pair.directory, { recursive: true, force: true });
|
|
65247
|
+
} catch {}
|
|
65248
|
+
} else if (opts.compile && record2 && record2.provenance.source === "compiled") {
|
|
65249
|
+
const patchRef = resolvePatch(manifest, targetSemver);
|
|
65250
|
+
const currentPatch = record2.provenance.patchVersion ?? 1;
|
|
65251
|
+
const targetPatch = patchRef?.patchVersion ?? 1;
|
|
65252
|
+
if (currentPatch >= targetPatch) {
|
|
65253
|
+
ctx.say(`Codex is already up to date (${installed}).`);
|
|
65254
|
+
return 0;
|
|
65255
|
+
}
|
|
65256
|
+
}
|
|
65257
|
+
}
|
|
65258
|
+
if (opts.isTTY && !opts.force && !opts.compile && (!current || compareSemver(current, targetSemver) < 0)) {
|
|
65014
65259
|
const action = await (opts.promptUpdate ?? promptUpdate)({ latest: target, highestAvailable: target });
|
|
65015
65260
|
if (action === "cancel") {
|
|
65016
65261
|
ctx.say("Update cancelled.");
|
|
@@ -65022,7 +65267,7 @@ async function runUpdate(ctx, opts = {}, transport = {}) {
|
|
|
65022
65267
|
return runInstall(ctx, { compile: opts.compile ?? false, codexVersion: target }, transport);
|
|
65023
65268
|
}
|
|
65024
65269
|
function appendLog(file2, line) {
|
|
65025
|
-
|
|
65270
|
+
mkdirSync9(join19(file2, ".."), { recursive: true });
|
|
65026
65271
|
appendFileSync(file2, `${new Date().toISOString()} ${line}
|
|
65027
65272
|
`);
|
|
65028
65273
|
}
|
|
@@ -65177,9 +65422,9 @@ async function promptCodexVersion(options) {
|
|
|
65177
65422
|
}
|
|
65178
65423
|
|
|
65179
65424
|
// src/hook/run.ts
|
|
65180
|
-
import { appendFileSync as appendFileSync2, closeSync as closeSync3, existsSync as existsSync12, mkdirSync as
|
|
65425
|
+
import { appendFileSync as appendFileSync2, closeSync as closeSync3, existsSync as existsSync12, mkdirSync as mkdirSync10, openSync as openSync3 } from "node:fs";
|
|
65181
65426
|
import { spawn as spawn2 } from "node:child_process";
|
|
65182
|
-
import { dirname as
|
|
65427
|
+
import { dirname as dirname10 } from "node:path";
|
|
65183
65428
|
var HOOK_SOURCES = ["startup", "resume", "clear"];
|
|
65184
65429
|
function parseHookInput(stdin) {
|
|
65185
65430
|
try {
|
|
@@ -65272,7 +65517,9 @@ async function runHook(ctx, stdin, deps) {
|
|
|
65272
65517
|
if (effectiveInstalled === null)
|
|
65273
65518
|
return done();
|
|
65274
65519
|
const patched = parseSemver(effectiveInstalled);
|
|
65275
|
-
const
|
|
65520
|
+
const active = activeGeneration(ctx.paths);
|
|
65521
|
+
const flat = active !== null && !isPackageLayout(active);
|
|
65522
|
+
const drift = needsRepatch(upstream, patched, state.policy) || flat;
|
|
65276
65523
|
if (!drift)
|
|
65277
65524
|
maintainWrapper(ctx, messages);
|
|
65278
65525
|
if (drift) {
|
|
@@ -65297,7 +65544,7 @@ async function runHook(ctx, stdin, deps) {
|
|
|
65297
65544
|
return done();
|
|
65298
65545
|
if (drift) {
|
|
65299
65546
|
deps.spawnDetached(ctx.cxBin, ["hook", "acquire"], ctx.paths.patchLog);
|
|
65300
|
-
messages.push(`cxstatusline: Codex updated to ${upstream.raw} (installed pair is from ${effectiveInstalled}). Installing the new pair in the background - reopen Codex in a few minutes. Log: ${ctx.paths.patchLog}`);
|
|
65547
|
+
messages.push(flat && !needsRepatch(upstream, patched, state.policy) ? `cxstatusline: this Codex was installed by an older cxstatusline; rebuilding it in the background - reopen Codex in a few minutes. Log: ${ctx.paths.patchLog}` : `cxstatusline: Codex updated to ${upstream.raw} (installed pair is from ${effectiveInstalled}). Installing the new pair in the background - reopen Codex in a few minutes. Log: ${ctx.paths.patchLog}`);
|
|
65301
65548
|
}
|
|
65302
65549
|
return done();
|
|
65303
65550
|
}
|
|
@@ -65306,7 +65553,7 @@ function realHookDeps() {
|
|
|
65306
65553
|
spawnDetached(cxBin, args, logFile) {
|
|
65307
65554
|
let fd;
|
|
65308
65555
|
try {
|
|
65309
|
-
|
|
65556
|
+
mkdirSync10(dirname10(logFile), { recursive: true });
|
|
65310
65557
|
fd = openSync3(logFile, "a");
|
|
65311
65558
|
const child = spawn2(cxBin, args, { detached: true, stdio: ["ignore", fd, fd], env: process.env });
|
|
65312
65559
|
child.on("error", (err) => {
|
|
@@ -65329,8 +65576,8 @@ function realHookDeps() {
|
|
|
65329
65576
|
}
|
|
65330
65577
|
|
|
65331
65578
|
// src/commands/doctor.ts
|
|
65332
|
-
import { existsSync as existsSync14, lstatSync as
|
|
65333
|
-
import { join as
|
|
65579
|
+
import { existsSync as existsSync14, lstatSync as lstatSync7, readFileSync as readFileSync14, readlinkSync as readlinkSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
65580
|
+
import { join as join21 } from "node:path";
|
|
65334
65581
|
|
|
65335
65582
|
// src/utils/format.ts
|
|
65336
65583
|
function formatDuration2(ms2) {
|
|
@@ -65346,18 +65593,17 @@ function formatDuration2(ms2) {
|
|
|
65346
65593
|
}
|
|
65347
65594
|
|
|
65348
65595
|
// src/commands/doctor-generation.ts
|
|
65349
|
-
import {
|
|
65350
|
-
import {
|
|
65351
|
-
import { dirname as dirname10, isAbsolute as isAbsolute3, join as join19, resolve as resolve4 } from "node:path";
|
|
65596
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, readlinkSync as readlinkSync3 } from "node:fs";
|
|
65597
|
+
import { dirname as dirname11, isAbsolute as isAbsolute3, join as join20, resolve as resolve4 } from "node:path";
|
|
65352
65598
|
var line = (key, value, ok = null) => ({ key, value, ok });
|
|
65353
65599
|
var NO_GENERATION = "n/a (no active generation)";
|
|
65354
65600
|
function resolvePointerTarget(paths, raw) {
|
|
65355
|
-
return isAbsolute3(raw) ? raw : resolve4(
|
|
65601
|
+
return isAbsolute3(raw) ? raw : resolve4(dirname11(paths.currentGeneration), raw);
|
|
65356
65602
|
}
|
|
65357
65603
|
function computeGenerationLine(paths, pointer) {
|
|
65358
65604
|
const dir = activeGeneration(paths);
|
|
65359
65605
|
if (dir !== null) {
|
|
65360
|
-
if (!isGenerationDir(dir))
|
|
65606
|
+
if (!isGenerationDir(dir) && !existsSync13(join20(dir, INSTALLATION_FILE)))
|
|
65361
65607
|
return { line: line("generation", "foreign", false), dir: null };
|
|
65362
65608
|
return { line: line("generation", dir, true), dir };
|
|
65363
65609
|
}
|
|
@@ -65427,25 +65673,26 @@ function upstreamCommitLine(record2) {
|
|
|
65427
65673
|
function digestLine(key, label, record2, dir) {
|
|
65428
65674
|
if (!record2 || !dir)
|
|
65429
65675
|
return line(label, NO_GENERATION, null);
|
|
65430
|
-
const file2 =
|
|
65676
|
+
const file2 = executablePath(dir, key);
|
|
65431
65677
|
if (!existsSync13(file2))
|
|
65432
65678
|
return line(label, "missing", false);
|
|
65433
|
-
let
|
|
65679
|
+
let got;
|
|
65434
65680
|
try {
|
|
65435
|
-
|
|
65681
|
+
got = digestOf(file2);
|
|
65436
65682
|
} catch (e) {
|
|
65437
65683
|
return line(label, `unreadable: ${e.message.split(`
|
|
65438
65684
|
`)[0]}`, false);
|
|
65439
65685
|
}
|
|
65440
|
-
const
|
|
65441
|
-
|
|
65686
|
+
const want = record2.provenance.files?.[`bin/${key}`] ?? record2.provenance.executables?.[key];
|
|
65687
|
+
if (!want)
|
|
65688
|
+
return line(label, "no digest recorded", false);
|
|
65442
65689
|
const verified = got.sha256 === want.sha256 && got.size === want.size;
|
|
65443
65690
|
return line(label, verified ? "verified" : "MISMATCH", verified);
|
|
65444
65691
|
}
|
|
65445
65692
|
function codexVersionLine(ctx, record2, dir) {
|
|
65446
65693
|
if (!record2 || !dir)
|
|
65447
65694
|
return line("codex_version", NO_GENERATION, null);
|
|
65448
|
-
const bin =
|
|
65695
|
+
const bin = executablePath(dir, "codex");
|
|
65449
65696
|
if (!existsSync13(bin))
|
|
65450
65697
|
return line("codex_version", "missing", false);
|
|
65451
65698
|
let result2;
|
|
@@ -65468,9 +65715,41 @@ function legalLine(record2, dir) {
|
|
|
65468
65715
|
return line("legal", "n/a (compiled build)", null);
|
|
65469
65716
|
if (!dir)
|
|
65470
65717
|
return line("legal", NO_GENERATION, null);
|
|
65471
|
-
const missing = GENERATION_LEGAL_FILES.filter((f2) => !existsSync13(
|
|
65718
|
+
const missing = GENERATION_LEGAL_FILES.filter((f2) => !existsSync13(join20(dir, f2)));
|
|
65472
65719
|
return missing.length === 0 ? line("legal", "present", true) : line("legal", `missing: ${missing.join(", ")}`, false);
|
|
65473
65720
|
}
|
|
65721
|
+
var DAEMON_SINCE = parseSemver("0.156.0");
|
|
65722
|
+
function packageLayoutLine(record2, dir) {
|
|
65723
|
+
if (!record2 || !dir)
|
|
65724
|
+
return line("package_layout", NO_GENERATION, null);
|
|
65725
|
+
if (!isPackageLayout(dir) || record2.provenance.files === undefined || record2.provenance.target === undefined) {
|
|
65726
|
+
const parsed = parseSemver(record2.codexVersion);
|
|
65727
|
+
const needed = parsed !== null && compareSemver(parsed, DAEMON_SINCE) >= 0;
|
|
65728
|
+
return line("package_layout", "flat layout from an older cxstatusline: run cxstatusline upgrade", needed ? false : null);
|
|
65729
|
+
}
|
|
65730
|
+
const problem = verifyPackage(dir, record2.provenance.files, { target: record2.provenance.target, codexVersion: record2.codexVersion });
|
|
65731
|
+
return problem === null ? line("package_layout", `ok (${record2.provenance.target})`, true) : line("package_layout", problem, false);
|
|
65732
|
+
}
|
|
65733
|
+
function daemonPackageLine(paths, record2) {
|
|
65734
|
+
const current = join20(paths.codexHome, "packages", "app-server-daemon", "current");
|
|
65735
|
+
let target;
|
|
65736
|
+
try {
|
|
65737
|
+
target = readlinkSync3(current);
|
|
65738
|
+
} catch {
|
|
65739
|
+
return line("daemon_package", "none", null);
|
|
65740
|
+
}
|
|
65741
|
+
const dir = isAbsolute3(target) ? target : resolve4(dirname11(current), target);
|
|
65742
|
+
let version2 = "unknown";
|
|
65743
|
+
try {
|
|
65744
|
+
const meta3 = JSON.parse(readFileSync13(join20(dir, "codex-package.json"), "utf8"));
|
|
65745
|
+
if (typeof meta3.version === "string")
|
|
65746
|
+
version2 = meta3.version;
|
|
65747
|
+
} catch {}
|
|
65748
|
+
if (record2 && version2 !== "unknown" && version2 !== record2.codexVersion) {
|
|
65749
|
+
return line("daemon_package", `daemon ${version2} differs from active ${record2.codexVersion} (${dir}); run codex app-server daemon restart`, false);
|
|
65750
|
+
}
|
|
65751
|
+
return line("daemon_package", `${version2} (${dir})`, null);
|
|
65752
|
+
}
|
|
65474
65753
|
function generationDetailLines(ctx, status) {
|
|
65475
65754
|
const { record: record2, dir } = status;
|
|
65476
65755
|
return [
|
|
@@ -65483,7 +65762,9 @@ function generationDetailLines(ctx, status) {
|
|
|
65483
65762
|
digestLine("codex", "codex_digest", record2, dir),
|
|
65484
65763
|
digestLine("codex-code-mode-host", "host_digest", record2, dir),
|
|
65485
65764
|
codexVersionLine(ctx, record2, dir),
|
|
65486
|
-
legalLine(record2, dir)
|
|
65765
|
+
legalLine(record2, dir),
|
|
65766
|
+
packageLayoutLine(record2, dir),
|
|
65767
|
+
daemonPackageLine(ctx.paths, record2)
|
|
65487
65768
|
];
|
|
65488
65769
|
}
|
|
65489
65770
|
function toolchainLine(ctx, source) {
|
|
@@ -65637,12 +65918,12 @@ function wrapperLine(ctx) {
|
|
|
65637
65918
|
const p2 = ctx.paths.wrapperPath;
|
|
65638
65919
|
let st2;
|
|
65639
65920
|
try {
|
|
65640
|
-
st2 =
|
|
65921
|
+
st2 = lstatSync7(p2);
|
|
65641
65922
|
} catch {
|
|
65642
65923
|
return line2("wrapper", "absent");
|
|
65643
65924
|
}
|
|
65644
65925
|
if (st2.isSymbolicLink())
|
|
65645
|
-
return line2("wrapper", `upstream symlink -> ${
|
|
65926
|
+
return line2("wrapper", `upstream symlink -> ${readlinkSync4(p2)}`);
|
|
65646
65927
|
return isOurWrapper(p2) ? line2("wrapper", "ours", true) : line2("wrapper", "foreign file! not ours, not a symlink", false);
|
|
65647
65928
|
}
|
|
65648
65929
|
function hookLine(ctx) {
|
|
@@ -65692,7 +65973,7 @@ function commandCacheLine(ctx) {
|
|
|
65692
65973
|
let oldestMtime = Infinity;
|
|
65693
65974
|
for (const f2 of entries) {
|
|
65694
65975
|
try {
|
|
65695
|
-
const st2 =
|
|
65976
|
+
const st2 = lstatSync7(join21(dir, f2));
|
|
65696
65977
|
if (st2.mtimeMs < oldestMtime)
|
|
65697
65978
|
oldestMtime = st2.mtimeMs;
|
|
65698
65979
|
} catch {}
|
|
@@ -65788,7 +66069,7 @@ async function doctorReport(ctx, opts) {
|
|
|
65788
66069
|
return line2("drift", `behind within minor: ${patched.raw} < ${upstream.raw} (held by policy; \`patch --force\` to pick up)`);
|
|
65789
66070
|
return line2("drift", "none", true);
|
|
65790
66071
|
};
|
|
65791
|
-
const
|
|
66072
|
+
const codexTarget2 = await codexTargetLine(ctx, effectivePatchedFrom, opts);
|
|
65792
66073
|
const lines = [
|
|
65793
66074
|
line2("renderer", `${ctx.cxBin} (${VERSION})`),
|
|
65794
66075
|
line2("settings", `${ctx.paths.settingsFile} ${existsSync14(ctx.paths.settingsFile) ? "present" : "absent (written on first render)"}`),
|
|
@@ -65797,7 +66078,7 @@ async function doctorReport(ctx, opts) {
|
|
|
65797
66078
|
line2("patch_version", status.record?.provenance.patchVersion === undefined ? "unknown (legacy)" : `v${status.record.provenance.patchVersion}`),
|
|
65798
66079
|
line2("patched_from", state.patched_from ?? "never"),
|
|
65799
66080
|
line2("policy", state.policy),
|
|
65800
|
-
|
|
66081
|
+
codexTarget2,
|
|
65801
66082
|
drift(),
|
|
65802
66083
|
bookkeepingLine(state, status.record),
|
|
65803
66084
|
wrapperLine(ctx),
|
|
@@ -65863,11 +66144,11 @@ function runPolicy(ctx, argv, io2) {
|
|
|
65863
66144
|
}
|
|
65864
66145
|
|
|
65865
66146
|
// src/commands/revert.ts
|
|
65866
|
-
import { existsSync as existsSync15, lstatSync as
|
|
65867
|
-
import { join as
|
|
66147
|
+
import { existsSync as existsSync15, lstatSync as lstatSync8, readFileSync as readFileSync15, readdirSync as readdirSync4, readlinkSync as readlinkSync5, rmSync as rmSync7, symlinkSync as symlinkSync2 } from "node:fs";
|
|
66148
|
+
import { basename as basename2, dirname as dirname12, isAbsolute as isAbsolute4, join as join22, resolve as resolve5 } from "node:path";
|
|
65868
66149
|
function safeIsSymlink(p2) {
|
|
65869
66150
|
try {
|
|
65870
|
-
return
|
|
66151
|
+
return lstatSync8(p2).isSymbolicLink();
|
|
65871
66152
|
} catch {
|
|
65872
66153
|
return false;
|
|
65873
66154
|
}
|
|
@@ -65886,23 +66167,23 @@ function revert(ctx) {
|
|
|
65886
66167
|
function removeGenerations(ctx, actions) {
|
|
65887
66168
|
const { currentGeneration, generationsDir } = ctx.paths;
|
|
65888
66169
|
if (existsSync15(currentGeneration) || safeIsSymlink(currentGeneration)) {
|
|
65889
|
-
|
|
66170
|
+
rmSync7(currentGeneration, { recursive: true, force: true });
|
|
65890
66171
|
actions.push(`removed generation pointer ${currentGeneration}`);
|
|
65891
66172
|
}
|
|
65892
66173
|
if (!existsSync15(generationsDir))
|
|
65893
66174
|
return;
|
|
65894
66175
|
let removed = 0;
|
|
65895
66176
|
for (const dir of listGenerations(ctx.paths)) {
|
|
65896
|
-
if (!
|
|
66177
|
+
if (!GENERATION_NAME.test(basename2(dir)) || safeIsSymlink(dir)) {
|
|
65897
66178
|
actions.push(`${dir} is not a cxstatusline generation; left in place`);
|
|
65898
66179
|
continue;
|
|
65899
66180
|
}
|
|
65900
|
-
|
|
66181
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
65901
66182
|
removed += 1;
|
|
65902
66183
|
}
|
|
65903
66184
|
actions.push(`removed ${removed} cxstatusline generation${removed === 1 ? "" : "s"} from ${generationsDir}`);
|
|
65904
66185
|
if (readdirSync4(generationsDir).length === 0)
|
|
65905
|
-
|
|
66186
|
+
rmSync7(generationsDir, { recursive: true, force: true });
|
|
65906
66187
|
}
|
|
65907
66188
|
var OWNED_LIBEXEC_PREFIXES = ["current.", "staging-", "download-", "compiled-"];
|
|
65908
66189
|
function removeStagingDebris(ctx, actions) {
|
|
@@ -65911,11 +66192,32 @@ function removeStagingDebris(ctx, actions) {
|
|
|
65911
66192
|
return;
|
|
65912
66193
|
const debris = readdirSync4(libexecDir).filter((n) => OWNED_LIBEXEC_PREFIXES.some((p2) => n.startsWith(p2)));
|
|
65913
66194
|
for (const name of debris)
|
|
65914
|
-
|
|
66195
|
+
rmSync7(join22(libexecDir, name), { recursive: true, force: true });
|
|
65915
66196
|
if (debris.length > 0) {
|
|
65916
66197
|
actions.push(`removed ${debris.length} leftover staging entr${debris.length === 1 ? "y" : "ies"} from ${libexecDir}`);
|
|
65917
66198
|
}
|
|
65918
66199
|
}
|
|
66200
|
+
function daemonCopyNotice(ctx, actions) {
|
|
66201
|
+
const root = join22(ctx.paths.codexHome, "packages", "app-server-daemon");
|
|
66202
|
+
const current = join22(root, "current");
|
|
66203
|
+
let target;
|
|
66204
|
+
try {
|
|
66205
|
+
target = readlinkSync5(current);
|
|
66206
|
+
} catch {
|
|
66207
|
+
return;
|
|
66208
|
+
}
|
|
66209
|
+
const dir = isAbsolute4(target) ? target : resolve5(dirname12(current), target);
|
|
66210
|
+
let ours = false;
|
|
66211
|
+
try {
|
|
66212
|
+
const record2 = JSON.parse(readFileSync15(join22(dir, INSTALLATION_FILE), "utf8"));
|
|
66213
|
+
ours = typeof record2?.provenance?.cxVersion === "string";
|
|
66214
|
+
} catch {
|
|
66215
|
+
return;
|
|
66216
|
+
}
|
|
66217
|
+
if (!ours)
|
|
66218
|
+
return;
|
|
66219
|
+
actions.push(`the Codex daemon still runs a copy of the removed generation (${dir}); stop it and remove the copy: codex app-server daemon stop && rm -rf ${root}`);
|
|
66220
|
+
}
|
|
65919
66221
|
function revertLocked(ctx) {
|
|
65920
66222
|
const actions = [];
|
|
65921
66223
|
let code = 0;
|
|
@@ -65925,7 +66227,7 @@ function revertLocked(ctx) {
|
|
|
65925
66227
|
const w2 = ctx.paths.wrapperPath;
|
|
65926
66228
|
if (existsSync15(w2) || safeIsSymlink(w2)) {
|
|
65927
66229
|
if (isOurWrapper(w2)) {
|
|
65928
|
-
|
|
66230
|
+
rmSync7(w2);
|
|
65929
66231
|
actions.push(`removed wrapper ${w2}`);
|
|
65930
66232
|
if (state.launcher_restore?.kind === "symlink") {
|
|
65931
66233
|
symlinkSync2(state.launcher_restore.target, w2);
|
|
@@ -65938,13 +66240,14 @@ function revertLocked(ctx) {
|
|
|
65938
66240
|
}
|
|
65939
66241
|
}
|
|
65940
66242
|
removeGenerations(ctx, actions);
|
|
66243
|
+
daemonCopyNotice(ctx, actions);
|
|
65941
66244
|
removeStagingDebris(ctx, actions);
|
|
65942
66245
|
if (existsSync15(ctx.paths.patchedBin)) {
|
|
65943
|
-
|
|
66246
|
+
rmSync7(ctx.paths.patchedBin);
|
|
65944
66247
|
actions.push(`removed patched binary ${ctx.paths.patchedBin}`);
|
|
65945
66248
|
}
|
|
65946
66249
|
if (existsSync15(ctx.paths.patchedCodeModeHost)) {
|
|
65947
|
-
|
|
66250
|
+
rmSync7(ctx.paths.patchedCodeModeHost);
|
|
65948
66251
|
actions.push(`removed Code Mode host ${ctx.paths.patchedCodeModeHost}`);
|
|
65949
66252
|
}
|
|
65950
66253
|
try {
|
|
@@ -67562,7 +67865,7 @@ function MainMenu({ onSelect, initialSelection = 0, hasChanges = false }) {
|
|
|
67562
67865
|
// src/tui/components/PowerlineSetup.tsx
|
|
67563
67866
|
import { existsSync as existsSync16, readdirSync as readdirSync5 } from "node:fs";
|
|
67564
67867
|
import { homedir as homedir2, platform as platform2 } from "node:os";
|
|
67565
|
-
import { join as
|
|
67868
|
+
import { join as join23 } from "node:path";
|
|
67566
67869
|
var import_react51 = __toESM(require_react(), 1);
|
|
67567
67870
|
|
|
67568
67871
|
// src/utils/powerline-settings.ts
|
|
@@ -67947,7 +68250,7 @@ function buildPowerlineSetupMenuItems(powerline) {
|
|
|
67947
68250
|
];
|
|
67948
68251
|
}
|
|
67949
68252
|
function detectPowerlineFont() {
|
|
67950
|
-
const dirs = platform2() === "darwin" ? [
|
|
68253
|
+
const dirs = platform2() === "darwin" ? [join23(homedir2(), "Library", "Fonts"), "/Library/Fonts"] : platform2() === "win32" ? [join23(homedir2(), "AppData", "Local", "Microsoft", "Windows", "Fonts"), "C:\\Windows\\Fonts"] : [join23(homedir2(), ".local", "share", "fonts"), join23(homedir2(), ".fonts"), "/usr/share/fonts"];
|
|
67951
68254
|
try {
|
|
67952
68255
|
return dirs.some((dir) => existsSync16(dir) && readdirSync5(dir).some((file2) => /powerline|nerd font|meslo.*lg/i.test(file2)));
|
|
67953
68256
|
} catch {
|
|
@@ -68468,7 +68771,7 @@ function readMemoryUsage(deps, nowMs) {
|
|
|
68468
68771
|
// src/commands/update-tool.ts
|
|
68469
68772
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
68470
68773
|
import { existsSync as existsSync17, realpathSync as realpathSync4 } from "node:fs";
|
|
68471
|
-
import { dirname as
|
|
68774
|
+
import { dirname as dirname13, join as join24 } from "node:path";
|
|
68472
68775
|
async function defaultFetchLatestVersion() {
|
|
68473
68776
|
const controller = new AbortController;
|
|
68474
68777
|
const timer = setTimeout(() => controller.abort(), 5000);
|
|
@@ -68495,12 +68798,12 @@ function detectInstallType(binaryPath = process.argv[1]) {
|
|
|
68495
68798
|
try {
|
|
68496
68799
|
resolved = realpathSync4(binaryPath);
|
|
68497
68800
|
} catch {}
|
|
68498
|
-
let dir =
|
|
68801
|
+
let dir = dirname13(resolved);
|
|
68499
68802
|
for (let i = 0;i < 5; i++) {
|
|
68500
|
-
if (existsSync17(
|
|
68803
|
+
if (existsSync17(join24(dir, ".git")) && existsSync17(join24(dir, "package.json"))) {
|
|
68501
68804
|
return { type: "git", repoDir: dir };
|
|
68502
68805
|
}
|
|
68503
|
-
const parent =
|
|
68806
|
+
const parent = dirname13(dir);
|
|
68504
68807
|
if (parent === dir)
|
|
68505
68808
|
break;
|
|
68506
68809
|
dir = parent;
|
|
@@ -68704,14 +69007,16 @@ async function installCommand(argv, io2, deps) {
|
|
|
68704
69007
|
}
|
|
68705
69008
|
}
|
|
68706
69009
|
const ctx = contextFor(io2, deps);
|
|
68707
|
-
if (
|
|
69010
|
+
if (!codexVersion) {
|
|
68708
69011
|
let manifest;
|
|
68709
69012
|
try {
|
|
68710
69013
|
manifest = loadManifest(ctx.patchesDir);
|
|
68711
69014
|
} catch (e) {
|
|
68712
|
-
io2.
|
|
69015
|
+
if (io2.isTTY === true && !yes) {
|
|
69016
|
+
io2.stderr(`Cannot load supported Codex versions: ${e instanceof Error ? e.message : String(e)}
|
|
68713
69017
|
`);
|
|
68714
|
-
|
|
69018
|
+
return 1;
|
|
69019
|
+
}
|
|
68715
69020
|
}
|
|
68716
69021
|
if (manifest) {
|
|
68717
69022
|
const supported = supportedCodexVersions(manifest);
|
|
@@ -68724,42 +69029,29 @@ async function installCommand(argv, io2, deps) {
|
|
|
68724
69029
|
prebuiltVersions = undefined;
|
|
68725
69030
|
}
|
|
68726
69031
|
}
|
|
68727
|
-
|
|
68728
|
-
|
|
68729
|
-
const
|
|
68730
|
-
|
|
68731
|
-
|
|
68732
|
-
|
|
68733
|
-
|
|
68734
|
-
|
|
68735
|
-
|
|
68736
|
-
|
|
68737
|
-
}
|
|
68738
|
-
}
|
|
68739
|
-
}
|
|
68740
|
-
}
|
|
68741
|
-
} catch {}
|
|
68742
|
-
if (!defaultVersion && prebuiltVersions && prebuiltVersions.length > 0) {
|
|
68743
|
-
defaultVersion = supported.find((v2) => prebuiltVersions.includes(v2));
|
|
68744
|
-
}
|
|
68745
|
-
const prompter = deps.promptVersion ?? promptCodexVersion;
|
|
68746
|
-
const result2 = await prompter({
|
|
68747
|
-
supportedVersions: supported,
|
|
68748
|
-
prebuiltVersions,
|
|
68749
|
-
defaultVersion,
|
|
68750
|
-
compile: compile3,
|
|
68751
|
-
isTTY: true,
|
|
68752
|
-
say: (l) => io2.stdout(`${l}
|
|
69032
|
+
const defaultVersion = compile3 ? supported[0] : prebuiltVersions && prebuiltVersions.length > 0 ? supported.find((v2) => prebuiltVersions.includes(v2)) ?? supported[0] : supported[0];
|
|
69033
|
+
if (io2.isTTY === true && !yes) {
|
|
69034
|
+
const prompter = deps.promptVersion ?? promptCodexVersion;
|
|
69035
|
+
const result2 = await prompter({
|
|
69036
|
+
supportedVersions: supported,
|
|
69037
|
+
prebuiltVersions,
|
|
69038
|
+
defaultVersion,
|
|
69039
|
+
compile: compile3,
|
|
69040
|
+
isTTY: true,
|
|
69041
|
+
say: (l) => io2.stdout(`${l}
|
|
68753
69042
|
`)
|
|
68754
|
-
|
|
68755
|
-
|
|
68756
|
-
|
|
69043
|
+
});
|
|
69044
|
+
if (result2 === null) {
|
|
69045
|
+
io2.stdout(`Installation cancelled.
|
|
68757
69046
|
`);
|
|
68758
|
-
|
|
69047
|
+
return 0;
|
|
69048
|
+
}
|
|
69049
|
+
const selection = typeof result2 === "string" ? { version: result2, compile: false } : result2;
|
|
69050
|
+
codexVersion = selection.version;
|
|
69051
|
+
compile3 = compile3 || selection.compile;
|
|
69052
|
+
} else {
|
|
69053
|
+
codexVersion = defaultVersion;
|
|
68759
69054
|
}
|
|
68760
|
-
const selection = typeof result2 === "string" ? { version: result2, compile: false } : result2;
|
|
68761
|
-
codexVersion = selection.version;
|
|
68762
|
-
compile3 = compile3 || selection.compile;
|
|
68763
69055
|
}
|
|
68764
69056
|
}
|
|
68765
69057
|
}
|
|
@@ -68912,7 +69204,7 @@ main(argv, {
|
|
|
68912
69204
|
isTTY: canPrompt(process.stdin, process.stdout),
|
|
68913
69205
|
stdin: () => {
|
|
68914
69206
|
try {
|
|
68915
|
-
return
|
|
69207
|
+
return readFileSync16(0, "utf8");
|
|
68916
69208
|
} catch {
|
|
68917
69209
|
return "";
|
|
68918
69210
|
}
|