본문으로 건너뛰기
cccskills
무료GitHub에 공개

viewer-render

Render the running viewer in a real headless browser and assert on what it drew — element geometry, computed colours, wrap points, truncated labels, console errors. Use when a change moves pixels (navbar/badge/chart layout, CSS, responsive behavior, theme), when a PR says it "needs a visual check", or when reviewing frontend work under src/viewer/assets/. Covers the gap viewer-smoke names: it asserts payload shape, this asserts rendering.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Rendering the viewer for real

Why this exists

Three layers of viewer testing already exist and none of them can see the page:

  • tests/*.test.mjs — pure frontend logic, no DOM by design (CLAUDE.md: "no bundler, no jsdom").
  • tests/viewer_smoke.sh — API envelopes. Its own "what it does not cover" section says "Browser-rendered UI … visual regressions need eyeball verification."
  • CI — compiles both backends. Compilation is not rendering.

So a change can be green everywhere and still ship a label at the disabled contrast tier, a chip strip that wraps out of the navbar, or a mithril keyed fragment that warns on every redraw. This renders the page in Chrome and reports what actually got drawn.

Two traps, both of which bite on the first run

1. Set REZOLUS_NO_OPEN=1. A second after binding, rezolus view opens the dashboard in the user's real browser (src/viewer/mod.rs). It is an environment variable, not a CLI flag, so it is easy to miss — and a headless session that starts seven viewers across a review silently opens seven tabs on someone's desktop. Always set it.

2. Build with --features developer-mode. The binary embeds src/viewer/assets/ at compile time. A normal cargo build bakes in whatever the assets were when it last ran, so you screenshot the old frontend, see your change missing — or worse, see something plausible and conclude it works.

cargo build --bin rezolus --features developer-mode          # assets from disk
REZOLUS_NO_OPEN=1 target/debug/rezolus view --listen 127.0.0.1:4299 /tmp/x.rez &

If the render disagrees with the source you are reading, it is trap 2.

Setup

puppeteer-core plus a browser already on the machine. Do not add either to the repo — it deliberately carries no JS toolchain, and puppeteer (without -core) downloads ~150 MB of Chromium you do not need.

mkdir -p /tmp/viewer-render && (cd /tmp/viewer-render && npm i puppeteer-core)
export PUPPETEER_CORE=/tmp/viewer-render/node_modules/puppeteer-core
export CHROME_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"

CHROME_PATH is optional where Chrome sits in a standard location; the script probes the usual macOS and Linux paths.

Plain chrome --headless --screenshot=out.png <url> hangs on this page — the dashboard never reaches the quiescent state that flag waits for. Use the script, which waits on networkidle2 plus a selector.

Use it

# 1. Assets from disk, and no browser tab on the user's desktop.
cargo build --bin rezolus --features developer-mode
REZOLUS_NO_OPEN=1 target/debug/rezolus view --listen 127.0.0.1:4299 /tmp/three.rez &

# 2. Render and inspect.
node scripts/viewer_render.mjs \
  --url http://127.0.0.1:4299 \
  --selector '.compare-badge' \
  --children '.compare-badge-label' \
  --out /tmp/badge.png

Stdout is a JSON block: tag, classes, computed colours, box geometry, per-child text/title/colour/truncation, rowTops, wrapped, consoleProblems, failedRequests. Two PNGs land beside --out: the element, and the top band of the page for layout context.

--children matters more than it looks. It defaults to direct children, and in this UI the node carrying the text, the tooltip and the truncation is usually a grandchild — a label inside a chip. Point it at that node or the interesting fields all read null.

Read the JSON, not just the picture

The screenshot is for the human in the PR. The JSON is what you assert on:

  • wrapped / rowTops — distinct child row tops mean the content broke onto more than one line. Sweep --width 1440 1280 1100 1000 820 to find the point where it happens; one screenshot at one width hides this entirely.
  • children[].truncated — scrollWidth past the painted width means an ellipsis is eating text. If that child has no title, the text is unrecoverable by the user. Truncation plus a missing tooltip is a finding.
  • children[].color — resolve the actual computed colour. --fg-muted is the disabled tier (#484f58 on dark); --fg-secondary (#8b949e) is "dimmer but meant to be read". Picking the wrong one looks fine in the CSS and wrong on screen.
  • consoleProblems — mithril keyed-fragment violations, exceptions in a redraw, and every console.warn (the viewer warns when it drops a link parameter the recording cannot satisfy, so a check on such a link expects those entries rather than an empty list). Silent in every other test layer.
  • failedRequests — a 404 on a newly added shared module means a missing site/viewer/lib symlink (see the viewer-parity skill), which breaks the static viewer completely.

Check both themes

Colours are CSS custom properties overridden under [data-theme="light"], and --fg-muted inverts between them. --theme light / --theme dark sets the attribute directly, so one run per theme covers both.

Where the script lives, and why not tests/

scripts/viewer_render.mjs. CI runs node --test tests/*.mjs, and that glob takes every .mjs in the directory, not just *.test.mjs — a tool parked there gets executed as a test and fails the suite.

Fixtures

rez's fixture writer caps at four recordings:

cargo run -p rez --features test-support --example write_rez_fixture -- /tmp/four.rez 4

For more arms — worth doing, since layout problems only appear at scale — combine archives:

target/debug/rezolus recording combine /tmp/four.rez /tmp/three.rez -o /tmp/seven.rez

Known noise

A bare fixture has no systeminfo, so /api/v1/systeminfo and /api/v1/selection 404 and surface in failedRequests. Not your change.

What this still does not cover

  • The WASM/static viewer. This drives rezolus view (the axum server). The frontend is symlinked and therefore identical, but the backend answering /api/v1/* is not — see the viewer-parity skill. To render that side you need ./crates/viewer/build.sh and a static server over site/.
  • Interaction. Hover, click, drag, dropdown open/close. Puppeteer can do all of it; the script just does not, yet.
  • Pixel regression. No baseline images are stored, deliberately — they rot. The JSON facts are the durable assertion.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Write or update the CLI `--help` text and README section for a new or changed rezolus feature (a subcommand, flag, mode, or behavior change), then prove the help is usable by dispatching a fresh subagent that has never seen the code. Use this whenever you add or change how rezolus is invoked — new `rezolus <subcommand>`, new flags/args on an existing mode, renamed options, or changed defaults — and any time the user says the help/README is thin, stale, confusing, or "an agent couldn't figure this out." Treats help text as an interface under test, not prose.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

Use when starting or picking up a non-trivial effort (feature, investigation, perf probe, refactor, migration) in a shared repo where teammates or future agents must coordinate or hand off; when a repo has no durable in-tree record of decisions and dead-ends; when you're about to drop a well-measured negative result; or when bootstrapping a journal from a repo's commit history.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

pr

무료

Create a feature branch, commit changes, push, and open a PR against iopsystems/rezolus

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

Tag and push a prerelease from the current Cargo.toml version. Use when the user wants to cut an alpha/beta/rc prerelease. Aborts on stable versions (no `-` in version string) and if the tag already exists.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

release

무료

Create a release PR with version bump and changelog update

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

Use when reviewing a Rezolus sampler change before merge — a new sampler, a change to an existing sampler's probes/refresh/metrics, or core changes that affect samplers; or whenever a sampler's overhead, cadence, or data source is in question.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

iopsystems/rezolus2772026년 10월 20일 업데이트

iopsystems의 스킬 모두 보기

이 스킬의 문제 신고