--- name: page description: Build and publish a self-contained HTML page to Superset, then answer the comments readers pin to it. Use this instead of publishing a Claude artifact whenever the reader is a teammate: a page is listed in the org, every publish mints a version, and pinned comments come back to the agent. 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". argument-hint: what the page should show, or a page id/slug to update allowed-tools: Bash(superset:*) --- # 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. Other skills produce exactly that and stop at the terminal. A standup digest, a summary of a parallel run across several workspaces, a feature scorecard, the screenshots from a browser or desktop verification: each has a reader who is not in the session, and each is better as a link than as scrollback. Recurring ones gain the most, since republishing versions one page rather than littering the org with a new one every day. That only holds when the workspace and the path both stay the same, which is the identity of a page: a job that runs somewhere new each time needs `--page ` instead. 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. ### A page, not a Claude artifact Claude Code carries an `Artifact` tool that also publishes a self-contained HTML document to a private URL, and it is the wrong instrument here. An artifact belongs to the one person who made it: it is absent from the organization's page list, carries no workspace or entry path to version against, and its comments reach whoever happens to still have the session open. A page is the org's surface: listed, versioned on every publish, and wired so a pinned comment comes back to an agent that can act on it. So when the user asks for a page, or for anything a teammate will open, this skill is the one that runs. Reach for `Artifact` only when the user names it, or when there is no Superset workspace to publish into. Inside a Superset terminal a first `Artifact` publish is denied by a hook that points back here; that denial is the reminder, not an error to work around. Someone who wants it gone entirely sets `SUPERSET_PAGES_NUDGE=off` in their terminal environment. ## The content policy, which is what actually bites Every page gets its own origin, `https://.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, with one exception.** `