Files
kandev/docs/plans/native-html-preview/plan.md
T
2026-09-07 13:45:28 +01:00

11 KiB

created, status, requirements, system_design, legacy_specs
created status requirements system_design legacy_specs
2026-09-05 complete
REQ-UI-NATIVE-HTML-PREVIEW-001
../../specs/ui/system-design/native-html-preview.md

Implementation Plan: Trusted Browser HTML File Preview

Overview

Replace the QuickJS and virtual-DOM implementation with a one-click static preview server in agentctl. Publish the current editor buffer as an in-memory entry document. Serve relative workspace assets from disk. Desktop and mobile replace the active file editor body with the focused iframe. The Browser panel remains an explicit secondary desktop action.

The product owner selected the trusted native-browser model. Implementation and documentation must state that previewing executes trusted workspace code and must not claim hostile-content isolation.

Scope

In scope

  • An ephemeral loopback static server owned by each agentctl instance.
  • Bounded in-memory overlays for current, unsaved HTML buffers.
  • Workspace-rooted relative asset serving with traversal and symlink-escape protection.
  • A session-authorized backend publish endpoint and agentctl client contract.
  • Existing session port-proxy routing for every supported executor.
  • Desktop in-editor iframe, Show code, refresh, and optional Browser-panel behavior.
  • A full-height mobile iframe with the same recovery and preserved editor state.
  • Localized trusted-code, progress, error, and retry copy in all locales.
  • Removal of the preview-specific QuickJS and direct parse5 dependencies, the virtual DOM, worker code, and obsolete tests.
  • Public documentation and focused backend, frontend, E2E, and desktop checks.

Out of scope

  • An untrusted-content security boundary or dedicated preview origin.
  • Framework builds, HMR, server-side routes, or package installation.
  • Review-diff previews, source mapping, and new Browser-panel inspector features.
  • Replacing explicit development-server commands for non-static applications.

Technical approach

Workspace preview server

Add a concurrency-safe manager to agentctl. It binds one loopback ephemeral port per selected workspace or repository root. The manager publishes up to 32 current-buffer overlays of at most 5 MiB each. It stops all servers with the agentctl instance. Exact overlay paths win over disk content. All responses use Cache-Control: no-store.

The server resolves request paths with the existing repository path helpers and rejects traversal, encoded traversal, and symlink targets outside the selected root. It does not rewrite document content or emulate browser behavior.

Session publish contract

Add a task-session endpoint that authenticates the session, ensures agentctl is ready, bounds the request, and forwards {repo, path, content}. Agentctl repeats validation and returns {port, path, version}. The frontend builds the existing session port-proxy URL and appends the version as a cache buster.

Responsive UI

Desktop and mobile keep the file tab identity and replace the source body with HtmlPreviewContent after publication. Kandev-owned chrome provides Show code, refresh, errors, retry, and an optional desktop Browser-panel action. Preview state is scoped to the active session and file identity and is not restored across reloads.

Before execution, user-facing copy identifies the action as trusted workspace code. The iframe uses the existing Browser-panel sandbox policy. The feature does not add an isolation claim or browser capability filter.

Migration and documentation

Delete the worker runtime, virtual DOM, Shadow DOM renderer, navigation normalizer, and preview-only QuickJS/direct parse5 dependencies. Keep Markdown behavior and explicit development-server controls unchanged. Update public guidance to distinguish the zero-configuration static preview from application development servers and to state the trust consequence.

Acceptance evidence

Acceptance criteria Evidence
.1, .2, .3, .7, .8, .9, .10 Frontend API/component tests plus desktop and mobile E2E for current buffers, in-editor toggling, explicit Browser-panel opening, trust copy, source preservation, and recovery
.4, .5, .11 Agentctl server tests and browser E2E for native scripts, browser APIs, relative assets, bounds, path containment, eviction, and shutdown
.6 Backend handler/client tests plus existing session port-proxy regression coverage

