b:
Text
b.markdown(text) renders Markdown. Raw HTML isn’t allowed.
b.code(code, { lang, title }) shows code or logs with a copy button. lang: "trace" highlights the first line of a stack trace and file locations; lang: "log" highlights file locations.
Fields
b.fields({ label: value }) shows labelled values. A value can be a string, a number, a boolean, a Date, or one of these:
b.ref(resource, id, title)links to a record. Items link to every record mentioned in their fields, and offer that record’s actions.b.sensitive(value, { hint })hides a value until someone allowed to reveals it. See Sensitive values.item.occurrences,item.users,item.firstSeen,item.lastSeenanditem.dueinsiderenderare live: they stay current as the item changes.
undefined values are left out, so optional fields need no special handling.
b.stats({ label: value }) shows the same values as large numbers, for the top of a page. A stat can carry a note: { value: 41, note: "of 120 seats" }.
Editing in place
b.edit(value, action) shows a value with a pencil next to it. Clicking it opens the action’s form with the value filled in:
{ field }. Everything about the action still applies: who may run it, its confirmation and its approval.
Records and tables
b.record(resource, id, title) shows a record as a link on its own line.
b.table(rows, columns) shows a table. Rows are objects; cells take the same values as fields, including b.ref and b.sensitive. Columns default to the keys of the first row.
Charts and timelines
b.chart(points, { title }) charts your own numbers, given as { at, value } pairs.
b.chart("occurrences", { range }) charts how often an item happened over "1h", "24h", "7d" or "30d", and b.chart(inbox, { range }) does the same for everything in an inbox. Pult keeps those numbers; your app only places the chart.
b.timeline(entries) shows a list of { at, text } events.
Buttons
b.actions(...) shows buttons that run actions:
record it runs on, a label and input to start the form with. Buttons for actions the viewer can’t run are left out. On records and pages, so are buttons whose action doesn’t apply to its record right now (its when says no), and actions with defaults start from them. The same goes for b.edit. Items keep their buttons as your app sent them. Pressing one works like anywhere else in the console: it runs straight away, or opens the form when the action has inputs or guardrails.
b.form(action) shows an action’s form right on the page instead of behind a button, for the things people do there all day, like broadcasting a message. It takes the same record, label and input as a button.
Inside a resource’s render, refer to the resource’s own actions by name, since the resource isn’t defined yet while it renders. They run on the record being shown:
From Pult
These blocks show Pult’s own data, worked out when someone looks, so they’re always current and only show what the viewer’s role allows:b.count(inbox, { filter, label })andb.count(view)show how many items match, linking to the list.b.items(inbox, { filter, limit, label })andb.items(view)show the latest few items.b.flag(flag)shows a flag and its value, with the switch for people allowed to change it.
Layout
b.columns([...], [...]) puts lists of blocks side by side, as many columns as you give it. On a phone they stack.
Attachments
b.attachment({ name, url }) links to a file your app hosts. To hand Pult the file itself, pass its contents and Pult stores it:
Sensitive values
reveal: true can reveal it on items, occurrences, records and pages, and every reveal is recorded on the item or record it came from and in the audit log. In tables of records, action results and history entries, sensitive values stay hidden for everyone. Triage never sees them.