feat(studio): add studio_inspect, so an agent reads before it writes - #3517
Draft
miguel-heygen wants to merge 1 commit into
Draft
feat(studio): add studio_inspect, so an agent reads before it writes#3517miguel-heygen wants to merge 1 commit into
miguel-heygen wants to merge 1 commit into
Conversation
3 tasks
miguel-heygen
marked this pull request as draft
August 27, 2026 01:33
Everything about one element in one call: resolved styles, text fields, box, data attributes, GSAP animations, and what the element will and will not accept. The point is to prevent a failed write rather than to satisfy curiosity. `can.reasonIfDisabled` is passed through verbatim from Studio's own capabilities, so an agent that reads first should never attempt an edit the element would refuse. Three things it refuses to get wrong: Animations are reported ONLY for the current selection, because that is the only element Studio parses them for. Attributing them to any other element would be reporting the wrong element's motion, which is worse than reporting none. When a handle names something else the field is empty and `animationEditingBlocked` says why. `animationEditingBlocked` also carries the two states where animation editing is off entirely, multiple timelines and an unsupported timeline pattern. Both live on the selection context. Learning them from a read costs one call; learning them from a failed write costs a retry loop. Inspecting a handle does NOT change what is selected. It is a read, and stealing the human's selection would be a side effect they did not ask for. There is a test asserting `applySelection` is never called. Nothing selected and no handle given is a failure, not an empty result. An empty result would assert "this element has nothing", which is a different and false claim.
miguel-heygen
force-pushed
the
feat/studio-webmcp-frame
branch
from
August 27, 2026 04:48
d7ba77c to
57c9bb0
Compare
miguel-heygen
force-pushed
the
feat/studio-webmcp-inspect
branch
from
August 27, 2026 04:48
bc098b8 to
1478adf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
studio_inspectreturns everything about one element in a single call: resolved styles, text fields, box, data attributes, GSAP animations, and what the element will and will not accept.Also extracts the shared WebMCP test fixtures into
webmcpTestUtils.ts, which removes the duplication that was accumulating across the tool test files and theas HTMLElementcasts that came with it.Stacked on #3516.
Why
The point is to prevent a failed write, not to satisfy curiosity.
can.reasonIfDisabledcomes through verbatim from Studio's own capabilities, so an agent that reads first should never attempt an edit the element would refuse. That matters more here than in a normal API, because a refused write in Studio is often silent.How
Three things it refuses to get wrong:
Animations are reported only for the current selection, because that is the only element Studio parses them for. Attributing them to any other element would be reporting the wrong element's motion, which is worse than reporting none. When a handle names something else the list is empty and
animationEditingBlockedsays why.animationEditingBlockedalso carries the two states where animation editing is off entirely, multiple timelines and an unsupported timeline pattern. Both live on the selection context. Learning them from a read costs one call; learning them from a failed write costs a retry loop.Inspecting does not change the selection. It is a read, and stealing the human's selection would be a side effect they did not ask for. There is a test asserting
applySelectionis never called.Nothing selected and no handle given is a failure, not an empty result. An empty result would assert "this element has nothing", which is a different and false claim.
Test plan
8 tests in
inspectTools.test.ts, and the whole WebMCP suite re-run after the fixture extraction:reasonIfDisabledpass through verbatim.animationEditingBlockedreasons are asserted separately.applySelection.WebMCP suite 78 passing. Full package suite 4563 passing across 411 files.
bunx tsc --noEmitclean,bunx oxlintclean,bunx fallow audit --fail-on-issuesclean.Still no browser verification anywhere in this stack; that is the final unit.