Picking an element of the preview page
Esta página ainda não foi traduzida, então você está lendo o original em inglês.
The Code screen's Preview panel frames the dev server's page in an iframe with an opaque origin (no
allow-same-origin), so nothing is injected into it and the screen cannot ask it what is under a click.
"Select element" (Ctrl/Cmd+Shift+S) therefore works on the server side, in the browser Chimera already has.
The path
POST /api/preview/select/capture: opens the page in the app's Playwright browser and returns a JPEG of the viewport, its size, and an internal revision (address plus load time of the document).- The owner clicks the picture. The client sends the point in the page's own pixels.
POST /api/preview/select/pick: asks the SAME page for the element at that point (document.elementFromPoint), refuses if the loaded document is no longer the one in the picture, and returns the element. Its text is stored as an attachment (sanitized and data-fenced bychimera/api/attachments.py); the crop of the element is stored as an image attachment.- Both attachments are marked as page content (
attachment-origin/<id>under the data folder). The turn that carries either one records a fetch in its ledger (record_page_elementsfor the text, which also carries a mark of its own, andrecord_page_originfor any attachment, including the PNG, which has no text to mark), so the run is tainted like any other page read. - If no conversation screen is mounted to take the chips, nothing is added, the panel says so, and
POST /api/preview/select/discarddeletes what was stored (only attachments marked as page content). POST /api/preview/select/closeends the session. An idle session is closed by a timer (5 minutes), a close cancels a capture still loading (generation counter), and a browser that does not answer in 90 s is abandoned: the caller gets a 504 and the next call runs on a fresh thread.
Rules
- Owner's desktop screen only (the guard of
/api/preview); the routes are absent from the bridge table. - A configured process server that is running, whose own process tree listens on its port, and whose port is
none of Chimera's. A server attached by
urlis never opened. - The browser is built from the app's own settings (site list, headless switch), except the cookie profile:
it is always ephemeral, whatever
CHIMERA_BROWSER_COOKIE_RETENTIONsays, because the project's page must not run in the profile that holds the agent's sign-ins. - The page's script runs in the page and can replace what the reader calls. Nothing it returns is trusted:
validatekeeps only an allowlist of attributes, requires a tag that is a plain name, clips every field, never reads a form field's value, and drops the query, fragment and credentials of every address. - A path segment of an address that looks like a credential (20+ hex characters, or 20+ url-safe base64
characters mixing upper case, lower case and digits) is replaced with
[redacted]. This is a heuristic: a secret in a readable segment, or in the element's visible text, is not recognised. The text is the page's, which is why it is fenced and the turn is tainted.
Tests
tests/test_element_pick.py (server, validation, taint, races, timeouts; includes a hostile-page check that
never skips and a Node run of the real reader), tests/test_element_pick_browser.py (real Chromium, skipped
without one), and the PreviewPane and attach-request tests on the desktop side.