Skip to main content
ClaudeWave
Skill13.7k repo starsupdated 2d ago

page

Build and publish a self-contained HTML page to Superset, then answer the comments readers pin to it. Use when the user asks to make or publish a page, turn a report, dashboard, chart, doc, or analysis into a shareable link, update or re-version a page already published, or work through comments left on one, including "make me a page for this", "publish this as a page", "share it as a link", "add a version", "address the comments on that page".

Install in Claude Code
Copy
git clone --depth 1 https://github.com/superset-sh/superset /tmp/page && cp -r /tmp/page/plugins/superset/skills/page ~/.claude/skills/page
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Superset Pages

A page is an **`.html` document** published to a URL people in the org can
open. Publish a single file and it must be self-contained; publish a directory
and its `index.html` is the document, with the images, stylesheets, and media
it references by relative path published alongside it. Every publish mints a version, so a page has history. Readers can
pin a comment to any element on it, and those comments come back to an agent to
fix. That is what makes a page a working surface rather than an export.

Pages are served from their own origin under a strict content policy. Most of
the work in this skill is respecting that policy; a page that ignores it looks
fine locally and breaks silently once published.

## When a page is the right surface

Publish a page when the work has a **reader** and wants a **link**: a report
someone will skim, a dashboard for a standup, a comparison table, a diagram, a
walkthrough of what you changed.

Don't publish when the artifact belongs in the repo (source, docs, config: put
those in files and commit them), or when it genuinely needs a server, a
database, or a login. A page has none of those.

If you're unsure, ask. Publishing is cheap and reversible, but a page the user
didn't want is noise in their org's list.

## The content policy, which is what actually bites

Every page gets its own origin, `https://<pageId>.frame.supersetusercontent.com`, and
is framed with `sandbox="allow-scripts allow-same-origin allow-forms
allow-popups"`. So the page is a real origin of its own, and a locked-down
one. The policy is `default-src 'none'` with a short allowlist, and it is
enforced identically in the desktop pane and the web viewer:

- **No network from script.** `fetch`, `XHR`, `EventSource` and WebSockets are
  all blocked, and so is `fetch("data:...")`: a page cannot read its own
  inlined data URIs back out. Write pages that need no network at all: bake
  the data into the document as a literal, or decode base64 in JavaScript
  (`atob`, then `Uint8Array.from`).
- **No compiling code at runtime.** `script-src` carries no `'unsafe-eval'`,
  so `eval()` and `new Function()` both raise an `EvalError`. This rules out
  inlining any library that builds functions at runtime, which includes
  several chart and templating libraries and a number of date and expression
  helpers. Check for it before you reach for a dependency: the page renders
  nothing and gives no visible reason why.
- **No scripts or stylesheets from a remote host.** `<script
  src="https://…">` and `<link rel="stylesheet" href="https://…">` are
  blocked, Google Fonts `<link>` tags included. A directory publish's own
  files load fine (relative `src`/`href`), and a remote font *file* is
  allowed, so an inline `@font-face { src: url(https://…) }` works.
- **Images, video and audio may be remote** (`https:`, `data:` or `blob:`),
  but prefer `data:` URIs for anything the page cannot do without: a reader
  with the network off sees nothing, and a remote image makes every reader's
  browser call that host directly, which hands a third party the IP address
  of everyone who opens the page.
- **Storage works** and is scoped to the page: `localStorage`,
  `sessionStorage`, `indexedDB` and cookies persist across reloads and across
  versions of the same page. Use it for a chosen tab or filter, never for
  anything the page cannot rebuild from its own content.
- **No parent access.** The viewer is a different origin, so
  `window.parent.document` and `window.top.location` throw. Superset injects
  one script into the page for comment anchoring; nothing else listens to
  `postMessage`, so don't build a handshake on it.
- **No form submission.** `form-action 'none'`: a `<form>` may exist for its
  controls, but submitting it goes nowhere. Handle inputs in script.

Scripts and popups *do* work. Inline JS runs normally, so charts, filters,
sorting, tabs, and interactive controls are all fine, as long as everything
they need is already in the file.

## The other hard limits

1. **`.html` only.** Any other extension is rejected at the CLI.
2. **One file, or one directory.** `superset pages publish ./report/`
   publishes a directory: `index.html` is the page, and every other file
   ships at its relative path, so `<video src="demo.mp4">`,
   `<link href="site.css">` and `<script src="app.js">` all work. Asset
   paths may not start with `versions/`, `files/`, `_superset/` or `~`, or
   be named `thumbnail.jpg`. Assets go up to 1 GiB each; on republish,
   unchanged assets are not re-uploaded. Prefer H.264 MP4 or WebM for
   video: iPhone `.mov` recordings may not play in every browser. Remote
   CDN links and external stylesheets are still blocked; for a single-file
   page, inline all CSS and JS and embed images as `data:` URIs.
3. **3 MB maximum for the HTML document itself**, and base64 `data:` URIs
   count toward it at ~1.37× their
   raw size. A few small SVGs or PNGs are fine; a photo gallery is not.
4. **Full-bleed frame with a white default background.** Set your own `body`
   background explicitly rather than inheriting.

Check before publishing: no `<script src>` or `<link rel="stylesheet">` pointing
at a remote host, no `fetch` of any kind including of a `data:` URI, no `eval`
or `new Function` anywhere in the file or in anything you inlined, page fits in
3 MB, opens correctly from `file://` with the network disabled. Remote images
are the one permitted exception: they go blank offline, which is the price of
not inlining them.

## Design

The page should look deliberate. Avoid the house style of generic AI output:
purple-to-blue gradients, everything centered, uniform pill-rounded corners on
every element, Inter (or system-sans) for every line, and emoji as section
icons. Those read as "generated" at a glance.

Instead: pick a real palette and hold to it, set a typographic scale with actual
contrast between heading and body, and let the layout follow the content: a
data-dense table wants
ticket-formatSkill

Canonical three-section structure for Linear and Superset tickets in this repo. Use when creating, drafting, or grooming a ticket.

project-structure-validatorSubagent

Validates project structure against co-location and architecture patterns defined in AGENTS.md

supersetSkill

Create workspaces, spawn agents, schedule automations, and manage Superset projects/tasks/hosts via the `superset` CLI. Use to orchestrate coding agents across devices from the terminal.

cdp-verificationSkill

Verify UI behavior end-to-end by driving the running desktop app over the Chrome DevTools Protocol. Use when asked to verify, reproduce, or confirm a UI change, bug, or regression in the real app rather than in tests.

db-migrationsSkill

Create a database migration with Drizzle on a fresh Neon branch. Use when changing the packages/db schema or generating migrations.

decideSkill

Walk the user through design or implementation decisions one at a time, or review completed code one change at a time. Use when the user says "walk me through each decision", "let's decide together", "help me work through these choices", "walk me through what you did", or "QA step by step". Present concise context, mutually exclusive options, log each answer, and finish with a summary.

redesignSkill

Critique and improve the visual design of an existing UI component with concrete implementation guidance. Use when the user asks to redesign, restyle, reimagine, polish, or improve a component, screen, or interface, especially in React and Tailwind codebases.

superset-settingsSkill

Read and update the Superset desktop app's user settings (theme, fonts, terminal, git, notifications, behavior) via the superset CLI, including creating and installing custom themes from JSON. Use when asked to change app settings, switch or create a theme, adjust fonts, or configure desktop preferences without opening the settings UI.