Work orders

Trusted Browser delivery

In-editor preview revision

Superseded implementation work

Tasks 01 through 04 describe the original scriptless prototype. Tasks 05 through 09 describe the QuickJS and virtual-DOM implementation. They are retained for traceability but cancelled because the selected product contract is native browser fidelity:

Dependency order

Task 10 agentctl server
        |
        v
Task 11 session contract
        |
        v
Task 12 responsive UI and runtime removal
        |
        v
Task 13 docs, E2E, and final verification
        |
        v
Task 14 in-editor desktop preview
        |
        v
Task 15 revised docs and E2E

Tasks 10 and 11 establish the serving and authorization boundary before any UI depends on it. Task 12 removes the old runtime only after the end-to-end URL can be produced. Task 13 verified the first shipped flow. Tasks 14 and 15 revise the desktop presentation without changing the serving boundary, then update its documentation and browser evidence.

Risks

  • Same-origin Browser-panel content can exercise Kandev/browser authority. This is an accepted product tradeoff and must remain visible to users.
  • Agentctl server teardown and overlay locking must cover stop, restart, and executor failure paths without leaking listeners or data.
  • Proxy rewriting and capability cookies must preserve relative, root-relative, redirect, module, and fetch requests.
  • Multi-repository roots and symlinks can accidentally widen filesystem access unless existing canonical path helpers are used consistently.
  • In-editor preview state must not outlive its session or file identity, and stale publish completions must not replace another file's source body.
  • Removing runtime packages changes the shared lockfile and generated license catalog. The Markdown renderer still owns transitive parse5 licenses, so the verification must distinguish those from the removed preview dependency.

Completion gate

The package is ready to merge after all required checks pass. These checks cover the backend, frontend, documentation, localization, E2E, desktop, dependencies, licenses, and PR CI. Every review thread must have a disposition before merge.

Verification results

  • Agentctl API tests and race tests passed, including deterministic concurrent publish/read, per-root ports, and HEAD/405 method coverage.
  • Full backend tests passed with the task-host internal config overrides cleared.
  • Focused frontend tests passed: 13 files and 69 tests, including stale session completion guards.
  • Agentctl client and task-handler tests passed for typed 400/413/503 propagation, malformed responses, oversized requests, and unavailable sessions. The unused lifecycle forwarding layer was removed.
  • Web typecheck, lint, i18n checks, i18n ratchet, license generation, and Vite E2E build passed.
  • Public-doc validation passed: 61 tests and 43 published pages.
  • Raw desktop Chromium and mobile Chrome preview suites passed: 2 tests each.
  • Desktop shell E2E passed.
  • Fresh desktop and mobile screenshots were captured, inspected, and compressed for the pull request.
  • Reproduced and fixed the CI-only frontend failure in the saved-repository picker by synchronizing the Radix menu dismissal and asynchronous discovery assertions.
  • Disabled Happy DOM main-frame and child-frame fixture navigation, and isolated Vitest-importable E2E utilities from Playwright runtime imports to remove the unhandled loopback ECONNREFUSED failures.
  • The full frontend suite passed after the fix: 1,871 test files, 15,869 passed, and 4 skipped, with no unhandled network errors.
  • Re-ran desktop and mobile native preview E2E locally: 2 tests passed in each project. Web lint, direct web typecheck, i18n checks, and formatting checks also passed.
  • Revised the desktop presentation so Preview HTML replaces the active editor body instead of automatically opening a Browser panel. Focused frontend coverage passed 6 files and 22 tests, including source recovery, latest-buffer refresh, explicit Browser-panel opening, and file/session identity resets.
  • Revised desktop and mobile preview E2E passed 2 tests in each project on the first attempt. Specification validation passed all 30 tests, public-doc validation passed 61 tests across 46 pages, and desktop shell E2E passed.
  • The final full frontend suite passed 1,872 test files and 15,902 tests, with four intentional skips and no failures.