Fix Codex browser QA routing before standalone Playwright
@berkshirehathaways đang làm issue này rồi.
Từ ngày 2/8/2026.
- #6549 của @berkshirehathaways — đang mở
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- node.js, playwright
- Lĩnh vực
- developer-experience, tooling
Hướng nghiên cứu
Bắt đầu với node --test plugins/omo/test/debugging-browser-routing.test.mjs, sau đó đọc plugins/omo/skills/debugging/SKILL.md cùng các tài liệu tham chiếu của nó là references/methodology/02-investigate.md, references/methodology/08-qa.md và references/tools/playwright-cli.md. Cập nhật frontmatter liên quan đến định tuyến và hướng dẫn QA để Codex Browser với tab.playwright đứng trước Playwright độc lập, đồng thời xác nhận rằng bài kiểm thử hồi quy đã đạt.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem Situation
LazyCodex's general QA guidance prefers the bundled Codex Browser for unauthenticated browser work, but the debugging skill says Playwright CLI is mandatory. That conflict routes browser debugging to a separate Playwright session even when Codex Browser and its tab.playwright surface are available.
Reproduction Logs
Command:
node --test plugins/omo/test/debugging-browser-routing.test.mjs
Before the fix:
not ok 1 - #given the debugging skill #when its routing description is parsed #then Codex Browser precedes standalone Playwright
error: The input did not match the regular expression /browser:control-in-app-browser/.
1..1
# pass 0
# fail 1
Live runtime discovery independently confirmed that both Chrome and Codex In-app Browser were available and advertised CDP capability, so tool absence was not the cause.
Root Cause
plugins/omo/skills/debugging/SKILL.md and its Phase 8 references described Playwright CLI as the only acceptable real-browser QA path. They did not recognize the bundled Browser plugin's tab.playwright API as a Playwright-driven real-browser surface. This narrower rule overrode the Browser-first guidance already present in review-work and visual-qa.
Verified Fix
The patch makes the routing precedence explicit in the skill-picker-consumed frontmatter and all debugging QA references: Codex Browser plus tab.playwright first, standalone Playwright only when Browser is unavailable, lacks the required action, or an isolated browser process is specifically required. The regression test verifies only the minimal routing-bearing frontmatter tokens without snapshotting body prose.
diff --git a/plugins/omo/skills/debugging/SKILL.md b/plugins/omo/skills/debugging/SKILL.md
index 3baf0b4..6f1b5de 100644
--- a/plugins/omo/skills/debugging/SKILL.md
+++ b/plugins/omo/skills/debugging/SKILL.md
@@ -1,6 +1,6 @@
---
name: debugging
-description: "MUST USE for any real runtime debugging across ANY language or binary — crashes, silent failures, wrong responses, stuck processes, memory leaks, async misbehavior, unexplained timing, reverse engineering. Runs a hypothesis-driven loop: form ≥3 hypotheses, investigate in parallel, after 2 failed rounds spawn Oracles from orthogonal angles, confirm root cause, lock with a failing test, fix minimally, QA by actually USING the system, scrub artifacts. The actual HOW lives in `references/` — READ THEM. Triggers: 'debug this', 'why is X not working', 'hanging', 'attach a debugger', 'reverse engineer', 'pwndbg', 'gdb', 'lldb', 'node inspect', 'tsx debug', 'pdb', 'dlv', 'delve', 'rust-gdb', 'set a breakpoint', 'context window exploded', 'why is the response empty', 'why is this happening', 'trace this bug', 'reproduce and fix', 'silent failure', 'HTTP 200 but empty', 'why did it stop', 'inspect the binary', 'playwright', 'flaky test', 'fails intermittently', 'passes in isolation', 'only fails in CI'."
+description: "MUST USE for any real runtime debugging across ANY language or binary — crashes, silent failures, wrong responses, stuck processes, memory leaks, async misbehavior, unexplained timing, reverse engineering. Runs a hypothesis-driven loop: form ≥3 hypotheses, investigate in parallel, after 2 failed rounds spawn Oracles from orthogonal angles, confirm root cause, lock with a failing test, fix minimally, QA by actually USING the system, scrub artifacts. For browser UI bugs in Codex, route through browser:control-in-app-browser and its tab.playwright surface first; use standalone Playwright fallback only when that surface is unavailable or lacks the required capability. The actual HOW lives in `references/` — READ THEM. Triggers: 'debug this', 'why is X not working', 'hanging', 'attach a debugger', 'reverse engineer', 'pwndbg', 'gdb', 'lldb', 'node inspect', 'tsx debug', 'pdb', 'dlv', 'delve', 'rust-gdb', 'set a breakpoint', 'context window exploded', 'why is the response empty', 'why is this happening', 'trace this bug', 'reproduce and fix', 'silent failure', 'HTTP 200 but empty', 'why did it stop', 'inspect the binary', 'playwright', 'flaky test', 'fails intermittently', 'passes in isolation', 'only fails in CI'."
---
# Debugging
@@ -49,12 +49,12 @@ These are not "optional extras". They are the correct tool in their domain, and
| Tool | Use when | Reference |
|---|---|---|
-| **Playwright CLI** | Any browser-served web UI bug. Any flow that requires clicking/typing/navigating. Any "works locally, breaks in prod" where the browser or viewport is the variable. **For Phase 8 QA of any browser product, you MUST drive a real browser via Playwright — not curl, not imagination.** | 📖 **[references/tools/playwright-cli.md](references/tools/playwright-cli.md)** |
+| **Browser Playwright / Playwright CLI** | Any browser-served web UI bug. Any flow that requires clicking/typing/navigating. Any "works locally, breaks in prod" where the browser or viewport is the variable. **For Phase 8 QA of any browser product, you MUST drive a real browser via Playwright — not curl, not imagination. In Codex, use `browser:control-in-app-browser` and its `tab.playwright` API first; use standalone Playwright only when Browser is unavailable or lacks the required action.** | 📖 **[references/tools/playwright-cli.md](references/tools/playwright-cli.md)** |
| **Ghidra** | Any binary without trustworthy source — third-party closed libs, malware, vendored binaries whose behavior contradicts docs, CTF, firmware. **Use Ghidra's decompiler before `strings`/`objdump` guessing. It turns machine code into readable C.** | 📖 **[references/tools/ghidra.md](references/tools/ghidra.md)** |
| **pwndbg** | Any native binary debugging session. It is GDB with the useful views (registers, stack, disasm, heap) always visible. **If you'd reach for plain `gdb`, reach for `pwndbg` instead — it is strictly a superset.** | 📖 **[references/tools/pwndbg.md](references/tools/pwndbg.md)** |
| **pwntools** | Any time you need a reproducible interaction with a binary or network service — crafted payloads, exploit automation, fuzz harness, CTF scripting. | 📖 **[references/tools/pwntools.md](references/tools/pwntools.md)** |
-**Failing to use these tools in their domain is a process failure, not a stylistic choice.** If the bug is in a browser and you did Phase 8 without Playwright, you are doing it wrong. If the bug is in a stripped binary and you read hex with `xxd`, you are doing it wrong. The references tell you how. Read them.
+**Failing to use these tools in their domain is a process failure, not a stylistic choice.** If the bug is in a browser and you did Phase 8 without a real Playwright-driven browser surface, you are doing it wrong. Codex Browser's `tab.playwright` satisfies this requirement; starting a separate Playwright session when Browser can perform the scenario does not. If the bug is in a stripped binary and you read hex with `xxd`, you are doing it wrong. The references tell you how. Read them.
---
diff --git a/plugins/omo/skills/debugging/references/methodology/02-investigate.md b/plugins/omo/skills/debugging/references/methodology/02-investigate.md
index 5a01c30..7796233 100644
--- a/plugins/omo/skills/debugging/references/methodology/02-investigate.md
+++ b/plugins/omo/skills/debugging/references/methodology/02-investigate.md
@@ -65,7 +65,7 @@ When the `team_*` tools are present, create a **debug-squad** team and split inv
{
"kind": "category",
"category": "deep",
- "prompt": "You are the Reproduction Engineer. Your job: build the smallest reliable repro — a curl command, a vitest/pytest/go test, a tmux script, a Playwright script for browser bugs, a pwntools script for binary targets. It must reproduce on first try and be copy-pasteable by the Lead. Document exact input, expected output, observed output. Save repro artifacts under /tmp/ and tell the Lead to journal them. If the bug is browser-based you MUST use Playwright CLI — do not simulate with curl."
+ "prompt": "You are the Reproduction Engineer. Your job: build the smallest reliable repro — a curl command, a vitest/pytest/go test, a tmux script, a Playwright script for browser bugs, a pwntools script for binary targets. It must reproduce on first try and be copy-pasteable by the Lead. Document exact input, expected output, observed output. Save repro artifacts under /tmp/ and tell the Lead to journal them. If the bug is browser-based you MUST use a real Playwright-driven browser — in Codex prefer browser:control-in-app-browser and tab.playwright, falling back to standalone Playwright only when needed; do not simulate with curl."
},
{
"kind": "category",
diff --git a/plugins/omo/skills/debugging/references/methodology/08-qa.md b/plugins/omo/skills/debugging/references/methodology/08-qa.md
index d900e40..016a02f 100644
--- a/plugins/omo/skills/debugging/references/methodology/08-qa.md
+++ b/plugins/omo/skills/debugging/references/methodology/08-qa.md
@@ -14,7 +14,7 @@ Pick the row that matches the product. Do what it says. Do not substitute.
|---|---|
| **CLI tool** | Open `tmux`, run the actual command end-to-end, capture output. Paste the session transcript into the journal. Include exit code, stdout, stderr, side-effect check (files created/modified). |
| **HTTP API** | Start the real server, hit endpoints with `curl` or `httpie`, inspect response status + body + headers. Hit the specific endpoint that reproduced the bug. If there's auth, use real auth. |
-| **Browser-served web app** | **Drive a real browser via Playwright CLI.** See [tools/playwright-cli.md](../tools/playwright-cli.md). Navigate the exact page/flow that reproduced the bug. Capture screenshot + DOM + network evidence. **Do not substitute with curl** — browsers have state (cookies, localStorage, service workers, client-side JS, viewport-dependent CSS) that curl does not have. |
+| **Browser-served web app** | **Drive a real browser via Playwright.** In Codex, use `browser:control-in-app-browser` and its `tab.playwright` API first; use standalone Playwright only when Browser is unavailable or lacks the required action. See [tools/playwright-cli.md](../tools/playwright-cli.md). Navigate the exact page/flow that reproduced the bug. Capture screenshot + DOM + network evidence. **Do not substitute with curl** — browsers have state (cookies, localStorage, service workers, client-side JS, viewport-dependent CSS) that curl does not have. |
| **Agent / LLM pipeline** | Run the same user prompt that originally failed. Capture the full turn — tool calls, messages, usage counters. **Confirm non-zero usage** (zero usage = still failing silently, see silent-failure check below). |
| **Background worker / job queue** | Trigger the job through the normal entry point (API call, cron tick, message publish), tail the worker logs, observe completion state in the queue or DB. Don't just call the worker function directly — the trigger path matters. |
| **MCP server** | Invoke the tool via its actual client (Claude Desktop, Cursor, etc. if available) or `mcp-cli`, not just the HTTP probe endpoint. The MCP handshake itself is sometimes where bugs live. |
diff --git a/plugins/omo/skills/debugging/references/tools/playwright-cli.md b/plugins/omo/skills/debugging/references/tools/playwright-cli.md
index 7d63671..0e8e7c4 100644
--- a/plugins/omo/skills/debugging/references/tools/playwright-cli.md
+++ b/plugins/omo/skills/debugging/references/tools/playwright-cli.md
@@ -2,9 +2,9 @@
**https://playwright.dev/ · https://github.com/microsoft/playwright**
-For any browser-served web UI bug, this is the correct tool. Not curl. Not imagination. Not a headless HTTP library. A real browser with a real rendering engine, real JS execution, real cookies, real service workers, real viewport.
+For any browser-served web UI bug, a Playwright-driven real browser is the correct surface. Not curl. Not imagination. Not a headless HTTP library. Use a real rendering engine with real JS execution, cookies, service workers, and viewport behavior.
-**In Phase 8 Manual QA for browser products, using Playwright is not optional.** Curl cannot catch: CSS that breaks at specific viewport widths, hydration mismatches, client-side router bugs, cookie/session interactions, service-worker caching, JS-triggered navigations. All of those are common bug classes. Drive a browser.
+**In Phase 8 Manual QA for browser products, using Playwright is not optional.** In Codex, read `browser:control-in-app-browser` first and use its `tab.playwright` API when available. That is the primary Playwright surface and keeps the in-app browser context. Use standalone Playwright CLI only when Browser is unavailable, lacks the required action, or the scenario specifically needs an isolated browser process. Curl cannot catch CSS that breaks at specific viewport widths, hydration mismatches, client-side router bugs, cookie/session interactions, service-worker caching, or JS-triggered navigations.
> Note: `microsoft/playwright-cli` is the legacy repo; the current tooling lives in `@playwright/test` (npm) and `playwright` (pip), which include the `playwright` CLI. Use those — the legacy `playwright-cli` package is deprecated.
diff --git a/plugins/omo/test/debugging-browser-routing.test.mjs b/plugins/omo/test/debugging-browser-routing.test.mjs
new file mode 100644
index 0000000..9123f7f
--- /dev/null
+++ b/plugins/omo/test/debugging-browser-routing.test.mjs
@@ -0,0 +1,22 @@
+import assert from "node:assert/strict";
+import { readFile } from "node:fs/promises";
+import { dirname, join } from "node:path";
+import test from "node:test";
+import { fileURLToPath } from "node:url";
+
+const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
+
+test("#given the debugging skill #when its routing description is parsed #then Codex Browser precedes standalone Playwright", async () => {
+ // given
+ const skill = await readFile(join(pluginRoot, "skills", "debugging", "SKILL.md"), "utf8");
+ const frontmatter = skill.match(/^---\n(?<body>[\s\S]*?)\n---\n/);
+ assert(frontmatter?.groups?.body, "debugging skill must have YAML frontmatter");
+
+ // when
+ const description = frontmatter.groups.body.match(/^description:\s*"(?<value>.*)"$/m)?.groups?.value;
+ assert(description, "debugging skill frontmatter must expose a description");
+
+ // then
+ assert.match(description, /browser:control-in-app-browser/);
+ assert.match(description, /standalone Playwright fallback/);
+});
Verification
- RED: targeted regression test failed because
browser:control-in-app-browserwas absent from the routing description. - GREEN: targeted regression test passed after the change (
1 passed, 0 failed). - Adjacent: routing, display metadata, and lcx skill tests passed (
4 passed, 0 failed). - Package:
npm pack --dry-run --jsonsucceeded. - Full plugin suite: unchanged baseline limitation in this generated mirror (
32failures before and after), caused by absent shared monorepo packages and unrelated marketplace-update fixtures. - Manual QA: a fresh
codex execwith Browser and Chrome available selectedBrowser/IAB (tab.playwright)as primary andPlaywright CLIas standalone fallback.
This fix was debugged, implemented, and verified with LazyCodex.
Tag: lazycodex-generated
- Ngôn ngữ chính
- TypeScript
- Star
- 3.8k
- Fork
- 246
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của code-yeongyu/lazycodex
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
code-yeongyu/lazycodex#170 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
code-yeongyu/lazycodex#172 ·
-
[5.0.0-beta.78] High cost and rapid quota consumption: use role-appropriate agent model defaultsĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
code-yeongyu/lazycodex#166 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
code-yeongyu/lazycodex#163 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
code-yeongyu/lazycodex#158 ·
Tất cả issue của code-yeongyu/lazycodex
Issue tương tự
-
bug require-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
expressjs/expressjs.com#2549 · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
umami-software/umami#4686 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: Device screenshot fails with 500 on iPhone Duo (Xcode 27.2): serve-sim calls simctl without --displayCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
pingdotgg/t3code#24900 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
inu-appcenter/UNIDorm-web#411 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
🐛 bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 2 ngày