← Marble DashboardCONTENT HISTORY

Update to Marble Dashboard

Snapshot Oct 31, 2026 · 01:21 UTC · version 0.2.46

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Marble Dashboard and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Create, read, edit or manually refresh widgets in the user's Marble web dashboard, including boards, tabs and mentioned widgets and requests from the dashboard Refresh button.",
  "included_files": [
    {
      "relative_path": "references/dashboard-navigation.md",
      "size_in_bytes": 395
    },
    {
      "relative_path": "references/functions-exec.md",
      "size_in_bytes": 2861
    }
  ],
  "name": "marble-widgets",
  "skill_md_contents": "---\nname: marble-widgets\ndescription: Create, read, edit or manually refresh widgets in the user's Marble web dashboard, including boards, tabs and mentioned widgets and requests from the dashboard Refresh button.\n---\n\nUse the Marble tools with the user's connected Marble account. Use `open_chat_dashboard` only when the user asks to view the whole board or the `onboarding` skill or a dashboard button prompt calls for it; continue authorized work if the dashboard is closed.\n\n## Acknowledge build requests immediately\n\nAs soon as the user asks to build a widget or selects **Make this widget**,\nmake your first visible response one short acknowledgment that work is starting.\nDo this before reading references, checking the board or source, retrieving\nschemas, opening a draft, or fetching data. The user needs to know their request\nwas received while the widget is being built. For example: \"I'll start building\nyour Hacker News widget and fetch the latest discussions.\" Do not wait for a\ntool result or the finished widget before acknowledging. This acknowledgment\nis required even when routine progress narration is otherwise unnecessary;\nit does not claim the data was fetched or the widget was saved.\n\nBefore collection-returning research, read [functions.exec guidance](references/functions-exec.md). Use the host-provided `functions.exec` when available to keep full responses in JavaScript and emit only compact projected records. It is a host tool, not a Marble MCP tool; do not invent it if absent.\n\nRead the target board/widget and current record version. Keep explicit workshop IDs and draft revisions; never infer one globally active widget. Read `get_widget_formats` for the full canonical schema before supplying data. Open a draft, retrieve authorized data, submit a result and summary, then save the accepted preview if the user requested creation or edits. A draft alone is not a saved widget. On version conflict, read the latest saved record and explain the conflict before replacing someone else's changes.\n\nFor a new widget, read the existing board positions and supply an explicit free position to `save_widget`. Do not reuse the default anchor or cover another card. Existing-widget edits omit position unless the user asked to move it.\n\nUse the authorized tools available in this conversation to retrieve data,\nincluding connected ChatGPT apps and MCPs. Marble's built-in public data tools\ncan also collect websites, social posts, maps and events without a separate\nsource account. Call them with the open draft's `workshopId` and revision;\neach tool's input schema is authoritative. For public web research, use\nChatGPT's own web search when available. Name the sources as described below;\nnew widgets do not need `list_connections` or `connectionIds`. Existing Marble\nconnection IDs remain supported for legacy drafts.\n\nFor Marble data tools, retain every paid operation ID and idempotency key. Poll and page that operation's saved results. After timeout or an uncertain dispatch, resume the same request; do not start another paid run. A different request needs a different key. Report uncertain dispatch or interrupted result retrieval instead of hiding it with another run.\n\nData supplied by ChatGPT, including authorized results from other plugins, does\nnot acquire unattended access to the original source. Do not select a Marble\nmodel or start interactive Marble inference for this conversation. In replies,\nsay how to update the data: open the widget's **⋮** menu and choose **Refresh\nnow**, or ask ChatGPT to update it. Avoid the word \"snapshot\"; it does not tell\nthe user what to do. Do not mention automatic refresh, disabled schedules or\ninternal refresh policy unless the user asks. The menu icon is vertical **⋮**.\n\nWhen a composer content mention is available, read its `marble://` resource to identify the exact saved board, tab or widget. Resolve current ownership and versions through tools before mutations. Search/selection never starts a provider run.\n\nRefresh widget data only when the user requests it.\n\n## Inline data previews\n\nMarble widgets show a preview of the data passed to them. When previewing data\nfor a Marble widget, showing its widget preview inline in the chat is usually\nenough. Submit the data through Marble's widget tools and let the inline\npreview show how the data will appear in the saved widget. Keep explanations\nbrief and useful alongside that preview.\n\n## Short replies beside the UI\n\nLet the visible widget carry its contents. After a successful create or edit,\nconfirm the saved widget name once: \"Saved **Trending AI demos** to your\n**Research** board.\" Use the actual widget and parent board names. Name only\nthe parent board by default; omit the tab name, navigation arrows (such as\n`->` or `→`), board/tab paths and internal identifiers. Mention a tab only if\nthe user explicitly asks which tab contains the widget. If the board name is\nunavailable, say \"your dashboard\" without inventing a name. Give at most one useful sentence\nabout the outcome. Do not repeat feed items, article links, measurements or counts\nalready displayed in the widget, or narrate routine tool calls. Keep its\nexisting inline card; do not capture a duplicate image or automatically open\nthe full dashboard. The inline card's **View in dashboard** link opens the\nfull dashboard inside ChatGPT. Keep dashboard navigation in that inline\ncontrol; do not add a dashboard URL or Markdown link to the assistant's reply.\nFollow [dashboard navigation](references/dashboard-navigation.md). The user\nchooses when to open the dashboard; do not open it for them.\nFor the first onboarding\nsave, follow `onboarding`'s short reply and refresh-control guidance. An optional\nnext suggestion should be one short sentence, not a feature tour.\n\nThese brevity rules do not remove required confirmation, source limitations,\nerrors or unresolved save/version conflicts. Never imply success after a\nfailed tool call.\n\n## Boards and the current dashboard\n\nWhen the user does not name a destination, or says \"this board\", call\n`get_current_board`. Use its `currentBoard.containerId` (parent board) and\n`currentBoard.boardId` (tab). This is the account's last displayed plugin board,\nshared across the sidebar and all chats; assume the user has one board open.\nDo not open another dashboard just to choose a destination. Do not use an old\n`currentMarbleBoard` context attachment or the default board from `list_boards`\nin place of this lookup. If `currentBoard` is null, list boards and ask where to\nsave. An explicitly named board or the board of an explicitly selected widget\nwins over this default. Once a draft is opened, keep that draft's board for the\nrest of the build. Read `get_board` for the chosen tab before opening the draft;\nresolve ownership and versions through tools before mutations.\n\nUse `list_boards` for parent boards, tabs and current versions. `create_board`\ncreates an empty parent board and initial tab: generate its two UUIDs once and\nreuse them on uncertain retries. Then use `rename_board` with the returned parent\nversion to set the user's requested name. If naming fails, report the created\nboard and retry naming after reading the current version; do not create another.\n`rename_board` preserves the board's picture and contents. Parent board tools take\n`containerId`; widget tools take the tab's `boardId`.\n\nBefore `delete_board`, state the exact board name and that all its tabs and widgets\nwill be removed, and wait for explicit confirmation. Never delete solely to make\nroom or clean up without a request. Read the latest version before the confirmed\ndelete. If a version conflict occurs, show the current state and confirm again;\ndo not silently retry a destructive change. The last board cannot be deleted.\nBoard changes do not refresh widget content.\nThe embedded dashboard reloads external changes; use the updated visible context,\nnot a deleted board ID, for subsequent requests.\n\n## Dashboard action conversations\n\nDashboard Add widget buttons start a new ChatGPT\nconversation for that action on supported web/desktop hosts. Refresh stays\nin the current conversation for chat-associated inline/fullscreen dashboards;\nthe sidebar/global dashboard opens a new refresh conversation.\nThe central host chatbox continues in its current conversation, and onboarding\ncarousel Build stays in the onboarding conversation. For an empty dashboard\nAdd request, follow `onboarding` and show its four fictional ideas; for a\nreturning populated dashboard Add request, first ask what kind of widget the\nuser wants. Clarify vague ideas before building. Edit widget attaches the\nsaved widget to the current plugin/chat composer through model context. It\ndoes not send a prompt or open a new chat; the user types their requested\nchanges in that conversation. Resolve the attached saved widget and current\nversion before editing. Ask what to change if their request is unclear.\nDo not capture a screenshot during initial edit/context selection.\nUse the callable `view_widget` tool only when visual inspection is needed.\n\n## Manual refresh\n\nA dashboard **Refresh now** request arrives in its associated chat (or a new\naction chat from the sidebar/global dashboard) with\n`widgetId` and a stable `requestId`. Ask the user to confirm this one refresh\nand wait for their answer before starting it. A button-sent request alone\nis not that conversational confirmation. Once confirmed, first call the write\ntool `begin_widget_refresh` with those exact IDs, before format research or provider work. It returns the\ncurrent saved definition, canonical schema and one durable workshop; do not\nopen another draft. If already succeeded, stop. Use the returned occurrence\nID for stable retry keys, retrieve authorized data, submit the result and save\nthe same widget with its returned versions and preview ID. Preserve definition,\nposition. If approval is\nrefused, stop before provider work and explain that no refresh was started.\nA click requests refresh but does not override actual host tool permissions;\ndo not promise that approving begin once authorizes later submit/save tools.\n\nFor a typed manual refresh request, resolve the exact widget ID if needed,\nthen generate one UUID requestId as its idempotency key and call the same\n`begin_widget_refresh` with widgetId and requestId before provider work. Retain\nthat requestId on uncertain retries; use only the occurrence ID returned by\nMarble. Do not use an unprotected ordinary draft for manual refresh or invent\na server occurrence ID. Respect\nsource-app permissions, preserve the last result on failure, discard a failed\nrefresh draft and reuse uncertain paid operation IDs and idempotency keys.\n\n## Source names and logos\n\nName each data source with `name` and an optional public website `domain`.\nMarble uses `name` as the source label and `domain` to look up the source logo\nshown on the widget. Choose the public website domain of the named source so\nthe logo represents the content the widget displays. This applies to sample\npreviews and saved widgets. If the domain is unknown or no logo is available,\nMarble shows a generic source icon; omit unknown domains rather than guessing.\nUse the platform, publication or service whose content or account data the\nwidget displays. Match the domain to that name. For Instagram posts, use\n`name: \"Instagram\", domain: \"instagram.com\"`; for Reddit posts, use\n`name: \"Reddit\", domain: \"reddit.com\"`. If a tool retrieves that content through\na provider such as Apify or Composio, keep the provider and tool requirements\nin the widget instructions. The display source is still the content platform.\nUse a provider's name and domain only when its own data is the subject of the\nwidget, such as Apify run usage.\nFor drafts use `sources: [{name, domain?}]`; for recommendation cards use\n`source: {kind: \"external\", name, domain?}`. Omit unknown domains. Do not fetch\nimage files, invent a domain, or call `list_connections` just for a logo.\nThese are display labels, not credentials. Use available authorized tools and\nkeep account/workspace requirements in the saved instructions. New ChatGPT\nwidgets can omit `connectionIds`; existing Marble connection IDs still work.\n"
}

SHA-256 of public snapshot: 781272f8978859ab8a23be223071d936fb6691e0ec966552990b0969693328fe