Give Your Coding Agent Eyes: Debug Cypress Through a Live Browser Session A developer introduced `cypress tap`, a terminal interface that lets coding agents inspect a live Cypress open-mode session rather than relying on `cypress run` exit codes. The tool exposes the Command Log, DOM snapshots, accessibility tree, and historical browser state via JSON commands like `status`, `reporter`, `command`, `pin`, `aria`, and `inspect`, enabling agents to gather the same evidence a human developer would before proposing a fix. The beta tool requires Cypress 15.21.0 or later, works only with `cypress open` and a Chromium-based browser, and includes a polling protocol to avoid stale-state verdicts. A coding agent can run cypress run and read the exit code. That tells it whether a spec passed. It does not show the Command Log, the DOM at the failed command, the accessibility tree, or the browser state a human sees in Cypress open mode. This gap matters when the failure is visual or stateful. “Element not found” could mean the selector is wrong, the page never loaded, an overlay covered the control, or the test inspected the wrong retry attempt. cypress tap adds a terminal interface to a live Cypress open-mode session. The interesting part is not that an AI can execute another command. It is that the agent can inspect the same evidence a developer would use before proposing a fix. Start Cypress and select a Chromium-based browser: npx cypress open --e2e --browser=chrome In another terminal: npx cypress tap specs --json npx cypress tap run cypress/e2e/login.cy.ts --json npx cypress tap status --json The run command requests a run and returns immediately. It does not mean the spec has started or finished. A reliable agent must poll status , set its own timeout, and wait for a terminal passed or failed state. There is a subtle stale-state trap: the previous run's verdict remains readable until the next run starts. The JSON status includes startedAt ; compare it with the run you requested before trusting the verdict. That produces a bounded protocol: type TapStatus = { status: | "not connected" | "browser not selected" | "spec not selected" | "loading" | "running" | "passed" | "failed"; startedAt: string | null; }; async function waitForVerdict requestedAfter: number { for let attempt = 0; attempt < 60; attempt++ { const status = await runJson