Ae1
High
- Category
- analysis-evasion
- Content
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
- Confidence
- 100% confidence
- Finding
- Referenced artifact was not completely inspected
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a disclosed local image-rendering tool, with expected browser and file-output behavior for its purpose.
Install only if you are comfortable with a local Chromium-based renderer. Do not render HTML you do not trust, because page JavaScript can run and make outbound requests, and local assets under the input/base directories can be exposed to that page during rendering. Review optional npm, npx, and sudo setup steps before running them.
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `render.mjs` | one design → **one image** (og card, badge, element, page, SVG) |
| `icons.mjs` | one design → **a favicon or app-icon set** (`.ico`/`.icns`/apple-touch/PWA) |
| `icons.mjs` | one design → **a favicon or app-icon set** (`.ico`/`.icns`/apple-touch/PWA) |
<!doctype html> <!-- html-shot starter template: a transparent, square mark — an app icon, a favicon master, a badge. The counterpart to template.example.html, which is an opaque 1200x630 card.
<!doctype html> <!-- html-shot starter template: a 1200x630 social card. System fonts only, so it renders out of the box with no /fonts directory.
npx skills add rockbenben/aishort-skills ``` Or clone this repo and copy (or symlink) `skills/html-shot/` into your agent's skills folder — `~/.claude/skills/` for Claude Code, `~/.agents/skills/` for the cross-runtime convention Codex and Gemini CLI also read, or wherever your agent keeps them.
**First run only** — install the engine: ```bash # $SKILL_DIR = wherever the skill landed (Claude Code: ~/.claude/skills/html-shot) SKILL_DIR=~/.claude/skills/html-shot cd "$SKILL_DIR" && npm install && node node_modules/playwright/cli.js install chromium ```
**仅首次运行** —— 装引擎: ```bash # $SKILL_DIR = skill 实际所在目录(Claude Code 为 ~/.claude/skills/html-shot) SKILL_DIR=~/.claude/skills/html-shot cd "$SKILL_DIR" && npm install && node node_modules/playwright/cli.js install chromium ```
**仅首次运行** —— 装引擎: ```bash # $SKILL_DIR = skill 实际所在目录(Claude Code 为 ~/.claude/skills/html-shot) SKILL_DIR=~/.claude/skills/html-shot cd "$SKILL_DIR" && npm install && node node_modules/playwright/cli.js install chromium ```
1. **First run only** — install the engine (below). If it is already installed, `render.mjs`
just works; if it is not, the script exits with the exact install command to run.
2. **Write or copy the HTML.** Two starters, and they size themselves differently on purpose:
- `template.example.html` — a card. `body` gets an explicit `width`/`height` in px and the
output size flows from there.
- `icon.example.html` — a transparent mark or app icon. The shape sits on a **child**node {SKILL_DIR}/node_modules/playwright/cli.js install --with-deps chromium
# 2. CJK + emoji system fonts, or non-Latin text renders as tofu boxes (□□□)
sudo apt install fonts-noto-cjk fonts-noto-color-emoji # Debian/Ubuntu
```
`{SKILL_DIR}` is this skill's own directory — whatever path the agent reports when it loadsnode {SKILL_DIR}/node_modules/playwright/cli.js install --with-deps chromium
# 2. CJK + emoji system fonts, or non-Latin text renders as tofu boxes (□□□)
sudo apt install fonts-noto-cjk fonts-noto-color-emoji # Debian/Ubuntu
```
`{SKILL_DIR}` is this skill's own directory — whatever path the agent reports when it loadsif (want.has("pwa") && presetName === "next")
fail(`the PWA pair cannot share an output directory with --preset next: these two files belong in public/, but the next preset writes App Router convention names into app/. Build them separately:\n node icons.mjs ${source} public --only pwa`);
// The default needs no checking, so all of this is about a --bg the user actually passed.
const bg = opts.bg ?? "#ffffff";
if (opts.bg) {
// Same rule as --small: what decides whether --bg does anything is whether THIS run writesDetected: suspicious.dangerous_exec