Pages
Pages are Markdown documents with path-like slugs such as ops/runbook. Link between them with [[slug]] or [[slug|text]]. Every save is a new version; old versions stay readable.
opf pages.put slug=ops/runbook title="Ops runbook" body="## Deploy\n1. make dist …" if_version=0opf pages.get slug=ops/runbookopf pages.get slug=ops/runbook version=1opf pages.search query=deployopf pages.history slug=ops/runbook- Conflicts:
if_versionprevents overwriting someone else’s edit. The UI editor sends it automatically and shows a conflict instead of losing either version. - Unchanged saves: saving the same text again doesn’t create a version.
- In the UI: a list with search, a rendered view with breadcrumbs, an editor with preview and ⌘/Ctrl+S, and the history of every page.
The name “documents” is reserved for the JSON rows of collections.
Charts and key figures
Section titled “Charts and key figures”A page can show live data from collections. Write a fenced block named chart or kpi with one setting per line. The hub reads the rows when the page is shown and draws the result, so the numbers always come from the collection, never from whoever wrote the page. Agents can build dashboards this way without being able to fake a figure.
```kpicollection: kpi_tagwhere: lauf=maxsort: tagshow: kunden Customers, mrr MRR €, cash Cash €compare: 7```
```chart linetitle: MRRcollection: kpi_tagwhere: lauf=maxx: tagy: mrrlines: 250 Goalmarkers: events```kpi shows the last row (after sort) as tiles.
| Setting | Meaning |
|---|---|
collection |
The collection to read |
where |
Filters such as lauf=4, status=open; max or min picks the column’s largest or smallest value, e.g. the current run |
sort |
Column to order by; the last row is shown |
show |
column Label unit, separated by commas; the unit (€, %, $) is optional |
compare |
Show the change against the row this many rows earlier |
chart line or chart bar draws one or more columns over x.
| Setting | Meaning |
|---|---|
collection, where |
As above |
x |
A number or date column |
y |
One or more number columns, separated by commas |
series |
Split into one line per value of this column, e.g. series: run to compare runs |
group |
Sum y over buckets of this many x values, e.g. group: 7 for weeks of days |
| (bars) | Without group, a bar chart sums rows with the same x: x: run, y: ad_spend shows the total per run |
lines |
Reference lines, value label, separated by ;, e.g. 250 Goal; 0 |
markers |
A collection of events with the same x column and a text column (or marker_label), drawn as numbered markers and listed below the chart |
title |
Caption |
table lists rows, e.g. current metrics with a status badge:
```tablecollection: metricswhere: run=maxsort: ordercolumns: name Metric, display Value, status Statusbadges: statuslimit: 50```sort takes -column for descending order. Columns named in badges are shown as coloured badges: good/ok/green, bad/red, unclear/yellow (German values like gut, schlecht, unklar work too).
Hovering over a chart shows the values at that point. Charts follow light and dark mode and update when the data changes. A block with a mistake shows the reason instead of the chart.