cxstatusline 0.9.1 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -7
- package/dist/cxstatusline.js +226 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
- [🚀 Install](#-install)
|
|
32
32
|
- [🎛️ Configure](#️-configure)
|
|
33
33
|
- [🧩 Widgets Catalog](#widgets)
|
|
34
|
-
- [🔄 Update & Revert](#update)
|
|
34
|
+
- [🔄 Update, Upgrade & Revert](#update)
|
|
35
35
|
- [🔍 How it Works](#-how-it-works)
|
|
36
36
|
- [🏷️ Supported Versions](#supported-versions)
|
|
37
37
|
- [🩺 Troubleshooting](#-troubleshooting)
|
|
@@ -81,7 +81,7 @@ cxstatusline doctor
|
|
|
81
81
|
|
|
82
82
|
`cxstatusline install` downloads the verified prebuilt binary matching your Codex version, verifies checksums against `manifest.json`, and activates it.
|
|
83
83
|
- **Interactive selection**: Running `cxstatusline install` opens a keyboard-driven version picker. Use ↑/↓ and Enter to select, or Escape/Ctrl+C to cancel. Prebuilt availability is shown per version; source-only choices require confirmation (unless you already passed `--compile`).
|
|
84
|
-
- **
|
|
84
|
+
- **Upgrade choices**: `cxstatusline upgrade` uses the same keyboard controls to choose the latest supported prebuilt, a supported source build, or cancellation. It does not update upstream Codex first.
|
|
85
85
|
- **Live progress**: Ink renders download progress in terminals while completed stages remain in the transcript. Source builds report their phases; redirected output retains plain milestone logs.
|
|
86
86
|
- **Target a specific version**: `cxstatusline install --codex-version <version>` (e.g. `cxstatusline install --codex-version 0.154.0`).
|
|
87
87
|
- **Non-interactive / CI**: Pass `-y` or `--yes` to accept the default without prompting.
|
|
@@ -147,19 +147,35 @@ Type IDs match ccstatusline's, so a ccstatusline preset imports without translat
|
|
|
147
147
|
👉 The full catalog, and how Custom Command handles timeouts, colours and background caching, are in
|
|
148
148
|
the **[Usage guide](docs/usage.md)**.
|
|
149
149
|
|
|
150
|
-
## Update
|
|
150
|
+
## Update & Upgrade
|
|
151
|
+
|
|
152
|
+
cxstatusline follows the Homebrew paradigm for managing updates:
|
|
153
|
+
- **`cxstatusline update`**: Updates the **cxstatusline CLI tool itself** to the latest release (via npm, bun, or git).
|
|
154
|
+
- **`cxstatusline upgrade`**: Upgrades the **patched Codex binary pair** to the latest supported release.
|
|
155
|
+
|
|
156
|
+
### Updating cxstatusline (The Tool)
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
cxstatusline update # Updates cxstatusline to the latest version
|
|
160
|
+
cxstatusline update --check # Checks for available tool updates without installing
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`cxstatusline update` automatically detects your install method (`npm`, `bun`, or `git checkout`) and updates the CLI tool.
|
|
164
|
+
|
|
165
|
+
### Upgrading Patched Codex
|
|
151
166
|
|
|
152
167
|
```sh
|
|
153
|
-
cxstatusline
|
|
168
|
+
cxstatusline upgrade
|
|
154
169
|
```
|
|
155
170
|
|
|
156
|
-
`cxstatusline
|
|
171
|
+
`cxstatusline upgrade` downloads and verifies the latest published prebuilt supported by your cxstatusline package, then activates the complete patched Codex pair. It does not run Codex's self-updater or modify your original Codex installation. Open a new Codex session afterward.
|
|
157
172
|
|
|
158
|
-
The same Codex version is checked for rebuilt patch assets; a newer installed version is never downgraded. If discovery or verification fails, the active pair stays in place.
|
|
173
|
+
The same Codex version is checked for rebuilt patch assets; a newer installed version is never downgraded. If discovery or verification fails, the active pair stays in place. When running `upgrade`, if a newer version of `cxstatusline` is available, it will display a friendly reminder to run `cxstatusline update` first.
|
|
159
174
|
|
|
160
175
|
Options:
|
|
161
|
-
- `cxstatusline
|
|
176
|
+
- `cxstatusline upgrade --compile`: builds the latest locally supported Codex patch from source instead.
|
|
162
177
|
- `--force`, `-y`, and `--yes` remain accepted for compatibility; updates already run without a prompt and always verify the pair.
|
|
178
|
+
- Note: Running `cxstatusline update --compile` or `--force` will automatically forward to `cxstatusline upgrade` with a notice.
|
|
163
179
|
|
|
164
180
|
Session-start updates also leave a newer patched pair in place when the original Codex installation is older, including under the `every` policy.
|
|
165
181
|
|
package/dist/cxstatusline.js
CHANGED
|
@@ -59007,8 +59007,8 @@ function runRefreshCommand(cacheKey2, deps) {
|
|
|
59007
59007
|
return 0;
|
|
59008
59008
|
}
|
|
59009
59009
|
// src/version-info.ts
|
|
59010
|
-
var VERSION = "0.
|
|
59011
|
-
var SOURCE_COMMIT = /^[0-9a-f]{40}$/.test("
|
|
59010
|
+
var VERSION = "0.10.1";
|
|
59011
|
+
var SOURCE_COMMIT = /^[0-9a-f]{40}$/.test("cb2f6799d53ce95398331bae1cea4f96d2c9641e") ? "cb2f6799d53ce95398331bae1cea4f96d2c9641e" : null;
|
|
59012
59012
|
var SOURCE_DIRTY = false;
|
|
59013
59013
|
|
|
59014
59014
|
// src/context.ts
|
|
@@ -59149,7 +59149,7 @@ function realContext(env3, io) {
|
|
|
59149
59149
|
}
|
|
59150
59150
|
|
|
59151
59151
|
// src/patch/run.ts
|
|
59152
|
-
import { appendFileSync, mkdirSync as mkdirSync8 } from "node:fs";
|
|
59152
|
+
import { appendFileSync, mkdirSync as mkdirSync8, rmSync as rmSync6 } from "node:fs";
|
|
59153
59153
|
import { join as join18 } from "node:path";
|
|
59154
59154
|
|
|
59155
59155
|
// src/lock.ts
|
|
@@ -63147,7 +63147,7 @@ function unchangedPair(ctx, manifest, artifact, tag) {
|
|
|
63147
63147
|
if (!release || release.tag !== tag || release.archiveSha256 !== artifact.sha256)
|
|
63148
63148
|
return null;
|
|
63149
63149
|
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;
|
|
63150
|
+
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
63151
|
if (!identical)
|
|
63152
63152
|
return null;
|
|
63153
63153
|
const directory = activeGeneration(ctx.paths);
|
|
@@ -64202,7 +64202,7 @@ function wrapperScript(patchedBin, cxBin) {
|
|
|
64202
64202
|
WRAPPER_MARKER,
|
|
64203
64203
|
"# Managed by cxstatusline. `cxstatusline revert` restores stock Codex.",
|
|
64204
64204
|
`if [ "$1" = "update" ]; then`,
|
|
64205
|
-
` exec ${sq(cxBin)}
|
|
64205
|
+
` exec ${sq(cxBin)} upgrade`,
|
|
64206
64206
|
"fi",
|
|
64207
64207
|
`CXSTATUSLINE_COMMAND=${sq(`${sq(cxBin)} render`)}`,
|
|
64208
64208
|
"export CXSTATUSLINE_COMMAND",
|
|
@@ -64217,7 +64217,7 @@ function generationWrapperScript(currentGeneration, cxBin) {
|
|
|
64217
64217
|
WRAPPER_MARKER_V2,
|
|
64218
64218
|
"# Managed by cxstatusline. `cxstatusline revert` restores stock Codex.",
|
|
64219
64219
|
`if [ "$1" = "update" ]; then`,
|
|
64220
|
-
` exec ${sq(cxBin)}
|
|
64220
|
+
` exec ${sq(cxBin)} upgrade`,
|
|
64221
64221
|
"fi",
|
|
64222
64222
|
`CXSTATUSLINE_COMMAND=${sq(`${sq(cxBin)} render`)}`,
|
|
64223
64223
|
"export CXSTATUSLINE_COMMAND",
|
|
@@ -65006,11 +65006,37 @@ async function runUpdate(ctx, opts = {}, transport = {}) {
|
|
|
65006
65006
|
}
|
|
65007
65007
|
const installed = readInstallation(ctx.paths)?.codexVersion ?? loadState(ctx).patched_from;
|
|
65008
65008
|
const current = installed ? parseSemver(installed) : null;
|
|
65009
|
-
|
|
65009
|
+
const targetSemver = parseSemver(target);
|
|
65010
|
+
if (current && compareSemver(current, targetSemver) > 0) {
|
|
65010
65011
|
ctx.say(`Installed Codex ${installed} is newer than the latest supported ${opts.compile ? "patch" : "prebuilt"} (${target}); leaving it unchanged.`);
|
|
65011
65012
|
return 0;
|
|
65012
65013
|
}
|
|
65013
|
-
if (
|
|
65014
|
+
if (current && compareSemver(current, targetSemver) === 0 && !opts.force) {
|
|
65015
|
+
const record2 = readInstallation(ctx.paths);
|
|
65016
|
+
if (!opts.compile && record2 && record2.provenance.source === "prebuilt") {
|
|
65017
|
+
try {
|
|
65018
|
+
const expected = {
|
|
65019
|
+
codexVersion: target,
|
|
65020
|
+
platform: platformFor(process.platform, process.arch)
|
|
65021
|
+
};
|
|
65022
|
+
const prepared = await preparePrebuilt(ctx, expected, transport);
|
|
65023
|
+
if (prepared.kind === "unchanged") {
|
|
65024
|
+
ctx.say(`Codex is already up to date (${installed}).`);
|
|
65025
|
+
return 0;
|
|
65026
|
+
}
|
|
65027
|
+
rmSync6(prepared.pair.directory, { recursive: true, force: true });
|
|
65028
|
+
} catch {}
|
|
65029
|
+
} else if (opts.compile && record2 && record2.provenance.source === "compiled") {
|
|
65030
|
+
const patchRef = resolvePatch(manifest, targetSemver);
|
|
65031
|
+
const currentPatch = record2.provenance.patchVersion ?? 1;
|
|
65032
|
+
const targetPatch = patchRef?.patchVersion ?? 1;
|
|
65033
|
+
if (currentPatch >= targetPatch) {
|
|
65034
|
+
ctx.say(`Codex is already up to date (${installed}).`);
|
|
65035
|
+
return 0;
|
|
65036
|
+
}
|
|
65037
|
+
}
|
|
65038
|
+
}
|
|
65039
|
+
if (opts.isTTY && !opts.force && !opts.compile && (!current || compareSemver(current, targetSemver) < 0)) {
|
|
65014
65040
|
const action = await (opts.promptUpdate ?? promptUpdate)({ latest: target, highestAvailable: target });
|
|
65015
65041
|
if (action === "cancel") {
|
|
65016
65042
|
ctx.say("Update cancelled.");
|
|
@@ -65863,7 +65889,7 @@ function runPolicy(ctx, argv, io2) {
|
|
|
65863
65889
|
}
|
|
65864
65890
|
|
|
65865
65891
|
// src/commands/revert.ts
|
|
65866
|
-
import { existsSync as existsSync15, lstatSync as lstatSync7, readdirSync as readdirSync4, rmSync as
|
|
65892
|
+
import { existsSync as existsSync15, lstatSync as lstatSync7, readdirSync as readdirSync4, rmSync as rmSync7, symlinkSync as symlinkSync2 } from "node:fs";
|
|
65867
65893
|
import { join as join21 } from "node:path";
|
|
65868
65894
|
function safeIsSymlink(p2) {
|
|
65869
65895
|
try {
|
|
@@ -65886,7 +65912,7 @@ function revert(ctx) {
|
|
|
65886
65912
|
function removeGenerations(ctx, actions) {
|
|
65887
65913
|
const { currentGeneration, generationsDir } = ctx.paths;
|
|
65888
65914
|
if (existsSync15(currentGeneration) || safeIsSymlink(currentGeneration)) {
|
|
65889
|
-
|
|
65915
|
+
rmSync7(currentGeneration, { recursive: true, force: true });
|
|
65890
65916
|
actions.push(`removed generation pointer ${currentGeneration}`);
|
|
65891
65917
|
}
|
|
65892
65918
|
if (!existsSync15(generationsDir))
|
|
@@ -65897,12 +65923,12 @@ function removeGenerations(ctx, actions) {
|
|
|
65897
65923
|
actions.push(`${dir} is not a cxstatusline generation; left in place`);
|
|
65898
65924
|
continue;
|
|
65899
65925
|
}
|
|
65900
|
-
|
|
65926
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
65901
65927
|
removed += 1;
|
|
65902
65928
|
}
|
|
65903
65929
|
actions.push(`removed ${removed} cxstatusline generation${removed === 1 ? "" : "s"} from ${generationsDir}`);
|
|
65904
65930
|
if (readdirSync4(generationsDir).length === 0)
|
|
65905
|
-
|
|
65931
|
+
rmSync7(generationsDir, { recursive: true, force: true });
|
|
65906
65932
|
}
|
|
65907
65933
|
var OWNED_LIBEXEC_PREFIXES = ["current.", "staging-", "download-", "compiled-"];
|
|
65908
65934
|
function removeStagingDebris(ctx, actions) {
|
|
@@ -65911,7 +65937,7 @@ function removeStagingDebris(ctx, actions) {
|
|
|
65911
65937
|
return;
|
|
65912
65938
|
const debris = readdirSync4(libexecDir).filter((n) => OWNED_LIBEXEC_PREFIXES.some((p2) => n.startsWith(p2)));
|
|
65913
65939
|
for (const name of debris)
|
|
65914
|
-
|
|
65940
|
+
rmSync7(join21(libexecDir, name), { recursive: true, force: true });
|
|
65915
65941
|
if (debris.length > 0) {
|
|
65916
65942
|
actions.push(`removed ${debris.length} leftover staging entr${debris.length === 1 ? "y" : "ies"} from ${libexecDir}`);
|
|
65917
65943
|
}
|
|
@@ -65925,7 +65951,7 @@ function revertLocked(ctx) {
|
|
|
65925
65951
|
const w2 = ctx.paths.wrapperPath;
|
|
65926
65952
|
if (existsSync15(w2) || safeIsSymlink(w2)) {
|
|
65927
65953
|
if (isOurWrapper(w2)) {
|
|
65928
|
-
|
|
65954
|
+
rmSync7(w2);
|
|
65929
65955
|
actions.push(`removed wrapper ${w2}`);
|
|
65930
65956
|
if (state.launcher_restore?.kind === "symlink") {
|
|
65931
65957
|
symlinkSync2(state.launcher_restore.target, w2);
|
|
@@ -65940,11 +65966,11 @@ function revertLocked(ctx) {
|
|
|
65940
65966
|
removeGenerations(ctx, actions);
|
|
65941
65967
|
removeStagingDebris(ctx, actions);
|
|
65942
65968
|
if (existsSync15(ctx.paths.patchedBin)) {
|
|
65943
|
-
|
|
65969
|
+
rmSync7(ctx.paths.patchedBin);
|
|
65944
65970
|
actions.push(`removed patched binary ${ctx.paths.patchedBin}`);
|
|
65945
65971
|
}
|
|
65946
65972
|
if (existsSync15(ctx.paths.patchedCodeModeHost)) {
|
|
65947
|
-
|
|
65973
|
+
rmSync7(ctx.paths.patchedCodeModeHost);
|
|
65948
65974
|
actions.push(`removed Code Mode host ${ctx.paths.patchedCodeModeHost}`);
|
|
65949
65975
|
}
|
|
65950
65976
|
try {
|
|
@@ -68465,6 +68491,154 @@ function readMemoryUsage(deps, nowMs) {
|
|
|
68465
68491
|
}
|
|
68466
68492
|
}
|
|
68467
68493
|
|
|
68494
|
+
// src/commands/update-tool.ts
|
|
68495
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
68496
|
+
import { existsSync as existsSync17, realpathSync as realpathSync4 } from "node:fs";
|
|
68497
|
+
import { dirname as dirname11, join as join23 } from "node:path";
|
|
68498
|
+
async function defaultFetchLatestVersion() {
|
|
68499
|
+
const controller = new AbortController;
|
|
68500
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
68501
|
+
try {
|
|
68502
|
+
const res = await fetch("https://registry.npmjs.org/cxstatusline/latest", {
|
|
68503
|
+
headers: { Accept: "application/json" },
|
|
68504
|
+
signal: controller.signal
|
|
68505
|
+
});
|
|
68506
|
+
if (!res.ok)
|
|
68507
|
+
return null;
|
|
68508
|
+
const data = await res.json();
|
|
68509
|
+
return typeof data.version === "string" ? data.version : null;
|
|
68510
|
+
} catch {
|
|
68511
|
+
return null;
|
|
68512
|
+
} finally {
|
|
68513
|
+
clearTimeout(timer);
|
|
68514
|
+
}
|
|
68515
|
+
}
|
|
68516
|
+
function detectInstallType(binaryPath = process.argv[1]) {
|
|
68517
|
+
if (!binaryPath)
|
|
68518
|
+
return { type: "npm" };
|
|
68519
|
+
try {
|
|
68520
|
+
let resolved = binaryPath;
|
|
68521
|
+
try {
|
|
68522
|
+
resolved = realpathSync4(binaryPath);
|
|
68523
|
+
} catch {}
|
|
68524
|
+
let dir = dirname11(resolved);
|
|
68525
|
+
for (let i = 0;i < 5; i++) {
|
|
68526
|
+
if (existsSync17(join23(dir, ".git")) && existsSync17(join23(dir, "package.json"))) {
|
|
68527
|
+
return { type: "git", repoDir: dir };
|
|
68528
|
+
}
|
|
68529
|
+
const parent = dirname11(dir);
|
|
68530
|
+
if (parent === dir)
|
|
68531
|
+
break;
|
|
68532
|
+
dir = parent;
|
|
68533
|
+
}
|
|
68534
|
+
if (binaryPath.includes(".bun") || resolved.includes(".bun")) {
|
|
68535
|
+
return { type: "bun" };
|
|
68536
|
+
}
|
|
68537
|
+
if (binaryPath.includes("pnpm") || resolved.includes("pnpm")) {
|
|
68538
|
+
return { type: "pnpm" };
|
|
68539
|
+
}
|
|
68540
|
+
} catch {}
|
|
68541
|
+
return { type: "npm" };
|
|
68542
|
+
}
|
|
68543
|
+
function defaultExecCommand(cmd, args) {
|
|
68544
|
+
const res = spawnSync5(cmd, args, { encoding: "utf8" });
|
|
68545
|
+
return {
|
|
68546
|
+
status: res.status ?? (res.error ? 1 : 0),
|
|
68547
|
+
stdout: res.stdout || "",
|
|
68548
|
+
stderr: res.stderr || (res.error ? res.error.message : "")
|
|
68549
|
+
};
|
|
68550
|
+
}
|
|
68551
|
+
async function runUpdateTool(flags, io2, deps = {}) {
|
|
68552
|
+
const checkOnly = flags.includes("--check");
|
|
68553
|
+
const currentVersionStr = deps.currentVersion ?? VERSION;
|
|
68554
|
+
const currentSemver = parseSemver(currentVersionStr);
|
|
68555
|
+
if (!currentSemver) {
|
|
68556
|
+
io2.stderr(`Invalid current version: ${currentVersionStr}
|
|
68557
|
+
`);
|
|
68558
|
+
return 1;
|
|
68559
|
+
}
|
|
68560
|
+
io2.stdout(`Checking for cxstatusline updates...
|
|
68561
|
+
`);
|
|
68562
|
+
const fetcher = deps.fetchLatestVersion ?? defaultFetchLatestVersion;
|
|
68563
|
+
const latest = await fetcher();
|
|
68564
|
+
if (!latest) {
|
|
68565
|
+
io2.stderr(`Failed to check for updates: could not reach npm registry.
|
|
68566
|
+
`);
|
|
68567
|
+
return 1;
|
|
68568
|
+
}
|
|
68569
|
+
const latestSemver = parseSemver(latest);
|
|
68570
|
+
if (!latestSemver) {
|
|
68571
|
+
io2.stderr(`Invalid version received from registry: ${latest}
|
|
68572
|
+
`);
|
|
68573
|
+
return 1;
|
|
68574
|
+
}
|
|
68575
|
+
if (compareSemver(latestSemver, currentSemver) <= 0) {
|
|
68576
|
+
io2.stdout(`cxstatusline is already up to date (${currentVersionStr}).
|
|
68577
|
+
`);
|
|
68578
|
+
return 0;
|
|
68579
|
+
}
|
|
68580
|
+
if (checkOnly) {
|
|
68581
|
+
io2.stdout(`Update available: ${currentVersionStr} -> ${latest}
|
|
68582
|
+
`);
|
|
68583
|
+
io2.stdout("Run `cxstatusline update` to upgrade the tool.\n");
|
|
68584
|
+
return 0;
|
|
68585
|
+
}
|
|
68586
|
+
const detector = deps.detectInstallType ?? (() => detectInstallType());
|
|
68587
|
+
const installInfo = detector();
|
|
68588
|
+
const exec2 = deps.execCommand ?? defaultExecCommand;
|
|
68589
|
+
if (installInfo.type === "git" && installInfo.repoDir) {
|
|
68590
|
+
io2.stdout(`Updating cxstatusline from git repository at ${installInfo.repoDir}...
|
|
68591
|
+
`);
|
|
68592
|
+
const pull2 = exec2("git", ["-C", installInfo.repoDir, "pull", "origin", "main"]);
|
|
68593
|
+
if (pull2.status !== 0) {
|
|
68594
|
+
io2.stderr(`Failed to update cxstatusline via git pull:
|
|
68595
|
+
${pull2.stderr || pull2.stdout}
|
|
68596
|
+
`);
|
|
68597
|
+
return 1;
|
|
68598
|
+
}
|
|
68599
|
+
const install2 = exec2("bun", ["--cwd", installInfo.repoDir, "install", "--frozen-lockfile"]);
|
|
68600
|
+
if (install2.status !== 0) {
|
|
68601
|
+
io2.stderr(`Failed to run bun install in repo:
|
|
68602
|
+
${install2.stderr || install2.stdout}
|
|
68603
|
+
`);
|
|
68604
|
+
return 1;
|
|
68605
|
+
}
|
|
68606
|
+
const build = exec2("bun", ["--cwd", installInfo.repoDir, "run", "build"]);
|
|
68607
|
+
if (build.status !== 0) {
|
|
68608
|
+
io2.stderr(`Failed to build cxstatusline in repo:
|
|
68609
|
+
${build.stderr || build.stdout}
|
|
68610
|
+
`);
|
|
68611
|
+
return 1;
|
|
68612
|
+
}
|
|
68613
|
+
io2.stdout(`Successfully updated cxstatusline from git checkout.
|
|
68614
|
+
`);
|
|
68615
|
+
return 0;
|
|
68616
|
+
}
|
|
68617
|
+
let command = "npm";
|
|
68618
|
+
let args = ["install", "-g", "cxstatusline@latest"];
|
|
68619
|
+
if (installInfo.type === "bun") {
|
|
68620
|
+
command = "bun";
|
|
68621
|
+
args = ["add", "-g", "cxstatusline@latest"];
|
|
68622
|
+
} else if (installInfo.type === "pnpm") {
|
|
68623
|
+
command = "pnpm";
|
|
68624
|
+
args = ["add", "-g", "cxstatusline@latest"];
|
|
68625
|
+
}
|
|
68626
|
+
io2.stdout(`Updating cxstatusline via ${command} (${command} ${args.join(" ")})...
|
|
68627
|
+
`);
|
|
68628
|
+
const result2 = exec2(command, args);
|
|
68629
|
+
if (result2.status !== 0) {
|
|
68630
|
+
io2.stderr(`Failed to update cxstatusline:
|
|
68631
|
+
${result2.stderr || result2.stdout}
|
|
68632
|
+
`);
|
|
68633
|
+
io2.stderr(`You can try updating manually with: ${command} ${args.join(" ")}
|
|
68634
|
+
`);
|
|
68635
|
+
return 1;
|
|
68636
|
+
}
|
|
68637
|
+
io2.stdout(`Successfully updated cxstatusline to ${latest}.
|
|
68638
|
+
`);
|
|
68639
|
+
return 0;
|
|
68640
|
+
}
|
|
68641
|
+
|
|
68468
68642
|
// src/main.ts
|
|
68469
68643
|
var USAGE = `usage: cxstatusline [command]
|
|
68470
68644
|
|
|
@@ -68474,7 +68648,8 @@ var USAGE = `usage: cxstatusline [command]
|
|
|
68474
68648
|
install the published Codex pair (--compile builds it from source)
|
|
68475
68649
|
patch [--force] build and install the patched Codex from source
|
|
68476
68650
|
patch --simulate-drift <v> record <v> as the installed version so the next session sees drift
|
|
68477
|
-
update [--
|
|
68651
|
+
update [--check] update cxstatusline tool to the latest version
|
|
68652
|
+
upgrade [--compile|--force] upgrade the patched Codex pair to the latest supported version
|
|
68478
68653
|
hook [install|uninstall] manage the SessionStart entry; bare 'hook' is what Codex runs
|
|
68479
68654
|
doctor report toolchain, drift, hook and wrapper state
|
|
68480
68655
|
policy [get|set <policy>] view or update policy (every, stable-minors, manual)
|
|
@@ -68617,12 +68792,44 @@ async function installCommand(argv, io2, deps) {
|
|
|
68617
68792
|
return runInstall(ctx, { compile: compile3, codexVersion }, deps.transport);
|
|
68618
68793
|
}
|
|
68619
68794
|
async function updateCommand(argv, io2, deps) {
|
|
68795
|
+
const flags = argv.slice(1);
|
|
68796
|
+
const codexFlags = new Set(["--compile", "--force", "-y", "--yes"]);
|
|
68797
|
+
if (flags.some((f2) => codexFlags.has(f2) || f2.startsWith("--codex-version"))) {
|
|
68798
|
+
io2.stdout(`Notice: 'cxstatusline upgrade' is now used to upgrade the patched Codex pair.
|
|
68799
|
+
Forwarding to 'upgrade'...
|
|
68800
|
+
|
|
68801
|
+
`);
|
|
68802
|
+
return upgradeCommand(argv, io2, deps);
|
|
68803
|
+
}
|
|
68804
|
+
const allowed = new Set(["--check", "-h", "--help"]);
|
|
68805
|
+
if (flags.some((f2) => !allowed.has(f2))) {
|
|
68806
|
+
io2.stderr(USAGE);
|
|
68807
|
+
return 2;
|
|
68808
|
+
}
|
|
68809
|
+
const updater = deps.updateTool ?? runUpdateTool;
|
|
68810
|
+
return updater(flags, io2, { fetchLatestVersion: deps.fetchLatestToolVersion });
|
|
68811
|
+
}
|
|
68812
|
+
async function upgradeCommand(argv, io2, deps) {
|
|
68620
68813
|
const flags = argv.slice(1);
|
|
68621
68814
|
const allowed = new Set(["--compile", "--force", "-y", "--yes"]);
|
|
68622
68815
|
if (flags.some((f2) => !allowed.has(f2))) {
|
|
68623
68816
|
io2.stderr(USAGE);
|
|
68624
68817
|
return 2;
|
|
68625
68818
|
}
|
|
68819
|
+
try {
|
|
68820
|
+
const latest = await (deps.fetchLatestToolVersion ?? defaultFetchLatestVersion)();
|
|
68821
|
+
if (latest) {
|
|
68822
|
+
const parsedLatest = parseSemver(latest);
|
|
68823
|
+
const parsedCurrent = parseSemver(VERSION);
|
|
68824
|
+
if (parsedLatest && parsedCurrent && compareSemver(parsedLatest, parsedCurrent) === 1) {
|
|
68825
|
+
io2.stdout(`
|
|
68826
|
+
\uD83D\uDCA1 Note: A newer version of cxstatusline is available (${VERSION} → ${latest}).
|
|
68827
|
+
Run 'cxstatusline update' to update the tool for the newest Codex patches.
|
|
68828
|
+
|
|
68829
|
+
`);
|
|
68830
|
+
}
|
|
68831
|
+
}
|
|
68832
|
+
} catch {}
|
|
68626
68833
|
return runUpdate(contextFor(io2, deps), {
|
|
68627
68834
|
compile: flags.includes("--compile"),
|
|
68628
68835
|
force: flags.includes("--force") || flags.includes("-y") || flags.includes("--yes"),
|
|
@@ -68693,6 +68900,8 @@ async function main(argv, io2, deps = {}) {
|
|
|
68693
68900
|
return patchCommand(argv, io2, deps);
|
|
68694
68901
|
if (cmd === "update")
|
|
68695
68902
|
return updateCommand(argv, io2, deps);
|
|
68903
|
+
if (cmd === "upgrade")
|
|
68904
|
+
return upgradeCommand(argv, io2, deps);
|
|
68696
68905
|
if (cmd === "install")
|
|
68697
68906
|
return installCommand(argv, io2, deps);
|
|
68698
68907
|
if (cmd === "hook" && (argv[1] === "install" || argv[1] === "uninstall")) {
|