Skip to content

Fix Codex terminal link clicks and name the innerdogfood harness - #581

Open
nedtwigg wants to merge 7 commits into
mainfrom
codex-link-click
Open

Fix Codex terminal link clicks and name the innerdogfood harness#581
nedtwigg wants to merge 7 commits into
mainfrom
codex-link-click

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Sep 6, 2026

Copy link
Copy Markdown
Member

Clicking a valid OSC 8 hyperlink from Codex did nothing because Dormouse captured the pointer on its wrapper at mouse-down, redirecting mouse-up away from xterm's link handler. Mouse presses now capture on xterm's screen, so link releases reach the existing confirmation dialog and selection still works when the first movement leaves the iframe.

Regression coverage checks the screen capture target, plain-click event propagation, capture before the first move, non-left buttons, and outside-iframe finalization. The spec records click-versus-drag behavior and the rationale records the browser evidence.

Also renames the standalone browser testing task to pnpm innerdogfood, updating walkthrough callers and agent guidance.

Validation:

  • Real Codex CLI 0.153.4 in innerdogfood: link clicks show the correct confirmation dialog.
  • Browser iframe probe: press 2 px inside the edge, move directly outside, then release; both events reach xterm's screen and the selection finalizes.
  • All 2,748 library tests pass across 174 files, including the mouse-router and terminal-registry regressions.
  • Library typecheck and spec lint/self-tests pass.

nedtwigg and others added 4 commits September 6, 2026 11:42
Reuse the pendingDrag.pointerId field that already existed for this and was
written but never read, instead of a second module-level pointer id with two
hand-written reset sites — pendingDrag is nulled on every finalize path, so it
already owns the lifetime.

Drop the terminalOwnsEvent probe from onPointerDown: it now guards only a
scalar stash, while the capture it used to gate is gated by pendingDrag, which
beginPendingDrag creates only when the terminal owns the press. That removes a
second getBoundingClientRect per left-button press.

Repoint the window-mousemove backstop comment at the capture's new home, fix
the test helper comment that claimed capture in two places, and drive the
non-left-button test past the drag threshold — with no press capturing any
more, it no longer distinguished anything.

Fold the new spec rule into the bullet that defines the threshold it cites,
put the AGENTS.md innerdogfood note in house form, and widen the standalone.md
`dev:standalone*` pointer that the rename left behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDoTLwhYDdKqux4t1V9mqj
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 6, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: c587dbb
Status: ✅  Deploy successful!
Preview URL: https://93318a14.mouseterm.pages.dev
Branch Preview URL: https://codex-link-click.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

Two inline: a drag that leaves the webview before crossing the threshold now never begins at all, and §3.1 of mouse-and-clipboard.md lost the rule the section is named for.

Comment thread lib/src/lib/terminal-mouse-router.ts Outdated
Comment thread docs/specs/mouse-and-clipboard.md Outdated

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

Both earlier findings are addressed. One inline: a comment rewrap that carries eight lines of churn for no change in wording.

Comment thread lib/src/lib/terminal-mouse-router.ts Outdated
@nedtwigg
nedtwigg marked this pull request as ready for review September 6, 2026 19:42

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The capture-target change reads correct end to end: .xterm-screen is resolved once at attach, after terminal.open(element) in createXtermHost, and both capture and release now go through mouseCaptureElement, so a retargeted mouseup bubbles through xterm's linkifier before the router's own window handlers see it. Dropping pendingDrag.pointerId is safe — it was written and never read on main. Only two files hand the router a hand-rolled element (terminal-mouse-router.test.ts and terminal-registry.alert.test.ts), and both now define querySelector, so there is no second instance of the failure that went red earlier. spec-lint, public-docs-lint, xterm-lint, loopback-lint, deploy-lint and e2e-lint all pass on this tree, AGENTS.md included, and no dev:standalone:ab or dev:agent-browser reference survives the rename.

One question on the new AGENTS.md guidance, inline.

Comment thread AGENTS.md
```

**Inside Dormouse, run `innerdogfood`** — `dor ensure -- pnpm innerdogfood`, then
`dor ab --key innerdogfood open http://localhost:1420`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this leave two live webviews on one sidecar? openAgentBrowser() runs unconditionally at the end of standalone/scripts/dev-agent-browser.mjs and does agent-browser --session <browserSession> open http://localhost:${vitePort} — with the defaults browserSession = 'dormouse-dev-standalone' and vitePort = 1420. So by the time the reader runs dor ab --key innerdogfood open http://localhost:1420, the harness has already opened that exact URL in its own session, and this line opens it again under dormouse.1.innerdogfood.

Both pages then hold an SSE stream on the same bridge, and the bridge has no per-webview routing: sseClients is a plain Set and broadcast() fans every sidecar event to all of it. That is the situation docs/specs/transport.md -> "PTY ownership" is about — "A PTY routed to one webview must not be stolen by another router; new routers attaching to a host must respect existing ownership" — and the dev bridge is the one host that doesn't enforce it.

The repo's own debug-standalone-agent-browser skill goes the other way: "Use the outer harness session printed by innerdogfood", i.e. drive the session the harness already opened rather than starting a second one. dor ab --session dormouse-dev-standalone <cmd> is the flag for that — per dor ab --help, "Attach to a raw agent-browser session by its literal name", and "dor opens (or reuses) the browser surface bound to the session" — which would put the harness's existing page in a Dormouse pane without a second webview.

If you exercised the two-browser form while validating the Codex link click and it behaves, say so and I'll drop it — I can't run the harness from CI. But as written, AGENTS.md and the skill now prescribe different things for the same task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants