Supersetの利用状況を調べ、まだ使っていない機能と活用方法を提案します。定期実行や並列作業、タスク管理などを一つずつ説明し、選んだ機能を実際に設定します。
- 未使用のSuperset機能を知りたいとき
- エージェントの定期実行を設定したいとき
- 別ワークスペースで並列作業したいとき
レポートや比較表、ダッシュボードをHTMLページにまとめてSupersetで共有し、公開ごとの版管理と、読者がページ上に付けたコメントへの対応まで進めます。
Build and publish a self-contained HTML page to Paradev (formerly 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". Also use it unprompted to offer a page when you finish output a teammate will read: a change or PR walkthrough, a comparison, a report or digest, an incident writeup, or verification screenshots.
実行スコア 未検証
インストール方法を見るレポート、比較表、グラフなどをHTMLページにまとめ、Supersetで共有リンクを発行します。公開するたびに版が残り、同じページを更新して使い続けられます。読者はページ内の要素にコメントを付けられ、エージェントが元ファイルの修正、再公開、返信、解決済みへの変更まで進めます。フィルターやタブなどの操作を備えたページも作れます。
チームに調査結果や変更内容を見てもらう場面に向いています。定期レポートを同じリンクで更新したい場合や、指摘された箇所を確認しながら修正したい場合にも使えます。共有ストレージを使った投票やチェックリストにも対応します。
SupersetのCLIを使います。HTML本文は16 MBまでで、単一ファイルか、index.htmlを含むディレクトリを公開します。通常のスクリプト通信や外部スクリプトの読み込みは制限されます。新規ページの公開範囲は既定で組織内です。元ファイルを移動した場合などは、ページIDを指定して更新します。
この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。
SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。
点数には入れていません。 2026年10月29日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。
インストールする前に、エージェントに与えられる指示の中身を確認できます。
paradev is an alias for the superset CLI: every superset command here also runs as paradev.
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.
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 <id> instead.
Don't publish when the artifact belongs in the repo (source, docs, config: put
those in files and commit them), or when it needs its own server, database
connection, or login flow. A page has none of those, but it can show live data
from the viewer's connected plugins (see references/storage-and-tools.md).
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.
Most people never go looking for this feature, so the offer is the onboarding. When you finish something that has a reader and wants a link, say so and offer to publish it. Don't wait to be asked, and don't publish silently either: a page the user didn't want still lands in their org's list.
Offer when the thing you just produced is one of these:
One line is the whole offer, and it names what the page would be:
This reads better as a page your team can open and comment on. Want me to publish it?
Then stop and let them answer. Publish on a yes, drop it on a no, and don't raise it again for the same piece of work.
Stay quiet the rest of the time. An ordinary answer, a quick fix, a question you just answered in two sentences, a file you edited: none of those want a link, and an offer attached to every reply is noise that trains people to ignore the one that matters. If you already offered in this session and were turned down, take that as the user's standing preference unless they say otherwise. When the user asked for a page outright, skip the offer and build it.
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 Paradev workspace to publish into. Inside a Paradev
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.
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:
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). For live data, use window.superset.tools
(references/storage-and-tools.md).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.<script src="https://…"> is always blocked. <link rel="stylesheet" href="https://…"> is blocked too, except from fonts.googleapis.com, so
a Google Fonts <link> tag works as-is. A directory publish's own files
load fine (relative src/href), and any remote font file is allowed,
so an inline @font-face { src: url(https://…) } also works for fonts
from elsewhere.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.localStorage,
sessionStorage, indexedDB and cookies persist across reloads and across
versions of the same page, but only in that one browser. Use it for a chosen
tab or filter. For anything the page should remember for everyone, use
window.superset.storage below.window.parent.document and window.top.location throw. Paradev injects
its own scripts for comment anchoring and for the storage API; don't build a
postMessage handshake of your own on top of them.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.
window.superset.storageA page can remember things for everyone who opens it. Each key holds one slot per person: you write yours, you read everyone's. That makes a poll, an RSVP sheet, a claim list or a checklist a few lines, and it makes two people writing at once a non-issue, because nobody ever writes someone else's slot.
const store = window.superset?.storage;
if (await store?.ready) {
await store.set("lunch-vote", "Ramen"); // my slot under this key
const mine = await store.get("lunch-vote"); // read it back
const all = await store.getAll("lunch-vote");
// [{ userId, name, value, updatedAt }, ...] everyone's slots
store.subscribe("lunch-vote", (records) => render(records));
await store.remove("lunch-vote");
}
Rules that matter when you write one:
store is undefined and store.ready resolves
false wherever there is no host: the thumbnail renderer, a file://
preview, a signed-out reader. Render a sensible read-only view from zero
records rather than a broken page.getAll on every
render. Never keep a running count in a record.error.code, never on the message: quota_exceeded,
rate_limited, unauthenticated, invalid, unavailable, and revoked.
revoked is terminal: the page's access changed while it was open, so
surface it once and stop retrying.store.viewer is { userId, name, image }, store.author is true for the page's author, and
store.writable says whether this viewer may write. Use store.author for
controls only the author should have, like closing a poll.everyone page gets no storage, so the page must still render.references/storage-and-tools.md..html only. Any other extension is rejected at the CLI.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.data: URIs
count toward it at ~1.37× their
raw size. A few small SVGs or PNGs are fine; a photo gallery is not.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
16 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.
Every page is served with a stylesheet of ours inlined at the top of <head>.
You never write it. The origin injects it into the document on the way out, so
it reaches pages published before it existed too. It gives bare HTML a readable
default: type scale, links, lists, tables, code blocks, box-sizing,
responsive images. Don't inline a CSS reset, a normalize, or a webfont.
Write semantic HTML and most pages need no <style> block at all.
What it deliberately does not set, because it reaches pages written before it
existed and those pages never agreed to it: padding on body, a width cap on
your text, or a height on your <iframe>s. The frame stays full-bleed and the
measure is yours to choose (see --sp-measure below).
Start from this skeleton:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Q3 pipeline</title>
</head>
<body>
<main>
<h1>Q3 pipeline</h1>
<p>Where every open deal stands going into Q4.</p>
<section>…</section>
</main>
</body>
</html>
Every rule in the theme is wrapped in :where(), which carries no
specificity. Any selector you write beats it: body { background: #0b0b0b }
in your own <style> wins outright, and a class of your own is never touched
by it. So the theme is a floor, not a cage: lean on it for the ordinary parts
and style the parts that make this page itself.
The theme is light unless you ask for dark, with a class on <body> that flips
background, text, borders, code blocks and native controls together:
<body class="dark">
<!-- or class="light", which is the default -->
</body>
It does not follow the reader's system setting on its own, and that is
deliberate. A page that set a background but no text colour, or set one on
<html> rather than <body>, would take the other half of the pair from a
palette that inverted underneath it, and end up dark text on a dark ground.
Opting in keeps that decision with the page that can actually see its own
colours.
So: add class="dark" when the page's visuals assume it: a chart with
baked-in colours, a screenshot with a dark background, a diagram with hardcoded
strokes. To follow the reader's system setting, ask for that too:
<body class="auto">
auto is the right choice for text and tables, where nothing is pinned to one
scheme. Use it whenever the page has no baked-in colours of its own, but reach
for it deliberately, and if you hardcode any colour anywhere on the page, set
its partner as well so the pair can never come from two different themes.
These are Paradev's own palette, so a page read next to the app belongs to it. Build on them rather than hardcoding colours and both themes keep working:
| Token | What it is |
|---|---|
--sp-bg | Page background |
--sp-surface | Raised or inset panels |
--sp-text | Body text |
--sp-muted | Secondary text, captions, table headers |
--sp-border | Rules and hairlines |
--sp-accent / --sp-accent-text | Links and emphasis, and text on top of the accent |
--sp-code-bg | Code background: a translucent tint of the surrounding text colour, so it sits on whatever background the page paints |
--sp-chart-1 … --sp-chart-5 | Categorical series colours, distinct in both themes |
--sp-radius | Corner radius |
--sp-measure | Reading measure for prose blocks |
--sp-font-sans / --sp-font-mono | Font stacks |
The accent is a near-neutral, the way the app's is. It carries emphasis
through weight and underline rather than hue. Reach for --sp-chart-* when you
need colours that separate from one another, and don't paint a chart in five
shades of the accent.
Redefine any of them on :root to re-skin the whole page in one place:
:root {
--sp-accent: #b4531f;
--sp-measure: 62ch;
}
Define overrides on :root, not on body. The theme's own values live on
:root, and a value set closer to the content would win in only one of the two
colour schemes.
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: hold to one palette (the tokens above, or a real one of your own) set a typographic scale with actual contrast between heading and body, and let the layout follow the content: a data-dense table wants a wide flush-left page, a narrative report wants the default measure. Use whitespace for grouping instead of borders on everything.
Make it responsive with relative units and flex/grid, and give wide content
(tables, code blocks, charts) its own overflow-x: auto container so the page
body never scrolls sideways.
If the user's project has a design system, read it first and match it.
superset pages publish report.html \
--title "Q3 pipeline" \
--description "Where every open deal stands going into Q4" \
--label "first draft"
# Or a directory: index.html is the page, everything else rides along
superset pages publish ./report/ --title "Q3 pipeline"
--title defaults to the filename with dashes and underscores turned into
spaces, so name the file well or pass the flag. --label is what shows in
version history; write what changed, not "update".
Attach a workspace whenever you have one. The CLI records the file's path relative to the workspace root as the page's entry path, and that path is the key: publish the same path again and it becomes version 2 of the same page rather than a second page. That is the only way a republish versions itself without you tracking an id.
Write the .html inside the workspace, not in /tmp or an agent
scratchpad. A file outside the workspace has no relative path, so it falls back
to being keyed by filename alone (/external/report.html), which means two
unrelated files with the same name will version each other. Keeping it in the
workspace also keeps the source next to the work it describes.
Outside a workspace entirely (a chat session, or a shell with no
$SUPERSET_WORKSPACE_ID and no --workspace) the publish still goes through.
The page is created and listed like any other; it just has no entry path, so
there is nothing for a later publish to resolve against. The result says
"unanchored": true and carries a republish command with the id already in
it. Keep that command and run it to add a version. Publishing the same
file again without --page creates a second page, and the link you already
shared keeps showing the first.
Keep the source file. It is the only copy you can edit; the published version is derived from it.
Two routes, and the difference matters:
superset pages publish report.html --label "fixed Q3 totals" # same path in the same workspace
superset pages publish report.html --page <page-id> --label "…" # anywhere, explicit
Use --page whenever you're outside the original workspace, the file moved, or
you're not certain the path still matches. A wrong guess doesn't error; it
quietly creates a new page, and the reader's link keeps showing the old one.
org (the default) or just_me, set with --visibility. Anything wider is not
settable from the CLI. A new page is readable by the org, because that is what a
page is usually for; pass --visibility just_me when the user wants a draft only
they can open.
Visibility belongs to the page, not to the publish. Republishing never changes
it, so a page someone narrowed to just_me stays that way through every later
version, and a page created before org became the default is still just_me
until someone widens it.
superset pages list --workspace <id> # or omit --workspace for the whole org
superset pages list --search "Q3 close" # -q also works; matches title or slug
superset pages get <page-id-or-slug>
superset pages versions <page-id-or-slug>
superset pages pull <page-id-or-slug> --version 2 > v2.html
pull writes HTML to stdout; use it to recover a source file you no longer
have, or to diff what actually shipped against what you have locally.
list returns every page it can see, so reach for --search before you reach
for a pipe into grep. Two flags change that: --limit <1-200> returns a
single batch, and --cursor continues from where a batch stopped.
They also change the JSON. Under --json, a plain list is a bare array, but
passing either flag wraps it as { items, nextCursor }. Feed that nextCursor
back as --cursor until it comes back null. Parsing the output? Either don't
pass the flags, or handle the envelope. The other two modes are unaffected: the
default table looks the same and tells you when there's more, and --quiet
prints ids either way.
get carries workspaceLinks: the workspace and the path each publish
resolved against. When you have lost the source, pull it back to that path
inside that workspace and a later publish versions the page instead of minting
a second one. An empty list means the page has no path to resolve against, so
--page <page-id> is the only way to add a version.
A reader clicks an element on the published page and pins a comment to it. When
they hand the thread to an agent, the prompt that arrives names the page, and
for each thread gives a thread: id, an at: CSS selector path from <body>,
and the element's text at the time of writing.
That selector points into the published HTML, which is the same document as
your source file. That document is the index.html you published, not any
asset beside it, so the anchor locates the exact element to edit. Quoted text alone doesn't; the same words often
appear more than once.
The loop, in order:
superset pages comments list --page <page-id-or-slug>
# edit the source file, fixing what each thread asked for
superset pages publish report.html --page <page-id> --label "addressed review comments"
superset pages comments reply --thread <thread-id> "Recomputed from the Q3 close; the total is 1.42M now."
superset pages comments resolve --thread <thread-id>
Rules that keep this honest:
Reopen with superset pages comments resolve --thread <id> --reopen.
| Symptom | Cause |
|---|---|
Only .html files can be published as a page | Wrong extension, or you pointed at a directory |
| Publish rejected on size | Over 16 MB; the data: URIs are almost always why |
| A new page appeared instead of a version | Published from outside the workspace, or the path changed; use --page <id> |
| Reader gets a 404 | Page is just_me, either set that way or created before org became the default; widen it with --visibility org |
| Page is blank once published, fine locally | A script threw, or the page loads a script or stylesheet from a remote host |
| A chart or widget renders nothing and logs no error | The library compiles code with new Function or eval, which the policy refuses; pick one that does not |
| Fonts missing when published | A stylesheet <link> from a host other than fonts.googleapis.com; inline the @font-face instead, or use --sp-font-sans |
Page ignores class="dark" | The class belongs on <body>, not on <html> or a wrapper |
| A theme token has no effect | It was redefined on body; move the override to :root |
| Images missing when published | http:// URLs, or the reader is offline; embed as data: URIs |
まだレビューはありません。使ってみた感想をお寄せください。
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
Supersetの利用状況を調べ、まだ使っていない機能と活用方法を提案します。定期実行や並列作業、タスク管理などを一つずつ説明し、選んだ機能を実際に設定します。
繰り返し作業をSupersetで自動化するために、エージェントへの指示と実行時刻・イベント条件を整え、承認後の作成から初回実行の確認まで進めるスキル。
Superset内のブラウザでページ閲覧・クリック・入力を行い、画面やコンソールを確認します。開発中のWebアプリの動作確認やフォーム操作を支援します。
Stripeの決済・定期課金・請求書連携を、公式資料とAPIの引数定義を確認しながら実装します。製品選びからテスト環境での検証、Webhook処理の設計まで扱います。
実際に起動しているデスクトップアプリをChrome DevTools Protocolで操作し、画面遷移や状態を記録しながらUI変更や不具合を確認します。
GitHub Actionsの失敗ログから最初の原因を探し、コードの不具合・環境要因・断続的な失敗・既存障害を切り分け、PRとの関係と次の対応を整理します。