Agent Studio Review extension¶
Status: Current | Last reviewed: 2026-09-23
Use the standalone Agent Studio Review extension to identify an environment and collect design feedback against specific DOM elements. This page covers maintenance and the clipboard format; the installation and review guide covers the browser controls.
Install and distribute¶
The committed tools/agent-studio-review/extension/ directory is ready to load as an unpacked Chrome extension. Teammates do not need Node.js or a running local TrueServe stack.
To rebuild, validate, and create a ZIP from the repository root:
cd tools/agent-studio-review
npm ci
npx playwright install chromium
npm run package
The ZIP is written to tools/agent-studio-review/artifacts/agent-studio-review-1.0.7.zip. It contains the agent-studio-review/ directory and installation instructions. Extract it and select that directory with Load unpacked in chrome://extensions.
Keep the extracted folder in a permanent location. To update, replace its contents with the new release, click Reload on the extension card, then refresh the Studio tabs. Reusing the same folder preserves the unpacked extension's identity and local comments. Uninstalling the extension removes its storage.
For HTML files opened directly from disk, open the extension's Details and enable Allow access to file URLs. Reload the file tab afterward. Title-based detection requires Chrome site access on the pages you want to review; On all sites enables automatic detection across HTTP and HTTPS sites.
Page detection¶
| Address pattern | Example environment |
|---|---|
https://ai-manager.<environment>.trueserve.ai/* |
ai-manager.macau.trueserve.ai → MACAU |
https://ai-manager.<environment>.dev.trueserve.deloitte.com/* |
ai-manager.vanguard.dev.trueserve.deloitte.com → VANGUARD |
https://studio.<environment>.trueserve.deloitte.com/* |
studio.qa.trueserve.deloitte.com → QA |
| HTTP/HTTPS localhost or loopback with an Agent Studio title | http://localhost:5173/ → LOCAL |
| Local HTML file with an Agent Studio title | file:///Users/designer/index.html → LOCAL FILE |
| Other HTTP/HTTPS site with an Agent Studio title | https://preview.example.org/ → PREVIEW.EXAMPLE.ORG |
The original URL rules work independently of the page title and take priority. The environment is the uppercased label or labels between the prefix and suffix. For example, studio.london.dev.trueserve.deloitte.com displays LONDON.DEV.
The title fallback matches the standalone phrase Agent Studio, ignoring case and allowing extra whitespace, prefixes, and suffixes. For example, Agent Studio, Agent Studio · Agents, and agent studio — Prototype qualify; AgentStudio and Agent Studios do not. localhost, its subdomains, IPv4 loopback addresses, [::1], and 0.0.0.0 display LOCAL. Other title-matched hosts use their uppercased hostname. Ports remain visible in the banner and captured origin.
The manifest matches HTTP, HTTPS, and file documents in the top-level frame only. Until the URL or title qualifies, the content script watches the document head without mounting the overlay or reading comment storage. It detects delayed titles, title text changes, and replacement of the head/title nodes. If a title-only page stops matching, it removes the overlay and its handlers; matching again reactivates it. Known Studio URL matches remain active regardless of title. Browser-internal, extension, data, and about URLs are excluded.
Implementation¶
The extension uses Manifest V3 with locally bundled TypeScript and CSS. It has no runtime dependencies, remote assets, API integration, telemetry, or application deployment.
| File | Responsibility |
|---|---|
| manifest.json | Host matching, permissions, entry points |
| content.ts | Banner, picker, pins, composer, comment list, copy and deletion |
| locator.ts | Element capture and conservative re-identification |
| model.ts | Comment schema, environment matching, validation and clipboard formatting |
| background.ts | Serialized storage writes across tabs |
| popup.ts | Toolbar popup and supported-page status |
Run npm run lint for strict TypeScript checks, npm run build to refresh the committed JavaScript, and npm test for the unit and Chromium integration suite. npm run check combines these. Commit source and rebuilt extension files together. The tests load the real unpacked extension against intercepted fixture pages at supported hostnames; they do not contact a live Studio deployment.
The overlay lives in a shadow root beside body. Its styling is isolated from Studio. The 30-pixel banner overlays the top edge without resizing Studio's canvas or fixed-position shell; minimizing it leaves a small white environment label at the far left, over the logo corner. Long labels truncate within 160 pixels, with the full environment available on hover. The center of the header stays available for clicking and element selection when the banner is collapsed. Pins use current element geometry and are refreshed on scrolling, resizing, DOM replacement, and an 800 ms navigation/layout check. Tests include HTTP previews and real temporary HTML files as well as intercepted HTTPS fixtures.
Storage and scope¶
Comments live in chrome.storage.local under agent-studio-review-v1. The service worker queues saves, individual deletes, and clear-all operations so simultaneous tab activity does not overwrite unrelated changes. It creates comment UUIDs in the extension's secure context, so plain HTTP previews work even when crypto.randomUUID is unavailable in the page. Persistence failures stay visible and keep the comment draft available.
The panel lists all saved comments from every page and environment, in saved order. Each row has a page title, environment, route, feedback, and two icon buttons: copy and delete. Copy all for AI copies the whole list. Clear all comments asks for confirmation, then clears the list across every environment in this browser profile. Individual deletion is immediate. The toolbar count shows the total saved comments.
The eye button beside Comments switches between Hide comment numbers and Show comment numbers. Hiding removes the page pins so they do not cover or intercept clicks on reviewed controls. Comments, list numbering, the total count, copying, and new selections remain available. Visibility defaults to shown and is stored separately as a boolean under agent-studio-review-show-pins in chrome.storage.local; it survives refreshes and updates open review tabs in the same profile. Saving or clearing comments does not reset that preference.
The banner starts expanded in a fresh browser session. Collapsing or expanding it sets agent-studio-review-banner-collapsed in chrome.storage.session, shared across supported pages and tabs. Refreshes, navigation, and title-driven overlay remounts restore the last choice. Neither banner variant appears until that preference loads, avoiding a flash of the full banner when collapsed. The worker enables content-script access to session storage before responding to the initial read; this area contains display preferences only. Restarting Chrome or reloading the extension resets the banner to expanded. Saved comments and the comment-number preference remain in local storage.
Each comment retains its exact origin and route: pathname, query string, and fragment. Pins appear only on that original page. Comments are local to the browser profile; teammates share them by copying text. They are not synchronized through a TrueServe tenant or Chrome Sync. Switching tenants on the same origin and route does not create a separate comment scope.
Client-side navigation does not block selection or saving. You can add comments after path, query, or fragment changes, including History API and back/forward navigation on local apps such as http://localhost:3100. If the route changes while you write a comment, saving retains the page URL and element context captured when you selected the element, even if the element has since disappeared. Navigation does not retarget your draft.
File URLs use file:// (plus a host for network files) as their stored origin, rather than the browser's opaque "null" origin. Their routes retain the complete encoded file path, so two different index.html files have separate pins. Copies include the full file URL.
The storage key stays the same across the update. Reading older comments preserves their feedback and element context, including previously resolved comments. Retired author, status, and update-time fields are ignored and stripped on the next write. The UI has no author field, filters, edit/resolve actions, or file import/export.
Clipboard format¶
Copy all for AI writes a compact block for each comment: the exact page URL, one selector, a short source-search label when available, and the feedback. The copy icon on a row writes only that comment. A manual text selection dialog is available when automatic clipboard writing fails.
## 1. https://ai-manager.macau.trueserve.ai/agents
Selector: button[data-testid="create-agent"]
Label: "Create agent"
Feedback: Make this action easier to find.
The URL provides the route and environment, the selector identifies the element, and the label gives AI a literal phrase to search for in JSX or templates. Labels prefer the accessible name, fall back to visible text, collapse whitespace, and are limited to 120 characters. An empty label is omitted. Selectors appear literally, including quotes. No separate page title, environment, route, timestamp, DOM path, XPath, coordinates, or element JSON is copied.
For an element inside shadow DOM, the single Selector: line contains the full selector chain joined by >>>. A short legend explains that notation once per copy. Single-comment copy, copy-all, and the manual clipboard fallback share this format, including for existing saved comments.
Stored comment data¶
The fuller captured data stays in local storage for pin positioning and re-identification. Each stored comment includes:
| Field | Meaning |
|---|---|
id |
Stable UUID identifying the stored comment |
environment |
Uppercased environment name |
page |
url, origin, route, title |
text |
Feedback |
createdAt |
Creation time as an ISO timestamp |
element.selector |
Unique CSS selector in the element's root |
element.domPath |
Full DOM ancestry, with >>> between shadow roots |
element.xpath |
Namespace-safe XPath for light DOM; null inside shadow DOM |
element.shadowPath |
Ordered CSS selectors: outer shadow hosts, then target |
element.tag, text, label, attributes |
Bounded element identity and context |
element.rect, point |
Captured viewport rectangle and click position as fractions of its size |
Locator generation prefers data-testid, data-test, data-cy, stable IDs, labels, and names, then falls back to an ancestry selector with sibling positions. Framework class names are not used. Pin placement requires exactly one match with the captured tag and, when present, matching text and label. A changed or missing element hides its pin; the comment and saved selector remain available in copied text.
Saves validate allowed fields, the original URL or captured Agent Studio title, and environment consistency before writing. Requests come from this extension's top-level isolated script and carry the current page title. The worker checks that the sending document is supported and stores the validated page context supplied by the picker. It does not require that captured URL to equal Chrome's sender URL or the tab's current route. Storage supports at most 1,000 comments within Chrome's local storage quota. Copy and remove older comments when that limit is reached.
The root prototype's built-in comment system is separate: it uses page-local ts-comments storage and its Copy All for Claude action writes only page labels and feedback. Those prototype records have coordinates but no element selectors. The extension's Copy all for AI output has a numbered URL heading and a Selector: line for every comment. Use the extension's Add Comment control to capture an element selector; updating the extension cannot reconstruct selectors for comments created by the prototype.
Capture boundaries¶
The extension records DOM paths, not React component names or source filenames. AI tools use the paths, labels, and text to locate the corresponding implementation. Paths can change after a redesign, and tabs or dialogs that do not change the URL must be reopened manually before their pins can appear.
Capture includes page URLs and bounded DOM text and labels. It omits form values, editable text, script/style content, cookies, screenshots, and full page HTML. It does not traverse closed shadow roots or iframe documents; only the visible host/frame can be selected. Browser fullscreen and native top-layer dialogs can cover the overlay; exit fullscreen or close that dialog to use the extension. Ordinary Studio DOM dialogs and open shadow roots are supported.