Improve Codex App review URL discoverability (#966)

This commit is contained in:
Eric Clemmons
2026-06-24 23:10:43 -05:00
committed by GitHub
parent 63ed44e4a1
commit e5e3fea38c
2 changed files with 64 additions and 7 deletions
+58 -7
View File
@@ -2,7 +2,12 @@ import { describe, expect, test } from "bun:test";
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { handleSaveNotes, handleServerReady, writeServerReadyMetadata } from "./shared-handlers";
import {
handleSaveNotes,
handleServerReady,
isCodexDesktopHost,
writeServerReadyMetadata,
} from "./shared-handlers";
function saveNotesRequest(body: unknown): Request {
return new Request("http://localhost/api/save-notes", {
@@ -104,15 +109,30 @@ describe("writeServerReadyMetadata", () => {
});
describe("handleServerReady", () => {
test("detects the Codex Desktop app host", () => {
expect(isCodexDesktopHost({ __CFBundleIdentifier: "com.openai.codex" })).toBe(true);
expect(isCodexDesktopHost({ __CFBundleIdentifier: "com.apple.Terminal" })).toBe(false);
});
test("does not open a browser when host-plugin mode handles it", async () => {
let opened = false;
const originalBundleIdentifier = process.env.__CFBundleIdentifier;
process.env.__CFBundleIdentifier = "com.apple.Terminal";
await handleServerReady("http://localhost:12345", false, 12345, {
skipBrowserOpen: true,
openBrowser: async () => {
opened = true;
},
});
try {
await handleServerReady("http://localhost:12345", false, 12345, {
skipBrowserOpen: true,
openBrowser: async () => {
opened = true;
},
});
} finally {
if (originalBundleIdentifier === undefined) {
delete process.env.__CFBundleIdentifier;
} else {
process.env.__CFBundleIdentifier = originalBundleIdentifier;
}
}
expect(opened).toBe(false);
});
@@ -141,10 +161,12 @@ describe("handleServerReady", () => {
const writes: string[] = [];
let opened = "";
const original = process.stderr.write.bind(process.stderr);
const originalBundleIdentifier = process.env.__CFBundleIdentifier;
(process.stderr as { write: unknown }).write = (chunk: unknown) => {
writes.push(String(chunk));
return true;
};
process.env.__CFBundleIdentifier = "com.apple.Terminal";
try {
await handleServerReady("http://localhost:3000", false, 3000, {
openBrowser: async (u: string) => {
@@ -154,11 +176,40 @@ describe("handleServerReady", () => {
});
} finally {
(process.stderr as { write: unknown }).write = original;
if (originalBundleIdentifier === undefined) {
delete process.env.__CFBundleIdentifier;
} else {
process.env.__CFBundleIdentifier = originalBundleIdentifier;
}
}
expect(writes.join("")).not.toContain("http://localhost:3000");
expect(opened).toBe("http://localhost:3000");
});
test("prints the URL for a local Codex Desktop session even when the browser opens", async () => {
const writes: string[] = [];
const originalWrite = process.stderr.write.bind(process.stderr);
const originalBundleIdentifier = process.env.__CFBundleIdentifier;
(process.stderr as { write: unknown }).write = (chunk: unknown) => {
writes.push(String(chunk));
return true;
};
process.env.__CFBundleIdentifier = "com.openai.codex";
try {
await handleServerReady("http://localhost:3000", false, 3000, {
openBrowser: async () => true,
});
} finally {
(process.stderr as { write: unknown }).write = originalWrite;
if (originalBundleIdentifier === undefined) {
delete process.env.__CFBundleIdentifier;
} else {
process.env.__CFBundleIdentifier = originalBundleIdentifier;
}
}
expect(writes.join("")).toContain("http://localhost:3000");
});
// Regression: a local session whose browser can't be opened (headless box,
// devcontainer with no display) must still surface the URL, or the agent
// hangs at waitForDecision with the user having no link to visit.
+6
View File
@@ -177,6 +177,10 @@ export function writeServerReadyMetadata(readyFile: string, metadata: ServerRead
appendFileSync(readyFile, `${JSON.stringify(metadata)}\n`, "utf8");
}
export function isCodexDesktopHost(env: NodeJS.ProcessEnv = process.env): boolean {
return env.__CFBundleIdentifier === "com.openai.codex";
}
/** Attempt to open the browser for the session URL. */
export async function handleServerReady(
url: string,
@@ -203,6 +207,8 @@ export async function handleServerReady(
process.stderr.write(
`\n Plannotator session ready — open on your local machine (forward port ${port} if needed):\n ${url}\n\n`,
);
} else if (isCodexDesktopHost()) {
process.stderr.write(`\n Plannotator session ready:\n ${url}\n\n`);
}
const skipBrowserOpen = options.skipBrowserOpen ?? process.env.PLANNOTATOR_SKIP_BROWSER_OPEN === "1";