Canvas hex grid
The hex grid is the spatial substrate of every workspace. Each element occupies one hex; the workbench is the same interactive surface, just zoomed in. Below: a strip of representative kinds at canvas scale, and a live mount of the canvas overlay layer over a fixture automation.
Workbench
Live portal-side specimens of workbench components, mounted in isolation above the generated metadata catalog. Each card below is the real Leptos component running with default in-memory state (no API, no auth) so the actual chrome — toolbars, palettes, source editors, inspectors — is visible and interactive, not a static mockup.
Connector settings
Contacts
SQL console
select name, state, updated_at
from contacts
where state = 'qualified';Preview
Workbench
workbench-agent-chat
#existingsourceThe working surface for element types operated as a conversation — the user writes a message, the agent responds, and turns stream back into a scrolling thread. Unlike workbench-terminal there is no PTY: the agent has no real shell, only a conversational contract. Tool calls and intermediate steps surface inline in the thread as the turn unfolds.
When to use
- An element type is a composable conversational agent (triformer) with no real terminal.
- Interaction is turn-based messaging, not raw keystroke passthrough.
- A human-in-the-loop element collects a decision through a message exchange (hitl).
When not to use
- The element runs a real CLI process — use workbench-terminal.
- The element edits source files as its primary job — use workbench-code-editor.
- The element is a connector or modifier configured through a form — use workbench-config-form.
Accessibility
Role: region
- Enter — Sends the composed message when the composer is focused.
- Shift+Enter — Inserts a newline in the composer without sending.
Screen reader: The thread is a live region that announces each new turn. The composer is a labelled multiline textbox; streaming responses announce on completion.
Notes: Announce turn boundaries, not every streamed token, to avoid flooding assistive tech during a long response.
Workbench surface
Holds
- message (many) — A single turn in the thread — a user message or an agent response.
- composer (one) — The input area where the user writes the next turn.
Sections
- conversation — The scrolling message thread + composer — the primary working area.
- readme — The element's README / intent documentation.
- history — Past conversations and threads with this agent.
Interaction: A conversation workbench binds a message thread to an agent element. The user composes a message and sends it; the agent's response — including tool calls and intermediate steps — streams back as one or more turns appended to the thread. Interaction is strictly turn-based: there is no raw input passthrough and no live process, only the conversational request/response contract.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
title | string | Agent conversation | Human-readable title for the conversation workbench chrome. |
state | enum: idle | streaming | waiting | streaming | Current turn lifecycle shown in the thread chrome. |
unread_turns | integer | 0 | Count of newly appended turns that have not been reviewed. |
Examples
A deterministic conversation surface: thread, tool call, and composer.
YAML
type: card
props:
title: Agent conversation
subtitle: Triformer · streaming
style: flat
padding: relaxed
slots:
default:
- type: stack
props:
direction: column
gap: md
children:
- type: stack
props:
direction: row
gap: sm
align: center
children:
- type: badge
props:
variant: primary
slots:
default: agent
- type: badge
props:
variant: info
slots:
default: tool call queued
- type: text
props:
kind: muted
value: 'User: summarize the open run and list the next safe action.'
- type: text
props:
value: 'Triformer: I found three blockers. The next action is to validate the showroom gate before adoption.'
- type: textarea
props:
value: Ask a follow-up…
rows: 2workbench-board-panel
#existingsourceThe working surface for board element types — a kanban of columns and cards. The user moves cards across columns, opens a card for detail, and edits card metadata. Generic boards and the domain-specialised boards (sales, planning, recruitment) all open into this same surface; specialisation is configuration on the element, not a different workbench. Board panel registration and its overview metadata are declared in chemistry/shell/panels/board/shell.yaml and emitted into generated shell layout constants, matching Browser and Terminal.
When to use
- An element type IS a kanban — columns, cards, and card movement (board, sales-board).
- Work is tracked as cards progressing through declared phases.
- The element wants drag-and-drop card flow with per-card metadata.
When not to use
- The data is tabular rows without a phase/column model — use workbench-record-viewer.
- The element is a node/edge graph — use workbench-graph-canvas.
- The element is configured, not operated as a board — use workbench-config-form.
Accessibility
Role: region
- Arrow-keys — Move focus between cards and columns.
- Space — Picks up / drops the focused card for keyboard-driven moves.
Screen reader: Each column is a labelled list; each card is a list item naming its column and position. Card moves announce the source and destination column.
Notes: Drag-and-drop must have a full keyboard equivalent — pick up, move, drop.
Workbench surface
Holds
- column (many) — A phase column that holds an ordered list of cards.
- card (many) — A unit of work with free-form metadata, living in one column.
Sections
- board — The kanban of columns and cards — the primary working area.
- readme — The element's README / intent documentation.
- history — Card movement and board change history.
Interaction: A kanban workbench renders the board's declared columns and the cards within them. The user drags cards between columns (or moves them by keyboard), opens a card to view and edit its metadata, and adds or archives cards. Column structure and card schema come from the element's spec.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
title | string | Board | Human-readable board title. |
columns | integer | 3 | Number of phase columns currently visible. |
selected_card | string | — | Identifier or title of the focused card. |
Examples
A kanban working surface with phase columns and card metadata.
YAML
type: card
props:
title: Recruitment board
subtitle: 3 columns · 8 active cards
style: flat
padding: relaxed
slots:
default:
- type: table
props:
caption: Board phases
columns:
- Backlog
- Interview
- Offer
rows:
- - UX review
- Frontend panel polish
- Reference checks
- - Showroom gate
- Element map QA
- Final offer
- type: stack
props:
direction: row
gap: sm
align: center
children:
- type: badge
props:
variant: success
slots:
default: keyboard moves enabled
- type: badge
props:
variant: muted
slots:
default: drag optionalworkbench-browser-panel
#existingsourceThe working surface for element types that ARE a headless browser — a real Chromium running in a sandboxed VM, streamed to the portal as encoded video (WebRTC) or JPEG frames. The user drives the page directly: clicks, typing, and navigation pass through to the remote browser. It is one of the two live-session workbenches; its chrome, transport, lifecycle, and input model are identical to workbench-terminal — only the streamed payload differs (a rendered page instead of a PTY byte stream). Browser panel registration and multi-session overview metadata are declared in chemistry/shell/panels/browser/shell.yaml and emitted into generated shell layout constants.
When to use
- An element type IS a browser session the user drives directly (chromeless, user-browser).
- The element needs a live rendered page — tabs, navigation, a screencast viewport.
- Session continuity matters — cookie state and open tabs survive across visits.
When not to use
- You only need to preview a frontend the platform serves — use workbench-web-preview.
- The element is a command-line process — use workbench-terminal, the sibling live-session workbench.
- The element is a static data source with no live render — use workbench-record-viewer.
Accessibility
Role: application
- all-keys — While the viewport is focused, keystrokes and pointer events forward to the remote page.
- Escape — Releases focus back to the surrounding panel chrome.
Screen reader: The remote page's own accessibility tree is surfaced via the session's accessibility-ref model. The tab bar is a labelled toolbar.
Notes: A live-session surface traps input by design — the focus-release affordance (Escape) must always be reachable and documented in the chrome.
Workbench surface
Holds
- tab (many) — An open browser tab — a navigable page within the session.
- viewport (one) — The live streamed render of the active tab.
Sections
- browser — The live tabbed browser viewport — the primary working area.
- readme — The element's README / intent documentation.
- history — Past sessions, snapshots, and navigation history.
Interaction: A live-session workbench attaches to a remote process running in a sandboxed VM and streams it to the portal over a WebSocket. The user interacts with the remote process directly: keystrokes and pointer events are passed through unmodified, and the surface streams back continuously (a PTY byte stream for a terminal, an encoded video/JPEG frame stream for a browser). The session has an explicit lifecycle — start, suspend (VM snapshot), resume (snapshot restore, sub-second), stop — surfaced as a session/tab bar above the live viewport. Terminal and browser-panel are the same surface with a different payload; their chrome, transport, lifecycle, and input model are identical.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
address | string | https://triform.dev/components/ | Address shown for the active streamed tab. |
transport | enum: webrtc | standby | webrtc | Current browser viewport transport state. |
focused | boolean | false | Whether pointer and keyboard input are currently captured by the remote page. |
Examples
A live browser-session shape using the shared chrome and viewport primitives.
YAML
type: stack
props:
direction: column
gap: none
children:
- type: browser-chrome
props:
mode: miniature
address: https://triform.dev/components/
tabs:
- id: c
title: Components
active: true
loading: false
- id: h
title: Health
active: false
loading: false
- type: browser-viewport
props:
mode: miniature
source: standby
loading: trueworkbench-code-editor
#existingsourceThe working surface for element types whose primary content is authored text — function handler code, prompt bodies, validation rules, documents. The user edits source in one or more buffers, navigates a file tree, and saves. Unlike a live-session workbench there is no streamed remote process; editing is local to the buffer and committed on save.
When to use
- An element type's content IS source the user authors (python, javascript, rust-fn, document).
- The element needs syntax-aware editing, a file tree, and save semantics.
- A modifier's body is authored text — a prompt, a validation rule, an expression.
When not to use
- The element drives a live process — use workbench-terminal.
- The element is configured through structured fields, not free text — use workbench-config-form.
- The element is a data store browsed as records — use workbench-record-viewer.
Accessibility
Role: application
- all-keys — While a buffer is focused, the editor captures editing keystrokes and shortcuts.
- Escape — Releases focus from the buffer back to the surrounding panel chrome.
Screen reader: Each buffer is a labelled multiline textbox; the file tree is a labelled tree. Cursor position and diagnostics are announced on navigation.
Notes: A code editor traps editing keys by design — keep the focus-release affordance reachable and documented.
Workbench surface
Holds
- source-buffer (many) — An open, editable text buffer backing one file of the element.
- file-tree (one) — The navigable tree of files belonging to the element.
Sections
- editor — The active source buffer — the primary working area.
- files — The element's file tree.
- readme — The element's README / intent documentation.
- history — Version and edit history for the element's content.
Interaction: An editor workbench presents the element's content as one or more editable source buffers alongside a file tree. The user edits text locally in a buffer and commits with an explicit save; there is no streamed remote process. Running the element is a separate explicit action invoked from the chrome.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
active_file | string | src/main.rs | Path of the buffer currently focused in the editor. |
language | string | rust | Syntax language for the active buffer. |
dirty | boolean | false | Whether the active buffer has unsaved edits. |
Examples
A source-editing surface with file context, code body, and status.
YAML
type: card
props:
title: src/main.rs
subtitle: rust · saved
style: flat
padding: relaxed
slots:
default:
- type: code-block
props:
language: rust
code: |-
pub fn handle(input: Value) -> Result<Value> {
run_action(input)
}
- type: stack
props:
direction: row
gap: sm
align: center
children:
- type: badge
props:
variant: success
slots:
default: saved
- type: badge
props:
variant: muted
slots:
default: Ln 2 · UTF-8workbench-connector
#existingsourceThe working surface for io/* connector elements that operate an external service. It mounts the real ConnectorPanel: connection/auth state, a one-click executor toggle when the connector supports multiple transports, and the scan/send/configure CTAs the element declares in cta.yaml. Unlike the generic props rail, a connector has a live external boundary to operate, so it earns a centered working surface. This component names the surface that shell_role: connector elements already mount today — making the declared meta.workbench honest rather than changing behaviour.
When to use
- An element type operates an external service through a declared connector boundary (io/* with shell_role: connector and connector_data).
- The user needs connection state, an executor/transport toggle, and the element's CTAs in one centered surface.
When not to use
- The element is configured but has no external boundary to operate — use workbench-props.
- The element has a live streamed process — use workbench-terminal or workbench-browser-panel.
- No connector_data is emitted for the element type — ConnectorPanel would fall through; use workbench-props instead.
Accessibility
Role: application
- Tab — Moves between connection controls, the executor toggle, and the CTA buttons.
- Enter — Activates the focused CTA or toggle.
Screen reader: Connection state is announced as a labelled status region; CTAs are labelled buttons; the executor toggle announces the active transport.
Notes: The CTAs rendered are exactly those declared in the element's cta.yaml; the panel never hardcodes per-service actions.
Workbench surface
Holds
- connection-state (one) — The connector's live connection/auth state and executor selection.
- cta (many) — A call-to-action the element declares in cta.yaml (scan, send, configure, ...).
Sections
- connection — Connection/auth state and the executor toggle — the primary working area.
- actions — The element's declared CTAs.
- readme — The element's README / intent documentation.
Interaction: A connector workbench mounts the real ConnectorPanel: it shows connection state, exposes an executor toggle when multiple transports exist, and renders the element's declared CTAs. The user operates the external service from this centered surface. Routing is via shell_role: connector, which the portal resolves before the generic workbench-center dispatch; this component makes that mapping explicit in meta.workbench without altering runtime behaviour.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
title | string | Connector | Title for the connector working surface. |
connection_state | enum: disconnected | connecting | connected | error | disconnected | Current connection/auth state for the external service. |
Examples
A connector workbench with connection state and the element's CTAs.
YAML
type: card
props:
title: Slack connector
subtitle: connected · 2 transports
style: flat
padding: relaxed
slots:
default:
- type: stack
props:
direction: row
gap: sm
align: center
children:
- type: badge
props:
variant: success
slots:
default: connected
- type: button
props:
variant: primary
size: small
slots:
default: Send
- type: button
props:
variant: secondary
size: small
slots:
default: Scanworkbench-diagram-canvas
#existingsourceThe working surface for diagram elements — a canvas that renders Mermaid text as visual BPMN-style and UML diagrams. Mermaid is the canonical portable source format; the workbench exposes mode-specific views (flowchart, sequence, class, state, ER, requirement, architecture) and inline editing of both the textual source and node-level metadata (Name, Intention, Readme, Requirements) so a diagram can later become a template or materialization input.
When to use
- An element IS a planning diagram in BPMN or UML form (diagram).
- The user works visually with shapes/edges, but Mermaid text is the source of truth.
- Mode switching across flowchart/sequence/class/state/ER variants is part of the working flow.
When not to use
- The element is a runtime topology of real elements — use workbench-graph-canvas.
- Only freeform text editing is needed without a rendered preview — use workbench-code-editor.
- You mean the workspace backdrop — that is the root canvas, not a workbench.
Accessibility
Role: application
- Tab — Move focus between the source editor, mode switcher, and rendered canvas.
- Arrow-keys — Pan the rendered canvas; with a node focused, walk along edges.
- Plus-Minus — Zoom the rendered canvas in and out.
Screen reader: The Mermaid source is exposed as a labelled text region; each rendered node is announced with its label and shape role; edge traversal announces source and target node labels. A non-spatial list view of nodes is offered as an alternative to the canvas.
Notes: Source-first dual-view (text + canvas) means an assistive-tech user can always fall back to the textual Mermaid representation, which is the canonical truth.
Workbench surface
Holds
- node (many) — A shape or activity in the diagram, selectable to inspect or edit its metadata.
- edge (many) — A connection between two nodes (flow, message, association, transition).
Sections
- source — The Mermaid text — canonical portable source.
- canvas — The rendered diagram — the primary visual working area.
- modes — Mode switcher across BPMN/UML variants (flowchart, sequence, class, …).
- readme — The element's README / intent documentation.
Interaction: A source-first visualization workbench. Mermaid text is the canonical representation; the canvas renders that source visually so the user can work spatially when that suits the diagram type. Edits to either side keep the other in sync. Mode switching reframes the rendered output without losing the underlying source.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
mode | string | flowchart | Active diagram mode: flowchart | sequence | class | state | er | requirement | architecture. |
node_count | integer | 0 | Number of nodes in the current diagram. |
edge_count | integer | 0 | Number of edges in the current diagram. |
Examples
A BPMN-style flowchart diagram canvas with three nodes and the source editor visible.
YAML
type: card
props:
title: Onboarding flow
subtitle: flowchart · 3 nodes · 2 edges
style: flat
padding: relaxed
slots:
default:
- type: stack
props:
direction: row
gap: md
align: center
children:
- type: element-hexagon
props:
kind: diagram
symbol: Dg
name: Diagram
category: diagrams
icon_name: account_tree
icon_color: '#0EA5E9'
form: atom
state: active
- type: code-block
props:
language: mermaid
code: |
flowchart LR
A[Sign up] --> B{Email verified?}
B -->|yes| C[Active]workbench-element-runner
#partialsourceThe working surface for invocable elements — Python and SQL today, every language and query element tomorrow. The user edits the element body on the left, selects or types a fixture on the right, fires the primary CTA, and watches output stream in. Past runs surface in a strip below for one-click replay. The workbench is element-agnostic: every behaviour that differs between element types (the primary CTA label, the input schema, the editor language) flows from that element's YAML, never from portal branches.
When to use
- An element type is invocable — it has a body the user authors and an op that consumes that body plus an input payload.
- The natural working flow is: edit → fixture → fire → watch → replay.
- Examples: python functions, sql queries, javascript handlers.
When not to use
- The element is a long-lived live session (terminal, browser-panel) — use workbench-terminal / workbench-browser-panel.
- The element is browsed not invoked (files, contacts) — use workbench-files-grid / workbench-record-viewer.
- The element is configured but not run (validation, brand, api-token) — use workbench-config-form.
Accessibility
Role: region
- Ctrl-Enter — Fire the primary CTA (Run / Query / Execute) without leaving the input editor.
- Esc — Cancel the in-flight run. No-op when nothing is running.
- Up/Down in History strip — Navigate past runs; Enter replays the focused row.
Screen reader: The output stream is announced through an aria-live=polite region — status pulses and result/error frames are read as they arrive. The history strip is a labelled list of past runs with status + duration + relative-time; each row exposes a replay action.
Notes: Long stderr/stdout streams must not flood the screen reader — the live region announces status transitions and the terminal frame summary, not every individual line.
Workbench surface
Holds
- editor (one) — The element body the user authors — code (python/sql/js), a query, a handler. Element-type chooses the editor language; the editor itself is generic.
- fixtures (many) — Saved test-input payloads. Selecting a fixture pre-populates the input editor; the user can also type ad-hoc input without saving.
- input (one) — The JSON payload the next run will use. Always editable; reflects the selected fixture or the user's ad-hoc edits.
- controls (one) — The primary CTA (Run/Query/Execute), Cancel, and Retry affordances. Labels come from the element's cta.yaml.
- output (one) — The live stream of status / stdout / stderr / result / error frames from the current or most-recent run.
- history (many) — A strip of recent past runs — status chip, duration, relative time, click-to-replay.
Sections
- editor — The element body editor — primary working area on the left.
- runner — Fixtures + input editor + primary CTA + cancel/retry strip.
- output — The live event stream of the current or most-recent run.
- history — Past runs with replay affordances.
- readme — The element's README / intent documentation tab.
Interaction: An editor workbench centred on the invoke flow. The user authors the element body on the left and prepares a run on the right: pick a saved fixture or type one ad-hoc, fire the primary CTA, watch frames stream into the output panel, then either replay from history or tweak the input and fire again. Cancel terminates the in-flight run; retry re-fires with the same fixture + input. The history strip surfaces the last N runs for this element — every row is clickable for drill-in and replay.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
element_path | string | my-circle/my-fn | Flat element path used to build the /api/{circle}/{path}/ops/{op} URL. |
element_type | string | python | Element type — used to pick the editor language and dispatch the right cta.yaml lookup. NEVER branched on in portal code. |
primary_cta_label | string | Run | Label of the primary CTA button — resolved from the element's cta.yaml `ctas.<primary>.label`, not hardcoded. |
has_fixtures | boolean | false | Whether the element has saved fixtures available (drives the fixtures panel's empty-state vs strip). |
is_running | boolean | false | Whether a run is currently in flight (drives CTA disabled state and Cancel affordance visibility). |
Examples
An empty runner workbench just before the first run, with one fixture saved.
YAML
type: card
props:
title: my-python-fn
subtitle: 1 fixture · no runs yet
style: flat
padding: relaxed
slots:
default:
- type: markdown-view
props:
text: |
**Left column** — Python editor with the handler scaffold.
**Right column**
- Fixtures: `default-input` (1 saved)
- Input editor: `{}`
- Primary CTA: `Run`
- Output stream: empty
- History strip: emptyworkbench-files-grid
#existingsourceThe working surface for file-store elements — a navigable folder tree beside a preview of the selected file. The user browses directories, previews and opens files, and uploads new ones. It is a data-grid workbench: the shared browse-and-detail grammar, specialised here for a hierarchical file store.
When to use
- An element type IS a file store — folders and files (files).
- The user browses a directory tree and previews file contents.
- Upload, download, and file organisation are part of the working flow.
When not to use
- The data is relational rows — use workbench-record-viewer or workbench-sql-console.
- A single document is authored as text — use workbench-code-editor.
- The element is a node/edge graph — use workbench-graph-canvas.
Accessibility
Role: region
- Arrow-keys — Navigate the folder tree and file list.
- Enter — Opens the focused file in the preview pane.
Screen reader: The folder tree is a labelled tree; the file list is a labelled grid. The preview pane announces the selected file's name and type.
Notes: Upload progress should be announced via a live region, not only visually.
Workbench surface
Holds
- file-tree (one) — The navigable hierarchy of folders and files in the store.
- file-preview (one) — The rendered preview of the currently selected file.
Sections
- files — The folder tree and file list — the primary working area.
- preview — The preview of the selected file.
- readme — The element's README / intent documentation.
- history — Upload, change, and access history.
Interaction: A data-grid workbench presents the element's data as a browsable surface with a detail view. In the files grid the browse axis is a folder hierarchy: the user navigates the tree, selects a file, and the preview pane renders it; upload and download are explicit actions in the chrome.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
selected_path | string | /docs/readme.md | Path currently selected in the folder tree. |
file_count | integer | 0 | Number of files shown in the active directory. |
upload_state | enum: idle | uploading | failed | idle | Current upload lifecycle for the file workbench. |
Examples
A files workbench with directory rows and a selected preview.
YAML
type: card
props:
title: /docs
subtitle: 4 files · readme.md selected
style: flat
padding: relaxed
slots:
default:
- type: table
props:
columns:
- Name
- Type
- Size
rows:
- - readme.md
- Markdown
- 18 KB
- - contract.json
- JSON
- 6 KB
- - screenshot.png
- Image
- 240 KB
- type: markdown-view
props:
text: |-
### Preview
Generated file-store documentation preview.workbench-graph-canvas
#existingsourceThe working surface for graph data elements — nodes and edges laid out on a pan/zoom canvas. The user explores the graph spatially, selects nodes to inspect them, and traverses edges. It is a visualization workbench: the content's own shape (its topology) is the layout, distinct from the workspace canvas, which is the root surface, not a workbench.
When to use
- An element type IS a node/edge graph the user explores (graph).
- Topology — what connects to what — is the thing being worked with.
- Spatial pan/zoom exploration suits the data better than rows or columns.
When not to use
- The data is tabular rows — use workbench-record-viewer.
- The data is a kanban of phased cards — use workbench-board-panel.
- You mean the workspace backdrop — that is the root canvas, not a workbench.
Accessibility
Role: application
- Arrow-keys — Pan the canvas; with a node focused, move selection along edges.
- Plus-Minus — Zoom the canvas in and out.
Screen reader: Each node is a labelled item naming its degree; edge traversal announces the source and target node. A list view of nodes is offered as a non-spatial alternative.
Notes: A spatial canvas needs a non-spatial fallback — expose the node/edge set as a navigable list for assistive tech.
Workbench surface
Holds
- node (many) — A vertex in the graph, selectable to inspect its detail.
- edge (many) — A connection between two nodes, traversable from either end.
Sections
- graph — The pan/zoom node-edge canvas — the primary working area.
- readme — The element's README / intent documentation.
- history — Graph mutation history.
Interaction: A visualization workbench lays the element's content out by its own intrinsic shape. In the graph canvas that shape is topology: nodes and edges are placed on a pan/zoom surface, the user explores spatially, selects a node to inspect it, and follows edges to traverse. This is distinct from the workspace canvas, which is the root backdrop rather than an element's workbench.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
selected_node | string | invoice:1024 | Node currently selected on the graph canvas. |
node_count | integer | 0 | Number of nodes currently loaded. |
edge_count | integer | 0 | Number of edges currently loaded. |
Examples
A topology surface with graph metrics and a selected node payload.
YAML
type: card
props:
title: Invoice graph
subtitle: 24 nodes · 31 edges
style: flat
padding: relaxed
slots:
default:
- type: stack
props:
direction: row
gap: md
align: center
children:
- type: element-hexagon
props:
kind: sql
symbol: SQL
name: SQL
category: data
icon_name: database
icon_color: '#3B82F6'
form: store
state: active
- type: element-hexagon
props:
kind: graph
symbol: Gr
name: Graph
category: data
icon_name: hub
icon_color: '#06B6D4'
form: store
state: pulse
- type: element-hexagon
props:
kind: queue
symbol: Qu
name: Queue
category: io
icon_name: queue
icon_color: '#EC4899'
form: connector
state: attention
- type: json-viewer
props:
json:
selected_node: invoice:1024
outgoing:
- customer:acme
- payment:paidworkbench-props
#existingsourceThe honest reused working surface for element types that have no dedicated, purpose-built workbench. Focusing the element reveals the right-edge magnetic Properties rail — exactly the surface a user gets by hovering the right edge — populated with that element's real spec sections (Readme, Properties, Contract, Actions, Cost, History, Activity, ...). The canvas stays visible as the center; the rail is a docked companion, not a center swap. Nothing is fabricated: the rail reads the live focused element. This replaces the fake-data config-form / record-viewer / sql-console specimens for every element that lacks a real working surface.
When to use
- An element type has no purpose-built workbench (most modifiers, secondary IO, lab facets, automation control-flow, generic data stores).
- The element is configured/inspected through its spec sections rather than operated through a live surface.
- A real dedicated workbench does not exist yet — props is the honest interim, never a placeholder specimen.
When not to use
- The element has a live process — use workbench-terminal or workbench-browser-panel.
- The element's content is authored free text or code — use workbench-code-editor.
- The element is a connector with a real ConnectorPanel — use workbench-connector.
- The element is a container of other elements — it has no workbench; it drills the canvas (meta.workbench: none).
Accessibility
Role: complementary
- Tab — Moves between the rail's section rows and, within a section, its fields.
- Enter — Opens the focused section / activates the focused control.
Screen reader: The rail is a labelled "Properties" region; each section is a labelled row, and opening a section announces its content. Focus changes update the rail's contents to the newly focused element.
Notes: The rail's section list follows the element's sections_for_element_type, so the structure matches the element's own properties model. The rail reveals transiently (like hover) and folds back on pointer-leave — it never replaces the canvas.
Workbench surface
Holds
- properties-section (many) — A named section of the focused element's properties (Readme, Properties, Contract, Actions, Cost, History, ...).
Sections
- readme — The element's README / intent documentation.
- properties — The element's spec fields — the primary working area.
- contract — The element's input/output contract.
Interaction: Focusing the element reveals the right-edge magnetic Properties rail (the same surface as hovering the right edge) populated with the element's real spec sections. The reveal is transient — it folds back on pointer-leave, mirroring the hover gesture — and does NOT change the center view; the canvas stays. The rail reads the live focused element through the focus context, so the content is always the element's actual properties, never placeholder data.
Elements using this workbench
- alert
- api-token
- auth-policy
- brain
- brand
- condition
- contacts
- cookie-jar
- ears
- entity
- external-agent
- filter-words
- icp
- loop
- matrix
- mattermost
- mouth
- oauth
- oauth-client
- organizations
- phone-number
- platform
- platform-trigger
- queue
- rate-limit
- recorder
- rocketchat
- schedule
- schema
- sql
- teams
- timeseries
- vector
- wait
- websocket
- wire
Props
| Name | Type | Default | Description |
|---|---|---|---|
title | string | Properties | Header label for the properties rail panel. |
Examples
An element's properties revealed as the right-edge rail's section list.
YAML
type: card
props:
title: Properties
subtitle: Readme · Properties · Contract · Cost
style: flat
padding: relaxed
slots:
default:
- type: stack
props:
direction: column
gap: xs
children:
- type: button
props:
variant: ghost
size: small
slots:
default: Readme
- type: button
props:
variant: ghost
size: small
slots:
default: Properties
- type: button
props:
variant: ghost
size: small
slots:
default: Contractworkbench-terminal
#existingsourceThe working surface for terminal-capable agent elements operated as an interactive command-line session — a real PTY running inside a sandboxed Firecracker VM, bridged to the portal over a WebSocket. The overview is element-backed: Claude Code, Open Code, and Codex elements appear as tiles, and selecting one opens that element's PTY stream. Sessions snapshot when idle and restore in sub-second time. It is one of the two live-session workbenches; its chrome, transport, lifecycle, and input model are aligned with workbench-browser-panel. Terminal panel registration and multi-session overview metadata are declared in chemistry/shell/panels/terminal/shell.yaml and emitted into generated shell layout constants.
When to use
- An element type IS a command-line process the user drives directly (claude-code, open-code, codex).
- The element needs a real shell — PTY semantics, raw keystrokes, terminal control codes.
- Session continuity matters — suspend/resume via VM snapshot across visits.
When not to use
- The element is a conversational agent with no real terminal — use workbench-agent-chat.
- The element edits source files rather than driving a live process — use workbench-code-editor.
- The element renders a web page — use workbench-browser-panel, the sibling live-session workbench.
Accessibility
Role: application
- all-keys — While focused, the terminal captures all keystrokes and forwards them to the remote PTY.
- Escape — Releases focus back to the surrounding panel chrome.
Screen reader: The live region announces new terminal output. The session/tab bar is a labelled toolbar; each session is a tab naming its lifecycle state.
Notes: A live-session surface traps the keyboard by design — the focus-release affordance (Escape) must always be reachable and documented in the chrome.
Workbench surface
Holds
- pty-session (one) — A live pseudo-terminal stream bound to a process in the sandbox VM.
Sections
- terminal — The live PTY viewport — the primary working area.
- readme — The element's README / intent documentation.
- history — Past sessions, snapshots, and transcript history.
Interaction: A live-session workbench attaches to a remote process running in a sandboxed VM and streams it to the portal over a WebSocket. The user interacts with the remote process directly: keystrokes and pointer events are passed through unmodified, and the surface streams back continuously (a PTY byte stream for a terminal, an encoded video/JPEG frame stream for a browser). The session has an explicit lifecycle — start, suspend (VM snapshot), resume (snapshot restore, sub-second), stop — surfaced as a session/tab bar above the live viewport. Terminal and browser-panel are the same surface with a different payload; their chrome, transport, lifecycle, and input model are identical.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
session_id | string | term-1 | Stable identifier of the attached terminal session. |
lifecycle | enum: starting | running | suspended | stopped | running | Terminal VM session lifecycle shown in the tab bar. |
cwd | string | /workspace | Current working directory shown in the terminal chrome. |
Examples
A terminal-backed live-session workbench with status and output.
YAML
type: card
props:
title: Terminal session
subtitle: running · /workspace
style: flat
padding: relaxed
slots:
default:
- type: code-block
props:
language: shell
code: |-
$ triform status
showroom gate: 190 live / 0 static
next: begin platform adoption
- type: stack
props:
direction: row
gap: sm
align: center
children:
- type: badge
props:
variant: success
slots:
default: snapshot ready
- type: badge
props:
variant: muted
slots:
default: PTY attachedworkbench-web-preview
#existingsourceThe working surface for frontend element types — a viewport that renders the live URL the platform serves for the element. The user sees the deployed result of the frontend (a single-page app, a server-rendered page, a 3D scene, a view) and reloads to pick up changes. Unlike workbench-browser-panel it is not a sandboxed browser the user drives arbitrarily — it is pinned to the element's own served URL.
When to use
- An element type renders a frontend the platform serves (spa, ssr, three-d, view).
- The working need is to SEE the deployed result, not to drive an arbitrary browser.
- Reload-to-refresh against the element's own URL is the core loop.
When not to use
- The element is a general-purpose browser the user navigates freely — use workbench-browser-panel.
- The element's content is authored source — use workbench-code-editor.
- The element is configured through fields — use workbench-config-form.
Accessibility
Role: region
- KeyR — Reloads the preview viewport.
- Tab — Moves into the rendered frame's own focusable content.
Screen reader: The rendered frontend carries its own accessibility tree. The preview chrome announces load state and the served URL.
Notes: Preview chrome announces load state and served URL; the rendered frontend owns the accessibility tree inside the viewport.
Workbench surface
Holds
- viewport (one) — The live render of the frontend element's served URL.
- address-bar (one) — The served URL and load state of the preview.
Sections
- preview — The live rendered viewport — the primary working area.
- readme — The element's README / intent documentation.
- history — Deploy and render history.
Interaction: A preview workbench renders the live URL the platform serves for the element inside a viewport. The user views the deployed result and reloads to pick up changes; the viewport is pinned to the element's own URL rather than being a freely navigable browser.
Elements using this workbench
Props
| Name | Type | Default | Description |
|---|---|---|---|
url | string | https://triform.dev/apps/demo | Platform-served URL being previewed. |
load_state | enum: loading | ready | failed | ready | Current preview frame loading state. |
viewport | enum: desktop | tablet | mobile | desktop | Viewport preset used by the preview frame. |
Examples
A pinned frontend preview, distinct from the freely navigable browser workbench.
YAML
type: stack
props:
direction: column
gap: sm
children:
- type: card
props:
title: Preview
subtitle: desktop · ready
style: flat
padding: tight
slots:
default:
- type: text
props:
kind: muted
value: https://triform.dev/apps/acme-dashboard
- type: browser-viewport
props:
mode: miniature
source: cached_frame
url: https://triform.dev/assets/showcase/browser-frame-sample.png
loading: false