cockpit html
Generated reference for cockpit html, including its syntax, options, results, and constraints from the canonical cockpit CLI source.
Some screens and steps may differ in the latest version.
This reference is generated from the same canonical source distributed as cockpit CLI help. See Cockpit CLI for concepts and safe operating guidance.
HTML surfaces render agent-generated HTML as an interactive screen attached to the current task. Prefer a surface over long Markdown when presenting comparisons, dashboards, or summaries with structure.
cat report.html | cockpit html show --stdin # Render an HTML surface for the current task
cockpit html get # Get the current HTML surface
cockpit html list # List HTML surfaces for the current task
cockpit side-panel html --surface-id latest # Open a surface in the right side panel
Isolated local JavaScript (Desktop and PWA)
Opt in by including <meta name="cockpit-scripts" content="isolated">. Inline <script> elements can then manipulate the surface DOM and calculate values. Authored scripts start after the document is parsed and the isolation guard is installed; if startup fails, they remain disabled. Bind events from a script with addEventListener or a property such as button.onclick; inline event attributes and javascript: URLs remain blocked. Scripts never run in display-only notices or outside an opted-in HTML Surface.
<meta name="cockpit-scripts" content="isolated">
<label>Quantity <input id="quantity" type="number" value="2"></label>
<output id="total">20</output>
<button id="toggle" type="button">Toggle chart</button>
<div id="chart">████</div>
<script>
const quantity = document.querySelector('#quantity');
quantity.addEventListener('input', () => {
document.querySelector('#total').textContent = String(Number(quantity.value) * 10);
});
document.querySelector('#toggle').addEventListener('click', () => {
const chart = document.querySelector('#chart');
chart.hidden = !chart.hidden;
});
</script>
The script frame has an opaque origin. It cannot read Cockpit's DOM, preload/IPC/Node APIs, other tasks, authentication, cookies, app storage, or local files. External scripts, styles, fonts, images, fetch/XHR/WebSocket, workers, media, WebRTC, form submission, navigation, downloads, popups, and top navigation are blocked. Use inline CSS and data/blob images or data fonts; existing external resources remain usable only in surfaces without this marker. Markup is re-parsed and sanitized until its serialization stabilizes (up to eight passes); unstable markup fails closed. Embedded pages and active metadata are removed, including a live-document sweep before scripts start and after mutations. Creating new embedded pages or realms, replacing the document, and browser editing commands are rejected. eval, Function, dynamic imports, and inline event attributes are unavailable. Use normal DOM operations for local state.
Local operations do not send agent messages. There is no public JavaScript agent API. Only a genuine user click on a marked action or validated submit control reaches the owning task through a private channel whose bootstrap is authenticated by a per-render capability removed before authored scripts run. Script-generated clicks, requestSubmit(), direct postMessage, arbitrary task IDs, and command payloads cannot send. --non-interactive still allows local calculations but never sends to an agent. Accepted action data is limited to 32 KiB, 128 field names (256 characters each), 128 values per field, and four actions per ten seconds. Actions are serialized while sending; failures can be retried by clicking again.
Search and element quotation use the isolated frame's bounded text bridge; search covers up to 24 KiB of UTF-8 text. Size updates and existing keyboard shortcuts work through the same channel. Updating, switching, or reopening a surface starts a fresh script context and closes the old channel. Runtime errors leave the HTML visible and show a recovery message; blocked navigation can replace the inner frame with a blocked document; reopen to restart or ask the task to fix the HTML.
Sending data back to the task
HTML without the script marker above keeps its existing script restrictions. For agent messages, mark controls and Cockpit sends the result to the task that owns the surface:
<form data-cockpit-action="review">
<textarea name="note"></textarea>
<button type="submit" value="approve">Approve</button>
<button type="submit" value="reject">Reject</button>
</form>
<button data-cockpit-action="deploy" data-cockpit-value="production">Deploy</button>
- Clicking a submit button inside a
<form>(a<button>withouttype="button", or<input type="submit">) sends one message, with or withoutdata-cockpit-action. Pressing Enter in a form field presses the form's first submit button. A form without a submit button never sends, and clicks elsewhere in the form, such as in a field, send nothing. - A submit button sends only when the form's
required,pattern,type, andmin/maxchecks pass; otherwise the surface points at the field.novalidateon the form orformnovalidateon the button skips the checks. - Clicking any other element with
data-cockpit-actionsends one message. actionis the element'sdata-cockpit-action, else the form's, elsesubmit.valueisdata-cockpit-value(ordata-cockpit-message), else the control'svalue, else the form'sdata-cockpit-value.labelis the control's text.fieldsholds everyinput,textarea, andselectin the form, or in the whole surface when there is no form, keyed byname.- The task receives it as its next message:
{ "type": "html_surface_action", "action": "review", "value": "approve", "label": "Approve", "fields": { "note": "..." } }
While sending, the surface shows a sending status; when the task cannot receive the message, the surface shows the reason. --non-interactive renders a read-only preview whose controls do not send.
Do not use HTML surfaces for browser navigation — use cockpit browser for real web pages.
Successful agent display requests leave a compact card in the task chat on Desktop and PWA. The card records the resolved target on this host and validates its host/task reference when opened; no prose link is needed. Desktop reopens the matching side panel. PWA opens that target in its existing task panel when the user taps the card, without switching away from a document on arrival. Closing the panel preserves the chat position and draft.
HTML cards refer to the saved Surface ID. Files and diffs show current content; Browser cards refer to the same host Identity, session, and tab, not a URL opened in the phone's browser. Deleted or unavailable targets report an error instead of opening another target. Display success means the host accepted the request, not that every device rendered it. Existing HTML unread notices are unchanged. Closing, resizing, manual panel selection, and reopening a card do not create another card. A transport retry reuses the operation ID; a new invocation can intentionally present the same target again.