Skip to content

feat: live campaign dashboard — Preview renders HTML, stays live, pops out (#2140) - #2145

Merged
jacktrnr merged 4 commits into
mainfrom
opencode/issue-2140-html-preview
Nov 7, 2026
Merged

jacktrnr merged 4 commits into
mainfrom
opencode/issue-2140-html-preview

Conversation

@jacktrnr

@jacktrnr jacktrnr commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Live campaign dashboard (#2140): Preview renders HTML, keeps it live, and pops it out to the browser; the research loop writes the page.

Closes #2141 · Closes #2142 · Closes #2143 · Closes #2144 · Part of #2140

What changes

  • Preview renders .html/.htm (Preview renders HTML files (sandboxed, scripts off, local images inlined) #2141). The page runs in an iframe sandboxed allow-same-origin without allow-scripts: scripts, inline handlers and meta refresh never run, while the host routes link clicks (https opens the system browser, local links open in Preview), applies zoom and keeps scroll. Before display the host strips script/base/refresh/link/embedding elements and inlines local images (relative, absolute, file://; img src and SVG image href) as data URIs read through the engine file API, within a count and size budget. Rendered/Source toggle as for Markdown.
  • Live outside the watcher (Preview: keep rendered HTML live when the page or its images change outside the watcher #2142). The engine watcher only sees the project tree and the agent's own writes. While its pane is active and the window visible, a rendered page re-reads itself every 3 s, and its images too while the inlined total is under 8 MB. New text goes through the parent, which never overwrites unsaved Source edits. A watcher change to an inlined image re-renders.
  • Pop-out (Preview: pop out a rendered HTML page to the system browser #2143). The "Open in browser" control posts a new bridge kind, open-html-external, so open-external stays https-only. Both webview shells forward it. The extension opens the file only when it is an absolute, existing, local .html/.htm file in a local window; every refusal shows a warning that says why.
  • Research loop contract (Research loop writes a live campaign dashboard page at every record boundary #2144). The research skill now specifies the page (status line, needs-you, loop table, key findings, plots), says it is static only, and says where it lives: reports/dashboards/ in a Research Project, ~/.amico/dashboards/ otherwise, never the synced vault. The mode card and its legacy mirror now point the record step at the page.

Not in scope

Verification

  • ./.notturno/gates (base origin/main): GREEN. Covers drift, typecheck, build, and vitest:extension (5801 tests).
  • pnpm --filter amicode test: 345 files, 5815 tests passed.
  • Materialized app: bun test for src/components/session gives 286 pass, 0 fail. session-ui routing and markdown-utils tests pass. tsgo -b is clean. vite build succeeds, and the bundle contains the view.
  • build:binary: DONE.
  • Headless Chrome, using a real agent-written status page (atd-mitten168/.../carried/status.html) with an injected script, meta refresh and a local plot, under the app's CSP. The page renders (17 table rows), the script did not run, the plot was inlined and decoded, meta refresh never reloaded the page (1 load), link clicks were intercepted and classified, and the frame stayed at about:srcdoc. An earlier probe confirmed that the parent can read the frame and its listeners fire while inline scripts and onerror handlers in the frame stay inert.
  • Not exercised: the extension's real webview, meaning a click-through of the controls in the running panel.

Jackson Turner added 4 commits November 6, 2026 13:44
#2141)

.html/.htm open rendered with the markdown Preview/Edit toggle. The page runs
in an iframe sandboxed allow-same-origin WITHOUT allow-scripts: scripts, inline
handlers and meta refresh never run, while the host routes link clicks (https
to the system browser, local links into Preview), applies zoom and keeps
scroll across re-renders. Before display the host strips script/base/refresh/
link/embedding elements and inlines local images (relative, absolute, file://;
img src and SVG image href) as data URIs read through the engine file API,
within a count and size budget.

Part of #2140.
The engine watcher only sees the project tree and the agent's own writes, so a
dashboard a script rewrites in the personal vault never refreshed. While its
pane is active and the window visible, the rendered page re-reads itself every
3 s (new text goes through the parent, which never clobbers unsaved Source
edits) and, while the inlined total is under 8 MB, its images; a watcher change
to any inlined image re-renders too. Re-renders keep scroll.

Part of #2140.
Rendered HTML in Preview gets an 'Open in browser' control. It posts a new
bridge kind, open-html-external, so open-external stays https-only; both
webview shells forward it, and the extension opens the path with the system
handler only when it is an absolute, existing, local .html/.htm file in a
local window. Every refusal (relative path, wrong type, missing file, remote
window) names itself in a warning; nothing opens.

Part of #2140.
The research skill gains the dashboard contract: one static HTML page per
campaign, a derived view of the ledger rewritten at kickoff and every record
step - status line, needs-you, loop table (verdicts copied, never upgraded),
key findings, plots as sibling files - static only (Preview renders it with no
scripts), linked once in chat as a file:// link. In a Research Project it lives
under reports/dashboards/, otherwise under ~/.amico/dashboards/ (never the
synced vault). The mode card (and its legacy mirror) points the record step at
the page instead of the nonexistent dashboard widget.

Part of #2140.
@jacktrnr jacktrnr self-assigned this Nov 6, 2026
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 80b2a21b-d00e-4980-addc-809b07edb900
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@jacktrnr
jacktrnr merged commit 2e241b1 into main Nov 7, 2026
12 checks passed
@jacktrnr
jacktrnr deleted the opencode/issue-2140-html-preview branch November 7, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant