Canvas

Block catalog

A canvas is made of blocks. Each block is a registered React component plus a JSON shape. The renderer looks up the type, reads the data, and produces the rendered surface. Thirty-odd block types ship today, grouped here by what they communicate.

Updated today

Overview

At a glance
Registry
REGISTRY map in CanvasBlock.tsx
Block count
30+
Component path
src/components/canvas/<BlockName>.tsx
Spec shape
{ type: string, data: <typed-by-block> }
Editable subset
kanban, structured_doc, table cells in some variants
Exportable
All blocks; see Exports page

The catalogue grows. Anything a skill needs to surface as a structured output deserves a dedicated block; reusing a generic table block for everything makes results read worse and limits the value of the canvas surface. The blocks below are grouped by what they communicate, not by what they look like.

Block shape

Every block is just a typed React component plus a JSON contract.

src/components/canvas/CanvasBlock.tsxtsx
1type BlockProps<T> = { data: T; meta?: CanvasMeta; readonly?: boolean }
2
3export function ComparisonTable({ data }: BlockProps<ComparisonData>) {
4 return (
5 <table>
6 <thead><tr>{data.columns.map((c) => <th key={c}>{c}</th>)}</tr></thead>
7 <tbody>
8 {data.rows.map((row, i) => (
9 <tr key={i}>{data.columns.map((c) => <td key={c}>{row[c]}</td>)}</tr>
10 ))}
11 </tbody>
12 </table>
13 )
14}

Data blocks

When the output is structured tabular data.

BlockUse it for
tableGeneric tabular data with sortable columns and inline cell types
comparison_tableSide by side comparison across products, options, candidates
lead_tableCRM leads with score, status, contact buttons
deal_tablePipeline deals with stage, amount, close date
metric_gridKPI tiles in a responsive grid
chart_barBar chart over a series with optional grouping
chart_lineLine chart for trends over time

Comparison and scoring

When the goal is to rank or score alternatives.

BlockUse it for
score_cardMulti-criteria scoring matrix with weighted totals
ranked_listOrdered list of options with reasons per position
pros_consTwo-column pros and cons split
risk_matrixLikelihood x impact grid with annotated cells
decision_treeBranching choice tree with terminal recommendations

Workflow and process

When the output is a sequence of steps or a board of work.

BlockUse it for
kanbanEditable board with columns and movable cards
task_listNumbered tasks with status and owner
timelineSequential events on a horizontal timeline
sequenceOutreach sequence with per-step copy and delays
funnelStage by stage conversion funnel with drop-offs
pipelineSales pipeline view with totals and stage values

Code and technical

When the output is software, configuration, or live output.

BlockUse it for
code_diffUnified or side-by-side diff of two file revisions
code_blockSingle block of code with language detection and copy
terminalLive terminal output with prompt + streaming text
file_treeFolder structure with file annotations
api_endpointREST/RPC endpoint card with method, path, sample
json_viewCollapsible JSON inspector for deep payloads

Narrative and document

When the output is long-form prose.

BlockUse it for
structured_docMulti-section document with editable paragraphs and inline metadata
briefTightly scoped one-page brief with title, summary, sections
email_draftEmail subject + body + thread reply target with send/edit
post_draftSocial post draft with platform tags and scheduling controls
agreementContract draft with clause toggles and party fields

Media and visual

When the output is an image, a carousel, or a video clip.

BlockUse it for
imageSingle image with caption and alt text
carouselSlide deck rendered by the marketing worker, embedded inline
videoHosted video clip with player controls
technique_coverVisual preview card for a technique result
brand_kitBrand assets pinboard (logo, colours, fonts, voice)

Registry

The registry is the source of truth for which types exist.

src/components/canvas/CanvasBlock.tsxtsx
1const REGISTRY: Record<string, React.ComponentType<BlockProps<any>>> = {
2 // data
3 table: TableBlock,
4 comparison_table: ComparisonTable,
5 lead_table: LeadTable,
6 deal_table: DealTable,
7 metric_grid: MetricGrid,
8 chart_bar: BarChart,
9 chart_line: LineChart,
10 // comparison
11 score_card: ScoreCard,
12 ranked_list: RankedList,
13 pros_cons: ProsCons,
14 risk_matrix: RiskMatrix,
15 decision_tree: DecisionTree,
16 // workflow
17 kanban: KanbanBoard,
18 task_list: TaskList,
19 timeline: Timeline,
20 sequence: Sequence,
21 funnel: Funnel,
22 pipeline: Pipeline,
23 // code
24 code_diff: CodeDiff,
25 code_block: CodeBlock,
26 terminal: Terminal,
27 file_tree: FileTree,
28 api_endpoint: ApiEndpoint,
29 json_view: JsonView,
30 // narrative
31 structured_doc: StructuredDoc,
32 brief: Brief,
33 email_draft: EmailDraft,
34 post_draft: PostDraft,
35 agreement: Agreement,
36 // media
37 image: ImageBlock,
38 carousel: Carousel,
39 video: Video,
40 technique_cover: TechniqueCover,
41 brand_kit: BrandKit,
42}
Tip
Unknown types fall through to UnknownBlock, which renders the raw JSON in a collapsed viewer. That is the failure mode when a skill ships a spec the renderer does not yet know about.

File map

src/components/canvas
CanvasBlock.tsxregistry + dispatch
TableBlock.tsx
ComparisonTable.tsx
KanbanBoard.tsx
ScoreCard.tsx
CodeDiff.tsx
StructuredDoc.tsx
Sequence.tsx
Funnel.tsx
Carousel.tsx
TechniqueCover.tsx
CanvasExportPicker.tsxPNG/PDF/Brain export

Glossary

Block
One renderable kind of canvas content. Implemented as a React component and registered by type in CanvasBlock.tsx.
Spec
The JSON object the canvas renderer consumes. Type plus data plus meta.
Registry
The map from type string to component used to dispatch a spec to its renderer.
Editable block
A block whose internal data accepts user edits and writes them back to the spec.
Unknown block
The fallback renderer for a type the registry does not know. Renders the raw JSON.