Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 000 — `--restart-codex` misses `codex.opencodex-real` shim backup binaries

## The report

On remote hosts where Codex autostart shim is installed (`~/.local/bin/codex`), running `ocx sync --restart-codex`
reports zero app-server processes stopped, leaving long-lived app-servers holding stale in-memory model catalogs.

## What is actually running there

`ps -ef` on the affected host:

```text
ubuntu 3600609 1 0 04:35 ? /home/ubuntu/.local/bin/codex.opencodex-real -c features.code_mode_host=true app-server --listen unix://
```

## The defect

`isCodexExecutableToken` in `src/codex/app-server-processes.ts` checked only `codex`, `codex.exe`, `codex.cmd`,
and Rust target triples. When the autostart shim moves the original launcher to `codex.opencodex-real`,
the process command line starts with `codex.opencodex-real` and fails `isCodexExecutableToken`, so `--restart-codex`
ignores it entirely.

## The fix

Admit `codex.opencodex-real`, `codex.opencodex-real.exe`, and `codex.opencodex-real.cmd` in `isCodexExecutableToken`
and in `WINDOWS_CODEX_BASENAME_CANDIDATE_RE`.
4 changes: 3 additions & 1 deletion src/codex/app-server-processes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const CODEX_TARGET_TRIPLE_BODY = "[a-z0-9_]+-[a-z0-9_]+-[a-z0-9_]+(?:-[a-z0-9_]+
* `codex-x86_64-pc-windows-msvc.exe`.
*/
export const WINDOWS_CODEX_BASENAME_CANDIDATE_RE = new RegExp(
`(^|[/\\\\\\s'"=])codex(-${CODEX_TARGET_TRIPLE_BODY})?([.]exe|[.]cmd)?['"]?(\\s|$)`,
`(^|[/\\\\\\s'"=])codex([.]opencodex-real)?(-${CODEX_TARGET_TRIPLE_BODY})?([.]exe|[.]cmd)?['"]?(\\s|$)`,
"i",
);

Expand Down Expand Up @@ -159,6 +159,8 @@ function tokenBasename(token: string): string {
function isCodexExecutableToken(token: string): boolean {
const base = tokenBasename(token);
return base === "codex" || base === "codex.exe" || base === "codex.cmd"
|| base === "codex.opencodex-real" || base === "codex.opencodex-real.exe"
|| base === "codex.opencodex-real.cmd"
|| CODEX_TARGET_TRIPLE_BASENAME_RE.test(base);
}

Expand Down
18 changes: 18 additions & 0 deletions tests/codex-app-server-processes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,18 @@ describe("Codex app-server process matching (#476)", () => {
});


test("matches codex.opencodex-real launcher backup binaries and wrappers", () => {
expect(isCodexAppServerCommandLine("/home/ubuntu/.local/bin/codex.opencodex-real app-server proxy")).toBe(true);
expect(isCodexAppServerCommandLine(
"/home/ubuntu/.local/bin/codex.opencodex-real -c features.code_mode_host=true app-server --listen unix://",
)).toBe(true);
expect(isCodexAppServerCommandLine("C:\\Users\\a\\AppData\\codex.opencodex-real.exe app-server --listen pipe")).toBe(true);
expect(isCodexAppServerCommandLine("\"C:\\Program Files\\nodejs\\codex.opencodex-real.cmd\" app-server")).toBe(true);
expect(isCodexAppServerCommandLine("node /usr/local/bin/codex.opencodex-real app-server proxy")).toBe(true);
expect(isCodexAppServerCommandLine("codex.opencodex-real exec 'hello'")).toBe(false);
expect(isCodexAppServerCommandLine("node worker.js codex.opencodex-real app-server")).toBe(false);
});

test("matches the npm wrapper that supervises the native app-server", () => {
// The shape that made `ocx sync --restart-codex` report a survivor on Linux. An
// npm-installed Codex runs as a PAIR: `node /usr/local/bin/codex app-server` and
Expand Down Expand Up @@ -492,6 +504,12 @@ describe("Codex app-server process matching (#476)", () => {
expect(isWindowsCodexCandidateCommandLine(
"C:\\Users\\a\\.codex\\bin\\codex-aarch64-pc-windows-msvc.exe app-server",
)).toBe(true);
expect(isWindowsCodexCandidateCommandLine(
"C:\\Users\\a\\.local\\bin\\codex.opencodex-real.exe app-server",
)).toBe(true);
expect(isWindowsCodexCandidateCommandLine(
"\"C:\\Program Files\\Codex\\codex.opencodex-real.cmd\" app-server",
)).toBe(true);
// Stay narrow: incidental "opencodex" paths must not pay GetOwner.
expect(isWindowsCodexCandidateCommandLine(
"node C:\\Users\\a\\opencodex\\src\\cli\\index.ts start",
Expand Down
Loading