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 verbatim

The 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

SkillOwns
effective-htmlthe implicit router; reports, explainers, landing pages, decks, tools, mixed artifacts
design-artifactpalette, type, composition, theming, register — composed with a specialist, never on its own
html-wireframelow-fidelity structure, 2–3 comparable layout directions
html-prototypepolished mockup, or a working flow with its real states
html-planplans and roadmaps that keep the source commitments verifiable
html-diagramtopology, 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:

  1. The agent writes the artifact and calls html_artifact_save.
  2. The app stores it, checks it, and answers with the id, /a/<id>, the ready-made emit_widget call, and the findings.
  3. The agent fixes anything at LỖI, saves again with the same id, 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

ToolDoes
html_artifact_savestore or update an artifact; returns id, view URL, emit_widget call, and the check
html_artifact_checkrun the same check without storing anything
html_artifact_listrecent artifacts, newest first, metadata only
html_artifact_getone artifact; include_html: true only when the HTML is actually needed
html_artifact_deleteremove 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 with default-src 'none' — inline CSS and JS run, but fetch, 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-html

Then <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.sh

Upstream

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 installed tot CLI. 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

@senclawtrusted
benji
51 packages · 21 downloads · member since 2026-07 · GitHub since 2015-06

The checkmark means SenClaw confirmed who this publisher is. It says nothing about whether their packages are safe.

About

Owner@senclaw
Latest1.0.0
Downloads0
Repositorygithub.com/NortonBen/senclaw-app ↗

Versions

VersionTagsArtifactsPublished
1.0.0latestdarwin-arm64, linux-x642026-09-02

Artifacts · 1.0.0

PlatformFormatSignatureFileSize
darwin-arm64zipunsignedeffective-html-app.zip1858 KB
linux-x64zipunsignedeffective-html-app.zip2061 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://senclaw.bacnd.com/api/v1/updates/tauri/senclaw/effective-html/{{target}}/{{arch}}/{{current_version}}"]

For an electron-updater app — generic provider URL:

https://senclaw.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://senclaw.bacnd.com/api/v1/packages/senclaw/effective-html