docs(plans): in-pod browser view — scoping note (TASK-060) - #1229
Open
lilyshen0722 wants to merge 2 commits into
Open
docs(plans): in-pod browser view — scoping note (TASK-060)#1229lilyshen0722 wants to merge 2 commits into
lilyshen0722 wants to merge 2 commits into
Conversation
Sam's idea, assigned to this seat, and the title's question mark is the right instinct: `Widget` IS the correct taxonomic home, and it has no runtime. It is a declared ComponentType in Installable.ts, that file is explicitly scaffolding only, and the taxonomy refactor is paused under ADR-011 — so the real choice is un-pause vs one-off, not which type. The finding that actually scopes the feature is that an iframe runs on the VIEWER's machine. "Render a live localhost pane" therefore means two different things depending on who is looking: it works perfectly for a solo operator and silently shows a second viewer their OWN localhost. That is not a later bug, it is the feature having two meanings. Proposes a cheaper first version with no security surface: agents already have a browser (MCP Playwright, verified live from this seat today), so the agent can render in ITS browser and attach the image — one browser, same pixels for every viewer. Strictly less capable, and the trade is Sam's to make, not mine. Written under the UI freeze: proposes no visual or layout change, and says so. Docs-only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t hid @sprint-review checked the reachability half and found the conclusion right off a wrong premise. "Widget has no runtime" holds — widgetLocation appears only in its own declaration. "Installable.ts is scaffolding, nothing reads it" does not: four consumers, one a live production route doing full CRUD. I checked the surface the feature would render from and treated its emptiness as a fact about the file. The render side is inert; the storage side ships. That premise was hiding the thing that actually scopes the task. Marketplace publish persists components from req.body after a single length check, and widgetUrl has no scheme check, no allowlist, no length bound. The rows are inert only because nothing renders them — so shipping a renderer makes every widgetUrl already in the catalog live at once, and the validation has to land first and independently rather than alongside the feature. It also removes "un-pause ADR-001 vs one-off" as a clean either/or: the pause covers the read path, so a one-off still writes into the live schema. Finding is @sprint-review's; the wrong premise was mine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
TASK-060, Sam's idea, assigned to this seat. A scoping note rather than a design — written under the 2026-08-24 UI freeze, so it proposes no v2 visual or layout change and says so up front.
The title's question mark is the right instinct
Widgetis the correct taxonomic home — it's a declaredComponentTypeinbackend/models/Installable.tsand ADR-001 describes it asWidget { location, url, scopes }, which is almost literally this feature. Nothing else in the taxonomy fits.But that file is explicitly "pure scaffolding: schema + types + indexes. No services, routes, adapters", nothing reads
components[].type === 'widget', and the Installable refactor is paused under ADR-011 with a reactivation trigger this task doesn't meet. So the decision isn't which component type — it's un-pause ADR-001 with this as the first widget, or build a one-off and migrate later.The part that decides the feature isn't rendering
An iframe runs on the viewer's machine. That splits "render a live localhost/URL pane" into two features that look identical in a mock:
localhost:3000The localhost case works perfectly for a solo operator and silently shows a second viewer the wrong thing — their own dev server, or worse, an unrelated app on the same port presented as the agent's work. That's not a bug to fix later; it's the feature meaning two different things depending on who's looking.
The remote case is bounded by the target's
X-Frame-Options/frame-ancestors, not ours, andDENYis the common default.The reframe, and a cheaper first version
The question is "whose browser is running it, and does the viewer see what the author saw?" — and agents already have a browser. MCP Playwright is live on this seat (verified today by navigating to
commonly.meand getting a real snapshot). So: the agent renders in its browser, attaches the image, a refresh action re-captures. One browser, same pixels for everyone, no iframe, no cross-origin question, no new component type.Strictly less capable — not interactive, not continuously live. That trade is Sam's to make, which is why the note ends on the question rather than answering it:
They pull in opposite directions, and the wrong pick costs a component type.
Incidental
This repo configures no
helmet, no CSP, noframe-ancestors— so Commonly itself is framable. That's about us being embedded rather than us embedding, and it's noted in the doc as deserving a separate look, not folded into this.Docs-only.
🤖 Generated with Claude Code