Core Concepts

Canvases and widgets

Every workspace mode is a React Flow canvas you can extend with draggable widgets.

Project88's UI is canvas-first. Every workspace mode — Home, Chat, Data, Agents, Office, and so on — is rendered inside a blank, infinite React Flow board (CanvasBlankCard). You can add widgets to it: draggable, resizable nodes that surface live workspace data.

Canvases

Each canvas is identified by a (org_id, type, slug) tuple and persisted to the canvases table:

  • typeboard for user-created canvases; orchestration, agent_pipeline, agent_config for system canvases.
  • slug — the workspace mode (home, chat, data, agents, office, etc.) or a user-chosen name.
  • nodes / edges — the React Flow graph as JSONB.
  • metadata — anchor viewport, name, icon, description, read-only flag.

Nodes and edges auto-save with an 800 ms debounce. Reopening a canvas restores the exact layout — including the saved zoom and viewport position via the anchor viewport (right-click → Canvas Settings → Set Anchor).

Editing

Canvases are read-only by default. Toggle edit mode from the canvas settings popup. In edit mode:

  • Right-click a free spot → Add Widget → category → Small / Medium / Large size.
  • Right-click an existing node → settings panel (background, border, shape, opacity, shadow, typography, handle configuration).
  • Drag to move. The NodeResizer lets you resize.
  • Keyboard shortcuts: ⌘Z undo, ⌘⇧Z redo, ⌘D duplicate, ⌘C/V copy/paste, Delete, ⌘A select all, Escape deselect.
  • Undo/redo keeps a snapshot history of up to 50 steps, including drag positions.

Widgets

A widget is a node that wraps a small interactive React app. Each widget ships in three sizes:

SizeWhat you get
SmallIcon-only — quick visual indicator
MediumCompact preview (mini-table, mini-form)
LargeFull interactive view

Built-in widgets — chat, data, pages:

  • NewChatWidget — chat input with model + agent selector and recents
  • DataTableWidget — interactive table view
  • DataTableListWidget — list of all tables; outputs tableId
  • DataTableViewerWidget — paginated view; outputs selectedRowId
  • DataRecordWidget — single-record card with prev/next nav
  • DataStatsWidget — KPI cards (row count, fill %, latest update)
  • PagesWidget — recents list + full block-aware page viewer

Built-in widgets — calendar, tasks, pipeline:

  • CalendarWeekWidget — week grid with drag-to-reschedule and drag-across-calendars
  • CalendarMonthWidget — month grid
  • CalendarAgendaWidget — agenda list with Now / Next status and per-event tag color
  • TasksWidget — pull kind = 'task' activities into a checklist; groups by overdue / due today / upcoming
  • PipelineStageWidget — kanban stages over records, conversations, events, or any taggable entity; rule-based filters

Built-in widgets — agent builder and dial:

  • AgentBuilderWidget — full agent editor on the canvas, with eight tabs (General, Prompt, Variables, Examples, Tools, Identity, Sandbox, Sub-agents)
  • DialWidget, DialBucketListWidget, DialStatsWidget, plus the supporting panels — see Dial mode

Connecting widgets

Widgets declare a DATA_ROLE:

  • source — outputs data (e.g. DataTableListWidget outputs tableId).
  • both — accepts upstream input and emits output (e.g. DataTableWidget takes a tableId and emits a selectedRowId).
  • target — consumes upstream input only (e.g. DataRecordWidget, DataStatsWidget).

When you connect a source/both widget to a both/target widget, two values flow:

  • data.upstreamTableId — propagates downstream so the connected widget knows which table to render.
  • data.upstreamRowId — emitted when you click a row in a table widget; downstream record widgets re-render to that row.

Connected widgets show a small ● Linked / ● Row Linked indicator. Disconnecting clears the upstream and restores manual selectors.

Handles

Each enabled handle is exactly one type:

  • Source nodes — all handles blue (outgoing).
  • Target nodes — all handles green (incoming).
  • Both nodes — left handles green (targets), right handles blue (sources).

The settings panel handle picker shows colored dots matching the resolved type. connectionMode="strict" ensures source→target only. isValidConnection blocks self-connections and anchor edges.

The Office and Planning canvases

Two specialised canvases:

  • Office — read-only bird's-eye view of every agent in the workspace, with delegation edges between them. Clicking an agent opens its AgentCanvasModal.
  • Planning — text-centric canvas attached to a page, with Text, Task, Group, and Link nodes. Renders as an inline preview above the page blocks.

Both share the same EditorShell and FlowNodeShell infrastructure as the Automation editor.

The Pipeline Stage widget

Worth calling out: the PipelineStageWidget is a kanban-style stage widget that groups entities by stage. Stages are derived from tags or a column value, and rules decide which entity belongs to which stage — tag match, date range, numeric comparison, text match. Drag an entity between stages to retag it.

Use it for sales pipelines (records → stages by opportunity status), support boards (conversations → stages by priority tag), or any kanban-shaped workflow over your data.

Widget linking primitive

A newer primitive (src/widgetLinks/) lets one widget's selection drive another's filter — wire the Email Inbox widget to a Records widget so clicking an email opens the linked customer record, for example. Links are configured per pair of widgets and persist with the canvas.

Where to go next

On this page