Widgets

Structured widget storage, dashboard usage, and hub publish/install lifecycle.

Widgets are stored in the mini_apps table and rendered from structured widget_definition JSON. They are managed in Modules -> Widgets. Unlike modules and skills, widgets are database records, not filesystem packages.

Local widget model

Each widget catalog entry stores:

  • slug
  • name
  • optional description
  • widget_source (local, hub, or system)
  • optional system_widget_key for the preinstalled dashboard widgets
  • widget_definition
  • optional latest_data (plus latest_data_updated_at / latest_data_updated_by / latest_data_source bookkeeping)

Each user-specific installation stores:

  • dashboard_visible
  • dashboard_settings (per-user JSON for widget-specific dashboard behavior such as sort/filter choices)
  • dashboard_x
  • dashboard_y
  • dashboard_w
  • dashboard_h
  • dashboard_z

The supported structured widget types are:

  • stats
  • list
  • table
  • notice
  • sections

The canonical normalization and validation path lives in:

  • src/lib/widget-definition.ts
  • src/lib/mini-apps.ts

Dashboard usage

The built-in dashboard cards exist as normal widget_source=system entries in the widget store and are installed automatically for every user. The system widget keys (src/lib/system-widgets.ts) are clients_summary, open_tasks, urgent_tasks, overdue_tasks, task_list, inbox, and news_feed.

The task list widget uses dashboard_settings.task_list to persist each user's chosen sort and filter mode directly on the dashboard widget instance. The current web UI exposes this through the widget header settings menu so users can see and change how "Anstehende Aufgaben" is ordered without leaving the dashboard.

Dashboard task widgets use an explicit all-board scope. Open tasks counts only the first configured status in category open, while urgent, overdue, and upcoming-task widgets use all unfinished status categories. Opening any of these widgets carries the matching board=all and status filters into /aufgaben, so the visible task view explains the displayed value instead of falling back to the default board.

The dashboard also includes a fixed agent suggestion widget on web and in the Apple client. Its static German prompt choices send a message directly to the personal agent chat. The prompts ask the agent to include a compact copilot_ui_render choice card with choices[] for useful follow-up actions when the tool is available, so the user can continue from the summary with one click instead of typing a numbered reply:

  • Tag starten: asks the agent to brief the user on today's meetings, important unread emails, and due tasks, then offer follow-up choices such as preparing the next appointment, planning the first due task, or summarizing an important email.
  • Update geben: asks the agent to summarize recent team activity across chats, tasks, and related work areas, then offer follow-up choices such as drilling into open points, deriving tasks, or preparing a status update.

On web the widget opens the right-side chat and dispatches the prompt through the existing /api/chat flow. On iOS/macOS it switches to the chat page and submits through the native AppModel.sendDashboardMessage path.

Hub lifecycle

Widgets can be distributed through the same hub model used by modules and skills:

  1. list local widgets from /api/widget-store/local
  2. fetch the widget hub catalog from /api/widget-store/catalog
  3. publish one local widget snapshot with /api/widget-store/publish
  4. install one published widget version with /api/widget-store/install

Hub-mode instances expose:

  • GET /api/v1/widgets
  • POST /api/v1/widgets/publish
  • GET /api/v1/widgets/:slug/:version/download

Published widget artifacts are versioned JSON snapshots stored in the hub storage area. Installs validate the downloaded payload, then create or update the local widget by slug.

Install behavior

Widget install differs from module/skill install because widgets are database records instead of filesystem packages:

  • new slug: creates a new local widget row in the shared catalog and installs it for the current user
  • existing slug: updates the existing widget content in place
  • existing dashboard placement: kept during re-install so the widget does not disappear from the installing user's dashboard

Agent support

Current live/native agent contracts cover widget CRUD and data updates (mini_apps_list/get/create/update/update_data and the widgets_* equivalents).

Widget hub publish/install is currently an admin UI and HTTP API workflow and is not yet exposed as a dedicated live/native agent tool contract.

Last chats

The bundled recent_chats widget is visible by default and lists the signed-in user's three most recently active personal chats, ordered by last message time (then creation time and ID). Main and pinned chats receive no preference. Existing dashboard layouts and hidden-widget choices are preserved; the widget can be removed and added again with the dashboard widget picker.

Selecting a conversation opens it in the right chat sidebar on desktop web, keeping the dashboard open. Mobile web, iOS, and macOS open the selected conversation in the chat view. The native dashboard includes the same three-chat card. Web refreshes on focus and every 30 seconds while visible; native refreshes when the dashboard opens or is refreshed. Empty, loading, and failure states are translated in German, English, and Italian.

Agents can read this widget through widgets_list / widgets_get (and the mini_apps_* aliases): latest_data.items contains the caller's recent chat IDs, titles, activity timestamps, and chat links. Personal chat data is resolved per request and is never stored in the shared widget catalog.

Agent suggestions layout

The former fixed Agent suggestions panel is now the bundled agent_suggestions widget. On desktop web it supports the same bottom-right resize handle, header drag handle, removal, and saved layout as other widgets. Its two actions wrap into one column when the widget is narrow, and content scrolls when needed. Existing installed widgets move down two grid rows once during promotion, preserving their sizes, visibility, and relative placement. Subsequent reads preserve the saved layout. On mobile web widgets flow automatically; the iOS/macOS dashboard continues to use its native adaptive layout, which has no manual widget-resizing surface.

Compact number tiles

The Customers, Open tasks, Urgent tasks, and Overdue tasks counters show only the title and number. Their default and minimum height is one grid row (92px), and resizing to this height persists through the dashboard API. Existing saved sizes and positions remain unchanged until edited. The Apple dashboard metric cards also omit the visible explanatory captions and use a shorter layout. Agent suggestions is rendered only through its movable dashboard widget; no fixed duplicate sits above the grid.