All features

A manifest can bring its own HTML

Try the real interface

Explore this workspace.

Real Torbie UI · mock sessions
Tab bar
Loading Torbie…
Technical background

An integration may render a complete HTML document in place of the field list, given the data every fetch step returned. It runs in a frame with sandbox="allow-scripts" and nothing else — an opaque origin, no require, no process — behind a CSP that refuses the network outright.

The problem

A field list is the right shape for a ticket and the wrong shape for anything that wants a layout of its own — a chart, a table, a run of coloured badges. The manifest format has an html key for exactly that, and both repositories documented it as "reserved, not implemented in either fork", which was wrong and cost a rediscovery.

How it works

A manifest may carry a complete HTML document, rendered in place of the fields list and given window.__data — every fetch step's JSON, keyed by step id — and window.__uri. It talks back over chrome.webview.postMessage with {height} or {open}. tabby-links/INTEGRATIONS.md has the contract, htmlHost.ts builds the document, and stith.json is the worked example.

Settings
  • linkTooltip.allowHtml: true

    Render a plugin's own HTML. Off falls back to the plain field list.

Details
  • sandbox="allow-scripts", and nothing else, is the entire security story. Tabby's renderer is nodeIntegration: true, contextIsolation: false with no CSP anywhere in the app, so a plugin page that reached the parent realm would be require('child_process'), not XSS. Without allow-same-origin the frame is on an opaque origin and can do nothing but post a message. Verified live: window.origin === 'null', no require, no process, and reading into the frame from the host throws SecurityError.
  • A CSP is injected ahead of the document — default-src 'none', connect-src 'none' — which the WebView2 host this was ported from does not do. The page renders data already fetched and cannot call home. img-src https: is the one exception, for parity with an icon on a fields card.
  • srcdoc is written only when the card's key changes. Assigning it reloads the page and restarts its script, and the linkifier re-asks many times a second during output.
  • The page could not be verified in the hidden dev build. Chromium throttles rendering for a cross-origin subframe that is never visible, so every measurement inside it reads 0 — a height: 77px div included. The test gives the page its own window, shown without focus and off-screen, purely so a compositor runs.
What this does not claim
  • This is a port of a contract the originating fork cannot run: its WebView2 host is compiled behind a feature flag with no WebView2Loader.dll shipped, so html there always falls back to fields. This fork is the only place the key does anything.
  • Measure document.body.scrollHeight, not documentElement's — the latter is the frame's own viewport, so a page reporting it just asks to stay the size it already is. A silent no-op that looks exactly like a broken channel.
Source commits
LinksAdded 2026-09-0412 files+742 / −34 lines