DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS
PAGES·BLOCKS AND REFERENCES

Blocks and references

The page editor (PageEditor) is built on TipTap with a custom set of extensions. This page lists every block type you can insert, plus the full reference syntax for embedding live links to other workspace entities.


Block types

Open the slash-command menu by typing / at the start of a line. The menu groups blocks into four categories.

Text

BlockHow to insertDescription
Heading 1/h1Large section heading (#).
Heading 2/h2Medium section heading (##).
Heading 3/h3Small section heading (###).
ParagraphDefaultPlain text. Supports bold (**), italic (*), inline code (`), and hyperlinks.
Link/linkWraps selected text in a hyperlink. Also auto-links URLs as you type.

The editor supports heading levels 1–3 only. Heading levels 4–6 are not available in the slash menu.

Lists

BlockHow to insertDescription
Bullet List/bulletUnordered list. Each item is a listItem node.
Numbered List/orderedOrdered list. Items are numbered sequentially.
Task List/taskCheckbox list. Each item has a checked/unchecked state. Task list items are taskItem nodes.

Blocks

BlockHow to insertDescription
Info Callout/callout-infoBlue-tinted callout for informational notes.
Warning Callout/callout-warningAmber-tinted callout for cautions.
Success Callout/callout-successGreen-tinted callout for confirmations.
Error Callout/callout-errorRed-tinted callout for errors or blockers.
Code Block/codeSyntax-highlighted code block powered by the OnnieCodeBlock extension (lowlight). Supports Tab indentation inside the block.

Callout blocks (calloutBlock) can contain any block content — paragraphs, lists, even nested callouts.

Media and layout

BlockHow to insertDescription
Image/imageEmbeds an image by URL. No file upload from the editor yet — you paste a URL when prompted.
Two Columns/columnsSide-by-side TwoColumnLayout with two ColumnBlock children. Each column accepts block content.
Divider/dividerHorizontal rule (---).
//NOTE

Image insertion from the editor currently accepts only external URLs. File upload will be wired to the storage module in a future release.


Inline references

Any text surface in a page body accepts inline references. Type @ at a word boundary — a search picker opens. Select any entity from your workspace and a reference pill is inserted.

The serialized wire format is:

[Display Name](ref:entity_type:uuid)
[Display Name](ref:entity_type:uuid/alias_id)

The alias_id tail is included when the entity has one (most workspace entities do). It is a 12-char base64 token auto-generated from the UUID by the set_alias_id() Postgres trigger — for example NWY5YjJhMDE_. It is not a human-readable slug; never write references like (ref:table:uuid/contacts).

Examples of valid reference syntax:

[Contacts](ref:table:5f9b2a01-9c4d-4b78-9e7f-3a8c1d6b0e2a/NWY5YjJhMDE_)
[Superagent](ref:engine_bot:00000000-0000-0000-0000-000000000001/TXkgQm90XzA_)
[Q2 Planning](ref:page:7a1c3d4e-2b6f-4a8c-9d1e-0c5b7f3a2e1d/N2ExYzNkNGU_)
[Sprint tasks](ref:task:9c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f)

Supported entity types

The reference picker searches across all of these entity types:

entity_typeWhat it points to
tableA workspace table (Tables module).
pageA page or subpage.
folderAn organisational folder in the page tree.
routineA scheduled automation.
functionA workspace-defined TypeScript function (Function Routines).
taskA task from the Tasks module (engine_tasks).
recordA single row inside a table.
projectA project.
userA workspace member.
teamA workspace team.
engine_botA custom or built-in bot (Superagent or any Onnie AI bot).
skillA saved skill document.
variableA workspace-scoped variable.
//WATCH OUT

The entity type for bots is engine_bot, not bot. Using (ref:bot:...) produces a broken reference — the parser accepts it but the renderer has no icon mapping for bot and the pill shows a fallback icon with no navigation target.


Reference rendering

At read time, each [label](ref:entity_type:uuid/alias_id) token is parsed back into a TipTap reference inline node and rendered by ReferenceNodeView as a ReferenceBadge.

The badge is an inline pill: a small icon on the left, the entity name truncated to 14 characters, styled with a type-specific background tint. Example colors by type:

  • engine_bot — emerald tint with a Bot icon.
  • table — indigo tint with a Table icon.
  • page — green tint with a FileText icon.
  • skill — sky tint with a BookOpen icon.
  • routine — violet tint with a Workflow icon.
  • function — amber tint with a FunctionSquare icon.
  • user / team — slate tint with a User / Users icon.

For entity types that have panels (skill, routine, engine_bot, table, page, folder), the pill is clickable. Clicking opens the entity's workspace panel via openPanel. For entity types without panels (user, team, task, project, variable, record), the pill is display-only.

The display_name in the pill is the label stored at insert time. It is not automatically updated if you rename the entity after inserting the reference. The UUID in the link target (id) always points at the correct row.


Broken references

If the entity a reference points to is deleted, the pill still renders using the last-known display_name and entity_type from the stored JSON. The badge will show the stored label with the type-specific styling, but clicking it will open a panel that shows "Not found."

There is no automatic cleanup of stale references when an entity is deleted. If you need to remove or update stale pills, edit the page and delete or re-insert the reference.