Skip to content

feat(panel): gate shot/nav (rule 2) + adopt the DS plugin-kit#8

Merged
mabry1985 merged 1 commit into
mainfrom
feat/gated-shot-nav-kit-adoption
Jun 13, 2026
Merged

feat(panel): gate shot/nav (rule 2) + adopt the DS plugin-kit#8
mabry1985 merged 1 commit into
mainfrom
feat/gated-shot-nav-kit-adoption

Conversation

@mabry1985

Copy link
Copy Markdown
Member
  • SECURITY: /panel/shot + POST /panel/nav move off the public /plugins/
    prefix to /api/plugins/agent_browser via build_panel_data_router,
    inheriting the operator bearer gate — previously anyone who could reach a
    token-gated deployment's port could DRIVE the operator's browser session
    and read its screen without the bearer.
  • The /panel/dash reverse proxy stays public OF NECESSITY (it's loaded by
    an <iframe>, which can't carry a bearer) — gating it needs a designed
    handoff; tracked in the companion issue.
  • Kit adoption (both pages): plugin-kit.js via dynamic import (it's an
    ESM; classic <script> throws on its exports) replaces the hand-rolled
    TMAP/listeners — initPluginView (live re-themes) + slug-aware authed
    apiFetch. The full page keeps a THIN relay forwarding the raw console
    message to the embedded dashboard (the kit doesn't re-broadcast).
  • Minimal page: module scripts are scoped, so the toolbar's inline onclick
    handlers are exposed via window.nav/window.go; boot once on
    handshake-or-timeout so the gated first poll authenticates.

Verified end-to-end against the real served kit (playwright
route-intercept): shot poll renders, nav posts through the gated path from
the toolbar, full page boots + relays; zero page errors. 0.1.1 → 0.2.0.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

- SECURITY: /panel/shot + POST /panel/nav move off the public /plugins/
  prefix to /api/plugins/agent_browser via build_panel_data_router,
  inheriting the operator bearer gate — previously anyone who could reach a
  token-gated deployment's port could DRIVE the operator's browser session
  and read its screen without the bearer.
- The /panel/dash reverse proxy stays public OF NECESSITY (it's loaded by
  an <iframe>, which can't carry a bearer) — gating it needs a designed
  handoff; tracked in the companion issue.
- Kit adoption (both pages): plugin-kit.js via dynamic import (it's an
  ESM; classic <script> throws on its exports) replaces the hand-rolled
  TMAP/listeners — initPluginView (live re-themes) + slug-aware authed
  apiFetch. The full page keeps a THIN relay forwarding the raw console
  message to the embedded dashboard (the kit doesn't re-broadcast).
- Minimal page: module scripts are scoped, so the toolbar's inline onclick
  handlers are exposed via window.nav/window.go; boot once on
  handshake-or-timeout so the gated first poll authenticates.

Verified end-to-end against the real served kit (playwright
route-intercept): shot poll renders, nav posts through the gated path from
the toolbar, full page boots + relays; zero page errors. 0.1.1 → 0.2.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@protoquinn

protoquinn Bot commented Jun 13, 2026

Copy link
Copy Markdown

👀 Quinn is reviewing — verdict (PASS / WARN / FAIL) + findings to follow.

@protoquinn protoquinn Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

QA Audit — PR #8 | feat(panel): gate shot/nav (rule 2) + adopt the DS plugin-kit

VERDICT: PASS


CI Status

  • No CI checks configured for this repo (Gap).

Diff Review

  • __init__.py: registers build_panel_data_router at /api/plugins/agent_browser — shot/nav now inherit the operator bearer gate. The public page router remains at /plugins/agent_browser. Clean separation.
  • browser_panel.py: _run helper + _shot/_nav routes extracted into build_panel_data_router; build_panel_router retains only /panel (page) + /panel/dash (iframe proxy). Module-level globals (_shot_ts, _SHOT_PATH) remain accessible. Both pages adopt plugin-kit.js via dynamic import with fallback shims — correct for an ESM module that can't load via classic <script>.
  • Diff truncated at 245 lines — minimal page's updated nav/go fetch paths not fully visible (Gap), but pattern is consistent with the full page and PR claims Playwright E2E verification.

Observations

  • HIGH (positive): shot/nav routes gated behind /api/plugins/ — closes the unauthenticated browser-drive + screen-read vector on token-gated deployments.
  • LOW: full page's import() catch body is empty (catch (e) {}) — benign since initPluginView() is fire-and-forget, but a console.warn would aid debugging.
  • Gap: no CI configured on this repo — can't verify automated checks pass.
  • Gap: clawpatch structural review unavailable (repo not in project registry).
  • Gap: diff truncated — minimal page tail not visible; unable to verify the kit.apiFetch call paths against the new /api/plugins/agent_browser/shot and /api/plugins/agent_browser/nav endpoints.

— Quinn, QA Engineer

@protoquinn

protoquinn Bot commented Jun 13, 2026

Copy link
Copy Markdown

Submitted APPROVE review on #8.

@mabry1985
mabry1985 merged commit c506654 into main Jun 13, 2026
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.

1 participant