Manifest Reference
Every field the OpenIslands manifest schema accepts, generated from @openislands/schema.
Generated from
@openislands/schemabyscripts/gen-reference.ts. Do not edit by hand. Runpnpm gen:referenceto refresh it after a schema change.
A manifest is the typed declaration of a data app: the datasets it reads, the pages and islands that render them, the optional actions and connectors that write to them, and the queries that read from them. This page documents every field the schema accepts. The schema is the single source of truth: the CLI, runtime, and MCP server all validate against it, so an island bound to a field that doesn't exist fails the build and names the island.
Top level
A manifest is a JSON object with the following top-level shape:
{
"version": 1, // required: the manifest format version, always 1
"title": "Finance Overview", // required: the app title
"icon": "wallet", // optional: the app's tile icon in the workspace app rail
"datasets": { /* ... */ }, // required: named data sources (see Datasets)
"pages": [ /* ... */ ], // required: the app's pages (see Pages)
"actions": { /* ... */ }, // optional: typed data writes (see Actions)
"queries": { /* ... */ }, // optional: typed, parameterized reads (see Queries)
"connectors": { /* ... */ } // optional: vendored sync integrations (see Connectors)
}| Field | Type | Required | Description |
|---|---|---|---|
version | 1 | yes | The manifest format version. Always 1. |
title | string | yes | The app title, shown in the chrome. |
icon | string | no | One of the curated icon names, used for the app's tile in the workspace app rail. |
datasets | object | yes | A map of dataset name to a dataset declaration. See Datasets. |
pages | array of object | yes | The app's pages, one sidebar entry each. See Pages. |
actions | object | no | A map of action name to an action declaration. See Actions. |
queries | object | no | A map of query name to a query declaration. See Queries. |
connectors | object | no | A map of connector name to a connector declaration. See Connectors. |
Datasets
datasets maps each dataset name to a source. A dataset is one of three shapes: a
file source, a SQL transform, or a SQLite table.
"datasets": {
"net_worth": { "source": "data/net_worth.csv" }, // a CSV / JSON / Parquet / SQLite file
"monthly": { "sql": "models/transforms/monthly.sql" }, // a DuckDB SQL transform over other datasets
"tracks": { "source": "data/library.sqlite", "table": "tracks" } // a table within a SQLite database
}| Field | Type | Required | Description |
|---|---|---|---|
source | string | no | Path to a CSV / JSON / Parquet / SQLite file. One of source or sql is required. |
sql | string | no | Path to a DuckDB SQL transform. One of source or sql is required. |
table | string | no | The table within a .sqlite / .db source. Required for a SQLite source; an error on any other source. |
description | string | no | Free-form note describing the dataset. |
A .sqlite / .db source requires table; supplying table for any other source is
a validation error. A sql dataset is derived and read-only; it can never be the
target of an action or a connector.
Pages
Each entry in pages is a page: one sidebar entry. A page holds either a flat
islands list or tabbed groups, never both:
{
"id": "overview", // required: unique page id, used in the URL
"title": "Overview", // optional: sidebar label
"icon": "house", // optional: one of the curated page icons
"filters": [ /* ... */ ], // optional: page-level shared filters (see Page filters)
"islands": [ /* ... */ ] // a page has EITHER islands ...
// "groups": [ { "id": "...", "title": "...", "islands": [ /* ... */ ] } ] // ... OR groups
}| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Unique page id, used in the /<appId>/<pageId> URL. |
title | string | no | Sidebar label for the page. |
icon | string | no | One of the curated page icons (e.g. house, chart-line, wallet). |
filters | array of object | no | Page-level shared filters: a date range or a categorical select. |
islands | array of object | no | The page's islands. Exactly one of islands or groups. |
groups | array of object | no | Tabbed groups of islands. Exactly one of islands or groups. |
A group is { id, title?, islands }: a string id, an optional title, and its own
islands list. Groups render as tabs under the page header, deep-linked via
?group=<id>.
Page filters
A page's optional filters declare shared controls in the page header. Each filter's bind
maps each affected dataset to the column the filter applies to; islands whose dataset appears
in bind re-query when the filter changes, and the rest ignore it. Two kinds are supported: a
daterange over a date column, and a select that narrows a categorical column.
"filters": [
{ "id": "period", "type": "daterange", "label": "Period",
"bind": { "net_worth": "month", "transactions": "ts" } },
{ "id": "team", "type": "select", "label": "Team", "multiple": true,
"bind": { "services": "owner" } }
]| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Unique filter id within the page. |
type | string | yes | The filter kind: daterange or select. |
label | string | no | Label shown on the control. |
bind | object | yes | A map of dataset name to the column the filter applies to. Each column is validated against the live data. |
multiple | boolean | no | select only: allow several values (IN); default single (=). |
options | array of string | no | select only: explicit choices; when omitted, the bound column's live distinct values are used. |
Actions
An action is a manifest-declared, typed write into a source dataset (a sql
dataset is never writable). mode: "insert" appends rows: an append for a flat file
(CSV / JSON(L)), an INSERT for a SQLite table. The row schema is derived from the
live data; fields only narrows or annotates it.
"actions": {
"log_meal": {
"dataset": "meals",
"mode": "insert",
"fields": {
"meal_type": { "enum": ["breakfast", "lunch", "dinner", "snack"] }
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
dataset | string | yes | The source dataset to insert into. Must not be a sql dataset. |
mode | "insert" | yes | The write mode. v1 supports insert. |
fields | object | no | Per-column overrides on the derived row schema (see field overrides). |
description | string | no | Free-form note describing the action. |
A field override (fields.<column>) narrows one column of the derived row schema:
| Field | Type | Required | Description |
|---|---|---|---|
type | "string" | "number" | "boolean" | "date" | no | Constrain the column to one type. |
enum | array of string | no | Constrain the column to a fixed set of string values. |
min | number | no | Minimum for a numeric column. |
max | number | no | Maximum for a numeric column. |
default | string | number | boolean | no | Value applied when the column is omitted. |
description | string | no | Free-form note describing the column. |
Queries
A query is a manifest-declared, read-only read over one dataset, written as a
declarative spec — not raw SQL. The compiler translates it to a parameterized,
type-aware SELECT, validates every field against the live columns, and binds every
param and value (so it's injection-safe). Its dataset is a source dataset or a
sql transform; there are no joins, so heavy shaping lives in a transform the query
points at.
"queries": {
"get_daily_macros": {
"description": "Macros + goals for one day; omit date for the latest.",
"dataset": "macros_daily",
"params": { "date": { "type": "date", "required": false } },
"where": [{ "field": "date", "op": "eq", "param": "date" }],
"orderBy": [{ "field": "date", "dir": "desc" }],
"limit": 1
}
}| Field | Type | Required | Description |
|---|---|---|---|
dataset | string | yes | The dataset to read: a source dataset or a sql transform. |
select | array of string | object | no | Columns to return: a column name or { field, fn?, as? } where fn is sum / avg / count / min / max. Omit for all columns. |
where | array of object | no | Filters, ANDed together; each is { field, op, param } or { field, op, value } (see filter ops). |
groupBy | array of string | no | Columns to group by, for aggregate select entries. |
orderBy | array of object | no | Sort keys, each { field, dir? } where dir is asc / desc (default asc). |
limit | number | no | Max rows returned. |
params | object | no | A map of parameter name to a parameter declaration (see query params). |
description | string | no | Free-form note describing the query. |
A query param (params.<name>) declares one parameter, referenced by a where
clause's param:
| Field | Type | Required | Description |
|---|---|---|---|
type | "string" | "number" | "boolean" | "date" | no | The parameter type. Defaults to string. |
required | boolean | no | Whether the caller must supply it. Defaults to true; false makes it optional. |
enum | array of string | no | Constrain a string parameter to a fixed set of values. |
min | number | no | Minimum for a numeric parameter. |
max | number | no | Maximum for a numeric parameter. |
default | string | number | boolean | no | Value used when the caller omits it; implies optional. |
description | string | no | Free-form note describing the parameter. |
A filter (where[]) names a field, an op, and exactly one of param (bind a
declared param) or value (a literal). The ops are eq, ne, lt, lte, gt,
gte, contains (case-insensitive substring), sameDay (match a timestamp field to a
date), and in (a literal value array). A filter bound to an optional param the
caller omits is dropped, so the query runs without it.
Connectors
A connector is a vendored integration that syncs a provider's data into source
datasets through the same checkpointed write path actions use. The integration code
lives in the user's project at <module>/index.ts; the manifest declares an instance:
"connectors": {
"whoop": {
"module": "connectors/whoop", // connector directory, relative to project root
"datasets": { "recovery": "whoop_recovery" }, // connector output name → manifest dataset name
"schedule": "6h", // optional: sync interval, overrides the connector default
"config": { "lookbackDays": 30 } // optional: validated against the connector's own schema
}
}| Field | Type | Required | Description |
|---|---|---|---|
module | string | yes | Connector directory relative to project root, e.g. connectors/whoop. |
datasets | object | yes | A map of connector output name to the writable source dataset it syncs into. |
schedule | string | no | Sync interval, overriding the connector default (<n>m, <n>h, <n>d, or ms-style). |
config | object | no | Free-form config, validated against the connector's own schema at load time. |
description | string | no | Free-form note describing the connector instance. |
Each datasets value must name a writable source dataset (never a sql dataset),
and each key must be one of the connector's declared outputs.
Islands
Each island in a page's islands (or a group's islands) is an object discriminated
by its type. Below is every built-in type with its grid span range and the fields
its config accepts. id, title, and span are common optional fields on every
data-bound island; span is a 1–12 grid column count that must sit within the island's
min–max range (a value below min or above max is a named validation error), and
defaults to the recommended width when omitted. Compact, single-value islands cap well
below full width; data-dense ones run the full 12. Bind an island only to fields that
exist in its dataset; a missing field fails validation and names the island.
A layout.row is a structural wrapper: it holds other islands and forces them onto
their own full-width grid row. It carries no span, title, or data binding, and it
cannot nest another layout.row.
Built-in islands: metric.kpi · metric.scorecard · timeseries.line · category.bar · category.combo · waterfall.bars · divergence.bars · breakdown.treemap · distribution.heatmap · activity.calendar · funnel.steps · rank.list · compare.radar · map.choropleth · correlation.scatter · category.pie · table.grid · timeline.feed · gauge.rings · gauge.goal · gauge.meter · status.grid · search.box · note.card · source.doc · content.editor · form.entry · board.kanban
metric.kpi
A single headline number, optionally with a delta vs the previous row or a target — use for at-a-glance KPIs.
Span: min 2, recommended 4, max 6 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
value | string | yes | field holding the headline value |
compareTo | string | no | 'prev', 'none', or a field name |
target | string | no | field holding a target to compare against |
unit | string | no | |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
color | string | no | 6-digit hex color (e.g. "#22C55E") for the sparkline, overriding the default palette |
metric.scorecard
A compact scorecard of several KPIs off the last row — use for a tidy row of related numbers, each with an optional delta vs the previous row.
Span: min 3, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
stats | array of object | yes | the stats to show, each read off the last row |
columns | number | no | fixed grid column count; defaults to responsive |
timeseries.line
A line chart over time — use for trends; supports multiple y fields, a series split, and a goal line.
Span: min 4, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | date/time field |
y | string | array of string | yes | numeric field(s) |
series | string | no | field to split series by |
colors | array of string | no | CSS colors per y field (or per series value, in first-seen order), overriding the default palette |
options | object | no |
category.bar
A bar chart across categories — use to compare discrete groups; supports grouped or stacked bars.
Span: min 4, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | category field |
y | string | yes | numeric field |
group | string | no | |
stacked | boolean | no | |
colors | array of string | no | CSS colors per series (group value or y field), overriding the default palette |
category.combo
A dual-axis chart: bars on the primary axis, lines on a secondary axis — use to compare a level against a rate (revenue vs margin, volume vs price).
Span: min 4, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | category or date field (x axis) |
bars | string | array of string | yes | numeric field(s) drawn as bars on the primary y-axis |
lines | string | array of string | yes | numeric field(s) drawn as lines on the secondary y-axis |
stacked | boolean | no | stack the bar series into one bar per category |
colors | array of string | no | CSS colors per series (bars first, then lines), overriding the default palette |
format | value format | no | format for the primary (bar) y-axis |
lineFormat | "usd" | "eur" | "gbp" | "jpy" | "int" | "decimal" | "pct" | "compact" | "kg" | "bytes" | "duration" | "date" | "datetime" | "time" | "month" | string | no | format for the secondary (line) y-axis |
waterfall.bars
A waterfall / bridge chart — use for a P&L walk or variance: an opening anchor, signed +/− steps that accumulate, and closing anchors. Mark anchor rows via a kind field whose value is "total".
Span: min 4, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | step-name field (x axis) |
value | string | yes | signed delta per step; for a total/anchor row, its absolute level |
kind | string | no | field marking anchor rows: a row whose value here is "total" draws as an absolute bar from zero (opening/closing/subtotal). Omit to make every row a delta. |
colors | object | no | CSS colors per tone, overriding the defaults (increase green, decrease red, total neutral) |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
divergence.bars
A diverging bar chart: one signed bar per category extending above or below a zero baseline, optionally colored by which value band it falls into. Use for deviation from a reference — daily calorie surplus/deficit, budget variance, net cash flow, sentiment, temperature anomaly. Pick this over category.bar when values are signed and the up/down direction is the message, and over waterfall.bars when each bar stands on its own rather than accumulating into a running total.
Span: min 4, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | category or date field (x axis) — one bar per row |
value | string | yes | signed numeric field: the bar rises above the zero baseline for positive values and drops below it for negative. Rows with a null or non-numeric value are skipped. Pre-compute the difference in SQL to diverge from a non-zero target. |
buckets | array of object | no | color each bar by the value band it falls in — e.g. surplus tiers green, deficit tiers red. Bands are matched top-to-bottom with half-open bounds [gte, lt); a value matching none renders neutral grey. Omit entirely for a default green-positive / red-negative two-tone. |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
breakdown.treemap
A treemap of part-to-whole composition — use to show how a total splits across (optionally hierarchical) parts.
Span: min 4, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | |
value | string | yes | |
parent | string | no | field for hierarchy parent |
colors | array of string | no | CSS colors cycled across top-level nodes, overriding the default palette |
distribution.heatmap
A matrix heatmap — use to show one value across two categorical dimensions (x × y), shaded by a continuous color scale.
Span: min 4, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | column-category field (x axis) |
y | string | yes | row-category field (y axis) |
value | string | yes | numeric field mapped to each cell's color |
colors | array of string | no | gradient color stops for the scale, overriding the default |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
activity.calendar
A calendar heatmap — use to show a daily value over weeks and months, GitHub-contributions style; rows on the same day sum.
Span: min 6, recommended 12, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
date | string | yes | date field — any parseable date or timestamp |
value | string | yes | numeric field mapped to the day's color intensity |
colors | array of string | no | gradient color stops, overriding the default |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
funnel.steps
A funnel of sequential stages — use for conversion or drop-off; each stage's width is its share, ordered by the rows unless sort is set.
Span: min 3, recommended 4, max 6 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | stage-name field |
value | string | yes | numeric field — the count at each stage |
sort | "none" | "ascending" | "descending" | no | funnel ordering; 'none' keeps the declared row order |
colors | array of string | no | CSS colors per stage, overriding the default palette |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
rank.list
A ranked Top-N list with proportional bars — use for leaderboards: top products, customers, errors, or movers.
Span: min 3, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | field naming each row |
value | string | yes | numeric field the rows are ranked by |
limit | number | no | max rows shown |
sort | "descending" | "ascending" | no | rank order by value |
secondary | string | no | optional field shown beside each row's value |
color | string | no | CSS color for the bars, overriding the default accent |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
compare.radar
A radar (spider) chart — use to compare entities across several metrics at once; each metric is an axis, each row a polygon.
Span: min 4, recommended 6, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
metrics | array of string | yes | numeric fields, one radar axis each |
series | string | no | field naming each polygon (one per row); omitted numbers them Series 1, 2, … |
max | number | no | fixed max for every axis; omitted maxes each axis at its metric's peak |
colors | array of string | no | CSS colors per polygon, overriding the default palette |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
map.choropleth
A geographic choropleth — use to shade regions (world countries) by a value; region names must match the map's names. Local-first: the map ships as vendored GeoJSON, no network.
Span: min 5, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
region | string | yes | field holding each row's region name, matching the map's region names (e.g. a country name like "France") |
value | string | yes | numeric field mapped to each region's color |
map | string | no | the registered map name |
colors | array of string | no | gradient color stops, overriding the default |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
correlation.scatter
A scatter or bubble plot of two numeric fields — use to explore correlation; split into series by a field and size points by a third.
Span: min 4, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
x | string | yes | numeric field for the x axis |
y | string | yes | numeric field for the y axis |
series | string | no | field splitting points into one colored series per distinct value |
size | string | no | numeric field driving bubble radius; omit for fixed-size dots |
label | string | no | field naming each point, shown in the tooltip |
colors | array of string | no | CSS colors per series, overriding the default palette |
format | value format | no | formats the y value (axis + tooltip) |
xFormat | value format | no | formats the x value (axis + tooltip) |
category.pie
A pie or donut chart of part-to-whole composition — use for one series' share across a handful of categories; set donut for a hole.
Span: min 3, recommended 4, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | category field naming each slice |
value | string | yes | numeric field sizing each slice |
donut | boolean | no | render with an inner radius (a donut hole) |
colors | array of string | no | CSS colors per slice (in descending-value order), overriding the default palette |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
table.grid
A paginated table of raw rows: use when exact values matter; supports column formats, click-to-open details, and collapsible groups.
Span: min 5, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
columns | array of object | no | |
details | array of object | no | fields hidden from the row, revealed by clicking it |
groupBy | object | no | |
pageSize | number | no | |
expand | boolean | no | offer the see-all / expand dialog; false renders every row inline instead |
drilldown | object | no | an embedded island shown in a clicked row's details dialog, filtered to that row |
timeline.feed
A reverse-chronological feed of events: use for logs and activity; supports detail dialogs and collapsible groups, and a rich row layout (header value, inline stats, meta footer) when highlight/stats/footer are set.
Span: min 4, recommended 7, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
ts | string | yes | timestamp field |
titleField | string | yes | |
detail | string | no | |
kind | string | no | |
details | array of object | no | fields hidden from the row, revealed by clicking it |
groupBy | object | no | |
highlight | object | no | right-aligned emphasized value in the row header |
stats | array of object | no | labeled inline stats rendered under the title |
footer | array of object | no | small meta line below the row; the row timestamp always leads it. Setting any of highlight/stats/footer switches the row from a single line to the rich layout |
expand | boolean | no | offer the see-all dialog; false renders every row inline instead |
drilldown | object | no | an embedded island shown in a clicked row's details dialog, filtered to that row |
gauge.rings
Up to four concentric progress rings read off the last row — use for tracking several goals or budgets at once.
Span: min 4, recommended 5, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
rings | array of object | yes | concentric rings, outermost first; reads the last row (max 4 for legible geometry) |
gauge.goal
One ring per goal comparing the last row's value to a goal or target band — use for numbers with a defined good range; within the band reads success-green, under amber, over danger-red. size sets the shared ring footprint so several share a row.
Span: min 2, recommended 5, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
goals | array of object | yes | one ring per goal, side by side in a row that wraps; each reads the last row (max 6 to stay legible) |
size | "small" | "medium" | "large" | no | footprint shared by every ring: small packs several goals into a row, large emphasizes one or two |
gauge.meter
One or more horizontal usage meters read off the last row — use for quota- or capacity-style values.
Span: min 3, recommended 4, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
meters | array of object | yes | horizontal usage bars, top to bottom; reads the last row |
status.grid
A responsive grid of state tiles — use for service/check health on ops & status-page dashboards; each tile's tone comes from its state value.
Span: min 4, recommended 8, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
label | string | yes | field naming each entity (service, check, host) |
state | string | yes | field holding each entity's status value |
value | string | no | optional metric shown under the label |
format | value format | no | Display format for a value. Currency: usd, eur, gbp, jpy. Number: int, decimal, pct (a 0–1 fraction shown as a %), compact (1.2K). Unit: kg, bytes (1024-scale), duration (a number of seconds → 1h 5m). Date/time: date, datetime, time, month. Omit for a plain number with up to 2 decimals. For any other ISO 4217 currency use 'currency:<CODE>' (e.g. currency:RSD). See the Value formats reference (/reference/value-formats). |
tones | object | no | map a state value to a tone; unmapped values fall back to a keyword convention (up/ok/healthy/online → success, warn/degraded/pending → warning, down/error/critical/fail → danger, else neutral) |
search.box
A search box over a dataset — typing matches rows case-insensitively across fields, results drop down as an autocomplete; selecting a result opens the row's details.
Span: min 3, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
fields | array of string | yes | columns the query matches against |
titleField | string | yes | field each result shows |
detail | string | no | field shown as a secondary line under each result |
placeholder | string | no | |
limit | number | no | max visible results |
note.card
A static markdown card with no data binding — use for commentary, instructions, or context between islands; set tone to render it as an info/success/warning/danger callout.
Span: min 3, recommended 6, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
tone | "info" | "success" | "warning" | "danger" | no | renders the card as a colored callout with a matching icon; omit for plain prose |
markdown | string | yes |
source.doc
An embedded file or external link (pdf, markdown, image, link) — use to surface source documents alongside the data; renders as a document card with a type icon, name, and open affordance.
Span: min 2, recommended 4, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
file | string | no | |
href | string | no | |
kind | "pdf" | "markdown" | "image" | "link" | no | |
label | string | no | human-readable name shown on the card; defaults to the file name or the link's host |
description | string | no | a short caption shown under the document |
content.editor
A full-page content workspace — browse and edit a directory of markdown files (and CSVs) Obsidian-style, with virtual folders and version history. Set exactly one of file (one doc) or dir (a tree). Binds no dataset and renders full-bleed.
Span: min 6, recommended 12, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
file | string | no | path to a single document under data/ or docs/ — mutually exclusive with dir |
dir | string | no | path to a directory under data/ or docs/ whose files are browsable and editable — mutually exclusive with file |
include | array of string | no | globs of files to surface when dir is set; defaults to markdown (**/.md, **/.markdown) |
csv | boolean | no | also surface .csv files (an editable table — cells and row add/delete; read-only when readOnly) when dir is set |
readOnly | boolean | no | disable editing/saving — a viewer only |
groups | array of object | no | virtual folders grouping scattered files; only meaningful with dir |
form.entry
A data-entry form card bound to a manifest action — renders one typed input per action field, with a submit button in the bottom-right that inserts a row; the bound dataset's islands then refresh live. The human-facing mirror of the agent's runActions insert: it reuses the action's typing and so binds no dataset of its own.
Span: min 3, recommended 5, max 8 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
action | string | yes | name of a manifest actions entry this form writes to; the form's inputs are derived from that action's resolved row schema — types, enums, ranges, and defaults all come from the action |
fields | array of string | no | the action's columns to render as inputs, in this order; omit to show every insertable column. Each must be a column of the action's dataset |
submitLabel | string | no | text on the submit button; defaults to "Add" |
board.kanban
A full-bleed kanban board grouping rows into columns by a status/stage field — use for work queues, incidents, or pipeline stages. Pick this over table.grid / status.grid when cards should move between columns, and over form.entry when the interaction is reassigning an existing row rather than inserting one. Moving a card POSTs match+set through the bound update action; without action or with readOnly, the board is view-only.
Span: min 6, recommended 12, max 12 (of 12). Omit span to render at the recommended width; below min or above max is a named error.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | no | |
title | string | no | |
span | number | no | |
dataset | string | yes | |
key | string | yes | field uniquely identifying each card — used as the match key when moving a card via the bound update action |
column | string | yes | field whose value places each row into a board column (e.g. status, stage) |
titleField | string | yes | field shown as the card title |
columns | array of string | no | ordered column values to always show (including empty ones); omit to derive columns from distinct values in the data, in first-seen order. Values present in the data but missing here still appear after the listed ones so nothing is hidden |
details | array of string | no | optional extra fields shown on each card under the title; each must be a column of the dataset |
action | string | no | name of a manifest actions entry with mode update that persists a column move (match on key, set column); omit or set readOnly to disable moves |
readOnly | boolean | no | disable drag/keyboard moves — a viewer only; default false when action is set |
Custom islands
When no built-in fits, register a renderer in the user's project under
components/custom/<type>/; the directory name is the island type. An unknown island
type is accepted as a custom island: with a schema.ts its manifest config is
validated by the same machinery that guards the built-ins; without one it renders a
placeholder. See the Custom Islands guide for the full shape.
Custom Islands
When no built-in island fits, register your own — a React renderer that lives in your project, gets a typed config, and is checked by the same validator.
Value formats
A format is the optional display format applied to a numeric or date value, available on every island and spec that renders a value.