senclaw/effective-html
app Đưa bộ skill plannotator/effective-html (MIT) vào SenClaw: sáu skill dạy agent dựng MỘT file HTML tự chứa — router effective-html cho báo cáo/explainer/landing/deck, design-artifact cho hướng thẩm mỹ (bảng màu, chữ, bố cục, sáng-tối), html-wireframe cho khung sườn lo-fi so sánh 2-3 phương án, html-prototype cho mockup tĩnh hoặc luồng bấm được kèm đủ trạng thái, html-plan cho kế hoạch/lộ trình giữ nguyên cam kết gốc, html-diagram cho sơ đồ kiến trúc/luồng/trạng thái. Kèm sổ artifact cục bộ: agent lưu file HTML bằng html_artifact_save rồi chèn thẳng vào ô chat qua widget effective-html.artifact, không cần ghi file tạm. Mỗi lần lưu app tự soi hợp đồng build (tài nguyên mạng, font CDN, thiếu lang/viewport/title, quên prefers-reduced-motion, quên :focus, 100vw, chữ mồi) và báo lỗi kèm số dòng. Artifact chạy trong iframe origin mờ và header default-src 'none' — không gọi mạng, không chạm được API của app. Toàn bộ dữ liệu nằm trên máy người dùng, app không đăng nội dung ra ngoài.
Install
senclaw app install senclaw/effective-html
Verifies sha512 and SenClaw’s signature before writing to disk.
Documentation
Effective HTML
[plannotator/effective-html](https://github.com/plannotator/effective-html) as a SenClaw Space App: six skills that teach an agent to produce one self-contained .html file, plus somewhere for the finished artifact to live and a widget that puts it straight into the chat box.
Upstream is a skill collection you install into a coding agent that has a filesystem, and it hands back an absolute path. SenClaw's user is in a chat window, so this app supplies the missing half: a local notebook, a check of the build contract the skills promise, and two widgets.
apps/effective-html/
src/store.rs SQLite notebook → ~/.senclaw/space-apps/effective-html/artifacts.db
src/check.rs the build contract, enforced instead of merely written down
src/api.rs REST + the /a/<id> artifact viewer (default-src 'none')
src/mcp.rs five html_artifact_* tools
skills/ the six vendored skills (MIT — see skills/LICENSE-upstream)
web/ React + Vite + Ant Design UI (light/dark)
web/public/ widget/artifact.html + widget/gallery.html, copied verbatimThe two chat widgets stay plain HTML in web/public/ rather than becoming Vite entries. A widget iframe is mounted per chat message, so it has to stay ~3 kB; the notebook UI it sits beside is ~310 kB gzipped of React and antd.
The shell follows the OS theme until the user picks Sáng/Tối, and an explicit choice also writes data-theme on <html> — the same attribute-beats-media-query contract design-artifact asks of the artifacts themselves.
The six skills
| Skill | Owns |
|---|---|
effective-html | the implicit router; reports, explainers, landing pages, decks, tools, mixed artifacts |
design-artifact | palette, type, composition, theming, register — composed with a specialist, never on its own |
html-wireframe | low-fidelity structure, 2–3 comparable layout directions |
html-prototype | polished mockup, or a working flow with its real states |
html-plan | plans and roadmaps that keep the source commitments verifiable |
html-diagram | topology, sequence, process, state, hierarchy, timeline |
Directory names match upstream, so the skills' relative cross-links (../design-artifact/SKILL.md) still resolve. Only the router was renamed — upstream calls it html, which is too generic for a global skill registry.
How an artifact reaches the chat
An HTML document is far too big for an emit_widget query string, so the widget carries an id instead:
- The agent writes the artifact and calls
html_artifact_save. - The app stores it, checks it, and answers with the id,
/a/<id>, the ready-madeemit_widgetcall, and the findings. - The agent fixes anything at
LỖI, saves again with the sameid, then emits the widget.
skills/effective-html/references/senclaw-delivery.md is where that flow is written once; all six skills link to it.
MCP tools
| Tool | Does |
|---|---|
html_artifact_save | store or update an artifact; returns id, view URL, emit_widget call, and the check |
html_artifact_check | run the same check without storing anything |
html_artifact_list | recent artifacts, newest first, metadata only |
html_artifact_get | one artifact; include_html: true only when the HTML is actually needed |
html_artifact_delete | remove one, permanently |
The check
src/check.rs scans for what the skills already require and prose cannot enforce: external resources and font CDNs, fetch/WebSocket/XMLHttpRequest, a missing doctype/lang/viewport/charset/title, animation without prefers-reduced-motion, controls without :focus, a dark theme with no [data-theme] override, 100vw, and placeholder copy. Findings carry a rule name and a line number.
It is a text scanner, not a browser. It cannot see contrast, a broken layout, or a dead button — the skills still require opening the artifact at a wide and a narrow width. Error means the self-containment contract is broken; Warn means it renders but misses something.
The rules are calibrated against upstream's own reference artifacts: all 14 HTML files under examples/ and site/public/examples/ in plannotator/effective-html pass with zero errors and zero warnings. Two rules were narrowed to get there — viewport-width fires only on a bare width/min-width: 100vw, never on the defensive max-width: calc(100vw - N) every upstream artifact uses; and theme-toggle fires only when a page writes data-theme that no CSS selector reads, since design-artifact explicitly allows an OS-only or single-theme concept.
What the sandbox costs
A stored artifact is model-written HTML, so it is contained twice over:
/a/<id>is served withdefault-src 'none'— inline CSS and JS run, butfetch, remote images, CDN fonts and form posts do not;- the widget and gallery frame it without
allow-same-origin, so it runs on an opaque origin and cannot reach the app's REST API or its own storage.
The cost: localStorage throws inside the frame, so prototype state has to live in memory. Opening /a/<id> as its own page lifts that.
Local run
cargo run -p effective-htmlThen <http://127.0.0.1:4780>. PORT overrides the port; SENCLAW_BIND_HOST=0.0.0.0 opts into exposing the app — including every stored artifact — to the LAN. SENCLAW_DATA_DIR moves the database.
apps/effective-html/scripts/pack.shUpstream
The skills/ tree is vendored from plannotator/effective-html under the MIT licence, kept verbatim except for:
- the router skill's directory and
name(html→effective-html); - SenClaw frontmatter on each skill (
version,when-to-use,triggers,allowed-tools,upstream); - each skill's "return the absolute file path" handoff, which now points at
senclaw-delivery.md; design-artifact's closing section, which upstream uses to offer publishing the artifact to a public URL via a globally installedtotCLI. A Space App installs nothing globally and publishes nothing — the artifact stays on the user's machine and they decide whether to share it.
The full licence is at skills/LICENSE-upstream.
Declared permissions
{
"network": [
"127.0.0.1"
],
"exec": [
"./effective-html"
]
}Declared by the publisher, not enforced by SenClaw. The CLI compares this against what you already have installed and asks before anything widens.
Published by
The checkmark means SenClaw confirmed who this publisher is. It says nothing about whether their packages are safe.
About
| Owner | @senclaw |
| Latest | 1.0.0 |
| Downloads | 0 |
| Repository | github.com/NortonBen/senclaw-app ↗ |
Versions
| Version | Tags | Artifacts | Published |
|---|---|---|---|
1.0.0 | latest | darwin-arm64, linux-x64 | 2026-09-02 |
Artifacts · 1.0.0
| Platform | Format | Signature | File | Size |
|---|---|---|---|---|
darwin-arm64 | zip | unsigned | effective-html-app.zip | 1858 KB |
linux-x64 | zip | unsigned | effective-html-app.zip | 2061 KB |
Unsigned builds require sign-in to download and are not distributed to the auto-updater, because unsigned executables from a new domain get flagged as unsafe. Sign and notarize (macOS) or Authenticode-sign (Windows) to distribute publicly.
Auto-update endpoints
For a Tauri app — add to tauri.conf.json:
"endpoints": ["https://hub-store.bacnd.com/api/v1/updates/tauri/senclaw/effective-html/{{target}}/{{arch}}/{{current_version}}"]For an electron-updater app — generic provider URL:
https://hub-store.bacnd.com/updates/senclaw/effective-html/stable
Only signed/notarized artifacts are offered as updates — a client fetches the update without credentials, and unsigned binaries are not publicly downloadable.
Something wrong with this package?
Report this package
Report this package
Tell us what is wrong and a moderator will look at it. Be specific — a report that names a version and a behaviour can be checked in minutes; one that says “looks sketchy” cannot be acted on at all.
Not about this package? Contact us instead. What happens to a report is described in reporting and moderation.
API: GET https://hub-store.bacnd.com/api/v1/packages/senclaw/effective-html