Manifest Reference
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 minimum grid span 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 and must not fall below the
island's minimum span. 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 · 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
metric.kpi
A single headline number, optionally with a delta vs the previous row or a target — use for at-a-glance KPIs.
Minimum span: 2
| 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. 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.
Minimum span: 3
| 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.
Minimum span: 4
| 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.
Minimum span: 4
| 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).
Minimum span: 4
| 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" | 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".
Minimum span: 4
| 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. 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.
Minimum span: 4
| 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.
Minimum span: 4
| 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. 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.
Minimum span: 6
| 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. 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.
Minimum span: 3
| 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. 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.
Minimum span: 3
| 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. 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.
Minimum span: 4
| 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. 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.
Minimum span: 5
| 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. 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.
Minimum span: 4
| 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.
Minimum span: 3
| 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. 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.
Minimum span: 5
| 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.
Minimum span: 4
| 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.
Minimum span: 4
| 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.
Minimum span: 2
| 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.
Minimum span: 3
| 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.
Minimum span: 4
| 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. 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.
Minimum span: 3
| 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.
Minimum span: 3
| 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.
Minimum span: 2
| 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.
Minimum span: 6
| 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 run_action: it reuses the action's typing and so binds no dataset of its own.
Minimum span: 3
| 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" |
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.