refactor(codex): rename context-codex #2

Merged
eleith merged 1 commits from refactor/codex-rename into main 2026-10-31 01:39:39 +00:00
19 changed files with 84 additions and 67 deletions

No files matched your search

@@ -1,13 +1,13 @@
name: "@eleith-pi/context-codex"
name: "@eleith-pi/codex"
on:
push:
branches: [main]
tags: ["@eleith-pi/context-codex@*"]
tags: ["@eleith-pi/codex@*"]
paths:
- extensions/context-codex/**
- extensions/codex/**
- packages/internal/**
- .github/workflows/context-codex.yml
- .github/workflows/codex.yml
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
@@ -20,9 +20,9 @@ on:
pull_request:
branches: [main]
paths:
- extensions/context-codex/**
- extensions/codex/**
- packages/internal/**
- .github/workflows/context-codex.yml
- .github/workflows/codex.yml
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
@@ -62,22 +62,22 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Check formatting
run: pnpm exec oxfmt --check extensions/context-codex packages/internal .github/workflows/context-codex.yml package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json .oxlintrc.json .oxfmtrc.json .editorconfig .gitignore .changeset/config.json
run: pnpm exec oxfmt --check extensions/codex packages/internal .github/workflows/codex.yml package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json .oxlintrc.json .oxfmtrc.json .editorconfig .gitignore .changeset/config.json
- name: Lint and typecheck
run: |
pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal lint
pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal check
pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal lint
pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal check
- name: Test
run: pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal test
run: pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal test
- name: Build
run: pnpm --filter @eleith-pi/context-codex build
run: pnpm --filter @eleith-pi/codex build
publish:
needs: check
if: github.ref_type == 'tag' && startsWith(github.ref_name, '@eleith-pi/context-codex@')
if: github.ref_type == 'tag' && startsWith(github.ref_name, '@eleith-pi/codex@')
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
@@ -102,8 +102,8 @@ jobs:
RELEASE_TAG: ${{ github.ref_name }}
run: |
set -eu
PACKAGE_NAME=$(node -p "require('./extensions/context-codex/package.json').name")
VERSION=$(node -p "require('./extensions/context-codex/package.json').version")
PACKAGE_NAME=$(node -p "require('./extensions/codex/package.json').name")
VERSION=$(node -p "require('./extensions/codex/package.json').version")
if [ "$RELEASE_TAG" != "$PACKAGE_NAME@$VERSION" ]; then
echo "Version mismatch: tag $RELEASE_TAG does not match $PACKAGE_NAME@$VERSION"
exit 1
@@ -117,7 +117,7 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm --filter @eleith-pi/context-codex build
run: pnpm --filter @eleith-pi/codex build
- name: Check npm version
id: registry_version
@@ -125,16 +125,16 @@ jobs:
NPM_CONFIG_USERCONFIG: /dev/null
run: |
set -eu
VERSION=$(node -p "require('./extensions/context-codex/package.json').version")
VERSION=$(node -p "require('./extensions/codex/package.json').version")
mkdir -p .cache
if npm view "@eleith-pi/context-codex@$VERSION" version --json --registry=https://registry.npmjs.org/ > .cache/context-codex-npm.json 2>/dev/null; then
echo "@eleith-pi/context-codex@$VERSION is already published; skipping"
if npm view "@eleith-pi/codex@$VERSION" version --json --registry=https://registry.npmjs.org/ > .cache/codex-npm.json 2>/dev/null; then
echo "@eleith-pi/codex@$VERSION is already published; skipping"
echo "published=true" >> "$GITHUB_OUTPUT"
else
node -e 'const result = require("./.cache/context-codex-npm.json"); if (result.error?.code !== "E404") throw new Error("Registry lookup failed; refusing to publish");'
node -e 'const result = require("./.cache/codex-npm.json"); if (result.error?.code !== "E404") throw new Error("Registry lookup failed; refusing to publish");'
echo "published=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish to npm
if: steps.registry_version.outputs.published == 'false'
run: pnpm --filter @eleith-pi/context-codex publish --registry=https://registry.npmjs.org/ --access public --no-git-checks
run: pnpm --filter @eleith-pi/codex publish --registry=https://registry.npmjs.org/ --access public --no-git-checks
@@ -3,9 +3,9 @@ when:
branch: main
path:
include:
- extensions/context-codex/**
- extensions/codex/**
- packages/internal/**
- .woodpecker/context-codex.yml
- .woodpecker/codex.yml
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
@@ -19,9 +19,9 @@ when:
- event: pull_request
path:
include:
- extensions/context-codex/**
- extensions/codex/**
- packages/internal/**
- .woodpecker/context-codex.yml
- .woodpecker/codex.yml
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
@@ -34,7 +34,7 @@ when:
on_empty: false
- event: tag
ref: "refs/tags/@eleith-pi/context-codex@*"
ref: "refs/tags/@eleith-pi/codex@*"
workspace:
base: /workspace
@@ -60,10 +60,10 @@ steps:
commands:
- npm install --global corepack@latest
- corepack enable
- pnpm exec oxfmt --check extensions/context-codex packages/internal .woodpecker/context-codex.yml package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json .oxlintrc.json .oxfmtrc.json .editorconfig .gitignore .changeset/config.json
- pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal lint
- pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal check
- pnpm --filter @eleith-pi/context-codex --filter @eleith/pi-internal test
- pnpm exec oxfmt --check extensions/codex packages/internal .woodpecker/codex.yml package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json .oxlintrc.json .oxfmtrc.json .editorconfig .gitignore .changeset/config.json
- pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal lint
- pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal check
- pnpm --filter @eleith-pi/codex --filter @eleith/pi-internal test
build:
image: node:26
@@ -72,22 +72,22 @@ steps:
commands:
- npm install --global corepack@latest
- corepack enable
- pnpm --filter @eleith-pi/context-codex build
- pnpm --filter @eleith-pi/codex build
check-version:
image: node:26
commands:
- |
set -eu
VERSION_FROM_TAG="$${CI_COMMIT_TAG#@eleith-pi/context-codex@}"
VERSION_FROM_PKG="$$(node -p "require('./extensions/context-codex/package.json').version")"
VERSION_FROM_TAG="$${CI_COMMIT_TAG#@eleith-pi/codex@}"
VERSION_FROM_PKG="$$(node -p "require('./extensions/codex/package.json').version")"
if [ "$${VERSION_FROM_TAG}" != "$${VERSION_FROM_PKG}" ]; then
echo "Version mismatch: Git tag version $${VERSION_FROM_TAG} does not match extensions/context-codex/package.json version: $${VERSION_FROM_PKG}"
echo "Version mismatch: Git tag version $${VERSION_FROM_TAG} does not match extensions/codex/package.json version: $${VERSION_FROM_PKG}"
exit 1
fi
if [ "$${VERSION_FROM_PKG}" = "0.0.0" ]; then
echo "Refusing to publish @eleith-pi/context-codex at placeholder version 0.0.0"
echo "Refusing to publish @eleith-pi/codex at placeholder version 0.0.0"
exit 1
fi
when:
@@ -97,7 +97,7 @@ steps:
image: node:26
environment:
COREPACK_HOME: /workspace/src/.corepack
NPM_CONFIG_USERCONFIG: /workspace/src/.cache/context-codex-publish.npmrc
NPM_CONFIG_USERCONFIG: /workspace/src/.cache/codex-publish.npmrc
NPM_TOKEN:
from_secret: gitea_npm_token
commands:
@@ -106,18 +106,18 @@ steps:
- |
set -eu
test -n "$${NPM_TOKEN}"
VERSION="$$(node -p "require('./extensions/context-codex/package.json').version")"
VERSION="$$(node -p "require('./extensions/codex/package.json').version")"
umask 077
mkdir -p .cache
trap 'rm -f "$${NPM_CONFIG_USERCONFIG}"' EXIT
printf '%s\n' '//git.eleith.com/api/packages/eleith.private/npm/:_authToken=$${NPM_TOKEN}' > "$${NPM_CONFIG_USERCONFIG}"
if npm view "@eleith-pi/context-codex@$${VERSION}" version --json --registry=https://git.eleith.com/api/packages/eleith.private/npm/ > .cache/context-codex-registry.json 2>/dev/null; then
echo "@eleith-pi/context-codex@$${VERSION} is already published; skipping"
if npm view "@eleith-pi/codex@$${VERSION}" version --json --registry=https://git.eleith.com/api/packages/eleith.private/npm/ > .cache/codex-registry.json 2>/dev/null; then
echo "@eleith-pi/codex@$${VERSION} is already published; skipping"
exit 0
fi
node -e 'const result = require("./.cache/context-codex-registry.json"); if (result.error?.code !== "E404") throw new Error("Registry lookup failed; refusing to publish");'
pnpm --filter @eleith-pi/context-codex publish --registry=https://git.eleith.com/api/packages/eleith.private/npm/ --no-git-checks
node -e 'const result = require("./.cache/codex-registry.json"); if (result.error?.code !== "E404") throw new Error("Registry lookup failed; refusing to publish");'
pnpm --filter @eleith-pi/codex publish --registry=https://git.eleith.com/api/packages/eleith.private/npm/ --no-git-checks
when:
- event: tag
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,5 +1,5 @@
{
"name": "@eleith-pi/context-codex",
"name": "@eleith-pi/codex",
"version": "0.1.1",
"private": false,
"description": "Extend or restore context windows for supported Codex models",
@@ -10,7 +10,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/eleith/pi-extensions.git",
"directory": "extensions/context-codex"
"directory": "extensions/codex"
},
"files": [
"dist/index.js",
@@ -145,7 +145,7 @@ function fixture(catalog = model()) {
state.branch.push(entry(data, customType));
}),
} satisfies ContextAPI;
const controller = new ContextController(api, "personal:context-codex");
const controller = new ContextController(api, "personal:codex");
return {
catalog,
state,
@@ -794,7 +794,7 @@ describe("ContextController", () => {
const f = fixture();
await f.controller.handle("extend", f.ctx);
f.controller.shutdown();
const controller = new ContextController(f.api, "personal:context-codex");
const controller = new ContextController(f.api, "personal:codex");
await controller.restore(f.ctx);
expect(f.state.current?.contextWindow).toBe(922_000);
await controller.handle("restore", f.ctx);
@@ -2,13 +2,13 @@ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
import { afterAll, expect, it, vi } from "vitest";
import contextCodex from "./index.ts";
import codex from "./index.ts";
const directory = await vi.hoisted(async () => {
const { mkdtempSync } = await import("node:fs");
const { tmpdir } = await import("node:os");
const { join } = await import("node:path");
const directory = mkdtempSync(join(tmpdir(), "context-codex-test-"));
const directory = mkdtempSync(join(tmpdir(), "codex-test-"));
vi.stubEnv("PI_CODING_AGENT_DIR", directory);
vi.stubEnv("PI_OFFLINE", "1");
return directory;
@@ -52,7 +52,7 @@ async function load(prefix = "eleith") {
ui: { notify, confirm: vi.fn(async () => false) },
sessionManager: { getBranch: () => [], getSessionId: () => "session", getLeafId: () => null },
} as unknown as ExtensionCommandContext;
await contextCodex(pi as unknown as ExtensionAPI);
await codex(pi as unknown as ExtensionAPI);
return {
pi,
ctx,
@@ -75,7 +75,7 @@ it("registers only the configured native command once after binding", async () =
await context.emit("session_start");
await context.emit("session_start");
expect(context.pi.registerCommand).toHaveBeenCalledTimes(1);
expect(context.pi.registerCommand.mock.calls[0]?.[0]).toBe("personal:context-codex");
expect(context.pi.registerCommand.mock.calls[0]?.[0]).toBe("personal:codex");
expect(await context.command().getArgumentCompletions?.("e")).toEqual([
{ value: "extend", label: "extend" },
]);
@@ -93,7 +93,7 @@ it("handles no argument as status rather than an invalid default action", async
expect(context.pi.setModel).not.toHaveBeenCalled();
await context.command().handler("extend restore", context.ctx);
expect(context.notify).toHaveBeenLastCalledWith(
"Usage: /eleith:context-codex [extend|restore]",
"Usage: /eleith:codex [extend|restore]",
"warning",
);
});
@@ -117,7 +117,7 @@ it("fails invalid prefix settings before registering any capabilities", async ()
writeFileSync(configPath, '{"commandPrefix":"Invalid Prefix"}');
const on = vi.fn(),
registerCommand = vi.fn();
await expect(contextCodex({ on, registerCommand } as unknown as ExtensionAPI)).rejects.toThrow(
await expect(codex({ on, registerCommand } as unknown as ExtensionAPI)).rejects.toThrow(
configPath,
);
expect(on).not.toHaveBeenCalled();
@@ -3,9 +3,9 @@ import { registerCommand } from "@eleith/pi-internal/commands";
import { getSettings } from "@eleith/pi-internal/config";
import { ContextController } from "./controller.ts";
export default async function contextCodex(pi: ExtensionAPI): Promise<void> {
export default async function codex(pi: ExtensionAPI): Promise<void> {
const settings = await getSettings();
const commandName = `${settings.commandPrefix}:context-codex`;
const commandName = `${settings.commandPrefix}:codex`;
const controller = new ContextController(pi, commandName);
registerCommand(pi, {
File renamed without changes.
@@ -19,13 +19,13 @@ import {
type ExtensionContext,
type ExtensionUIContext,
} from "@earendil-works/pi-coding-agent";
import contextCodex from "./index.ts";
import codex from "./index.ts";
const directory = await vi.hoisted(async () => {
const { mkdtempSync } = await import("node:fs");
const { tmpdir } = await import("node:os");
const { join } = await import("node:path");
const directory = mkdtempSync(join(tmpdir(), "context-codex-sdk-test-"));
const directory = mkdtempSync(join(tmpdir(), "codex-sdk-test-"));
vi.stubEnv("PI_CODING_AGENT_DIR", directory);
vi.stubEnv("PI_OFFLINE", "1");
return directory;
@@ -97,7 +97,7 @@ async function fixture(window = 272_000, modelId = "gpt-6-sol") {
noThemes: true,
noContextFiles: true,
extensionFactories: [
contextCodex,
codex,
(pi) => {
pi.on("model_select", modelSelect);
pi.on("input", (_event, ctx) => {
@@ -180,7 +180,7 @@ it.each([
const original = structuredClone(f.catalog);
try {
const leaf = f.manager.getLeafId();
await f.session.prompt("/eleith:context-codex extend");
await f.session.prompt("/eleith:codex extend");
const extended = f.session.model!;
expect(extended.contextWindow).toBe(Math.max(window, 922_000));
if (window < 922_000) {
@@ -194,7 +194,7 @@ it.each([
await f.session.reload();
expect(f.session.model?.contextWindow).toBe(Math.max(window, 922_000));
expect(f.registry.find("openai-codex", modelId)?.contextWindow).toBe(window);
await f.session.prompt("/eleith:context-codex restore");
await f.session.prompt("/eleith:codex restore");
expect(f.session.model?.contextWindow).toBe(window);
expect(extended.contextWindow).toBe(Math.max(window, 922_000));
expect(f.catalog).toEqual(original);
@@ -216,6 +216,23 @@ it.each([
},
);
it("SDK replays a saved context preference after the command rename", async () => {
const f = await fixture();
const saved = { provider: "openai-codex", modelId: "gpt-6-sol", extended: true };
try {
f.manager.appendCustomEntry("eleith-context", saved);
await f.session.reload();
expect(f.session.model?.contextWindow).toBe(922_000);
expect(f.preferences()).toEqual([saved]);
await f.session.prompt("/eleith:codex restore");
expect(f.session.model?.contextWindow).toBe(272_000);
expect(f.preferences()).toEqual([saved, { ...saved, extended: false }]);
} finally {
await f.cleanup();
}
});
it.each(["rename", "external"])(
"SDK delayed auth with %s warns without repair, thinking rewrite, success records, or replay",
async (event) => {
@@ -240,7 +257,7 @@ it.each(["rename", "external"])(
});
const selection = vi.spyOn(f.session, "setModel");
try {
const request = f.session.prompt("/eleith:context-codex extend");
const request = f.session.prompt("/eleith:codex extend");
await started;
const submitted = selection.mock.calls[0][0];
const originalSubmitted = structuredClone(submitted);
@@ -267,7 +284,7 @@ it.each(["rename", "external"])(
expect(thinkingWrites).not.toHaveBeenCalled();
expect(f.session.thinkingLevel).toBe(thinking);
// Only an explicit context-changing command resumes work.
await f.session.prompt("/eleith:context-codex restore");
await f.session.prompt("/eleith:codex restore");
expect(f.session.model?.contextWindow).toBe(272_000);
expect(f.preferences()).toEqual([
{ provider: "openai-codex", modelId: "gpt-6-sol", extended: false },
@@ -287,14 +304,14 @@ it.each(["missing", "endpoint"])(
async (reason) => {
const f = await fixture();
try {
await f.session.prompt("/eleith:context-codex extend");
await f.session.prompt("/eleith:codex extend");
const lookup = vi
.spyOn(f.registry, "find")
.mockReturnValue(
reason === "missing" ? undefined : { ...f.catalog, baseUrl: "https://different.invalid" },
);
const select = vi.spyOn(f.session, "setModel");
await f.session.prompt("/eleith:context-codex restore");
await f.session.prompt("/eleith:codex restore");
expect(select).not.toHaveBeenCalled();
expect(f.session.model?.contextWindow).toBe(922_000);
expect(f.confirm).not.toHaveBeenCalled();
@@ -342,9 +359,9 @@ it.each(["user", "custom"] as const)(
return stream;
});
try {
await f.session.prompt("/eleith:context-codex extend");
await f.session.prompt("/eleith:codex extend");
const extendedLeaf = f.manager.getLeafId()!;
await f.session.prompt("/eleith:context-codex restore");
await f.session.prompt("/eleith:codex restore");
expect(f.session.model?.contextWindow).toBe(272_000);
expect(f.confirm).toHaveBeenCalledTimes(1);
File renamed without changes.
@@ -83,7 +83,7 @@ describe("context status windows", () => {
};
const original = structuredClone(current);
const report = formatContextStatus(current, NOW);
expect(report).toContain("context-codex · openai-codex/gpt-6-sol");
expect(report).toContain("codex · openai-codex/gpt-6-sol");
expect(report).toMatch(/^ Usage +12k \/ 922k$/m);
expect(report).toMatch(/^ Standard +272k$/m);
expect(report).toMatch(/^ Extended +922k \(local window\)$/m);
@@ -90,7 +90,7 @@ export function formatContextStatus(status: ContextStatus, now = Date.now()): st
const { model, usage, standardWindow, extendedWindow, branch, desiredExtended, replayPaused } =
status;
const lines = [
`context-codex · ${modelKey(model)}`,
`codex · ${modelKey(model)}`,
"",
" window",
row(
File renamed without changes.
+2 -2
View File
@@ -39,13 +39,13 @@ importers:
specifier: 4.1.11
version: 4.1.11(@types/node@22.19.19)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1)
extensions/compact-editor-chrome:
extensions/codex:
devDependencies:
'@eleith/pi-internal':
specifier: workspace:*
version: link:../../packages/internal
extensions/context-codex:
extensions/compact-editor-chrome:
devDependencies:
'@eleith/pi-internal':
specifier: workspace:*