Scaffold a new 100% client-side static web tool from the agent-webtool-template skeleton, implement its pure testable core + independent audit + tests, verify the gates locally, then create the GitHub repo, push, and enable Pages. Use when the user wants a free browser-based diagnostic / calculator / analyzer shipped as its own repo ("์ ์ ์น ๋๊ตฌ ๋ง๋ค์ด์ค", "GitHub Pages ๋๊ตฌ", "ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๊ณ์ฐ๊ธฐ/๋ถ์๊ธฐ", "์ด ์์ด๋์ด๋ก ์ ์น ๋๊ตฌ repo", "ํ ํ๋ฆฟ์ผ๋ก ์ ๋๊ตฌ"). Do NOT use for features inside an existing app, server-backed tools, or non-web deliverables.
Installation
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Scaffold a new 100% client-side static web tool from the agent-webtool-template skeleton, implement its pure testable core + independent audit + tests, verify the gates locally, then create the GitHub repo, push, and enable Pages. Use when the user wants a free browser-based diagnostic / calculator / analyzer shipped as its own repo ("์ ์ ์น ๋๊ตฌ ๋ง๋ค์ด์ค", "GitHub Pages ๋๊ตฌ", "ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๊ณ์ฐ๊ธฐ/๋ถ์๊ธฐ", "์ด ์์ด๋์ด๋ก ์ ์น ๋๊ตฌ repo", "ํ ํ๋ฆฟ์ผ๋ก ์ ๋๊ตฌ"). Do NOT use for features inside an existing app, server-backed tools, or non-web deliverables.
webtool-from-template
Turns a tool idea into a shipped, self-verifying, zero-dependency static site.
The mechanical steps (copy ยท rename ยท gates ยท repo ยท push ยท Pages) are owned by
scripts/scaffold.py; you only write the tool's domain logic. Reference build:
harness-quality-checker (five-axis harness analyzer), itself built this way.
The template pattern (what you inherit)
A agent-webtool-template-derived repo has five parts you keep and specialize:
File
Role
assets/compute.js
Pure core โ DOM-free, deterministic, dual export (browser global + Node module.exports) so the same code path is unit-tested and shipped.
data/*.json
Data / rules / fixtures, validated in CI. Keep scoring or config data-driven here, not hardcoded in JS.
assets/app.js
Thin DOM wiring: read inputs โ call the pure core โ render. No logic. Render user input with textContent/escaping, never raw innerHTML.
audit/reference_audit.py
Independent re-derivation (not copied from the JS) + hand-computed anchors + field-by-field JS parity.
test/compute.test.cjs
Objective unit gate (exit 0/1).
CI (validate.yml) runs unit + audit parity + JSON validation + HTML wiring;
pages.yml deploys to GitHub Pages. No npm, no pip, no build step.
Flow
Clarify the tool in one line: inputs โ deterministic output. If the logic
needs a model call or a server, this skill is the wrong tool โ stop.
Scaffold โ python3 scripts/scaffold.py new --name <slug> --title "<Title>" --dir <parent> --template-repo sylvanus4/agent-webtool-template. Produces a
local working copy with the example still passing.
Implement the pure core (assets/compute.js) โ keep it pure and
deterministic; put tunables/rules in data/*.json.
Rewrite fixtures (data/*.json) with hand-verifiable cases + expected
bands, and the independent audit (audit/reference_audit.py) as a second
implementation from the spec (this is what catches drift the unit test misses).
Rewrite the unit gate (test/compute.test.cjs) and the UI
(index.html + assets/app.js) โ thin wiring only.
Verify โ python3 scripts/scaffold.py verify --dir <path>. Both gates must
be green ([[evaluator-must-act]]: run them, don't eyeball).
Ship โ python3 scripts/scaffold.py ship --dir <path> --name <slug> --desc "<one-liner>". Creates the repo, pushes main, enables Pages. Then
confirm the live URL returns 200 and re-run the pages workflow if it fired
before Pages was enabled.
Invariants (do not break)
No runtime dependencies, no build step, no data egress. Same-origin static
JSON only. If a step needs a key or server, it does not belong here.
Pure core is the single source of truth; the Python audit is an independent
witness; both run in CI. Every shipped number is hand-anchored or agreed by two
implementations ([[sonnet-format-determinism]]: format/logic owned by code+data,
not model prose).
Regex/rule patterns must be portable โ identical behavior under JS RegExp
and Python re โ or JSโPython parity breaks.
Ship only a green build.ship runs the gates first and aborts on red.
External actions (repo create, push, Pages) need the user's go-ahead, per repo
policy โ ship is the explicit gate for that.
Optional patterns (proven in harness-quality-checker)
Bilingual (EN/KO) without a second core. Keep the pure core
language-agnostic (return ids + scores). Put display copy as {en,ko} bundles
in data/*.json; the app picks the language. Scoring never reads the copy, so
the Python audit parity is unaffected. UI chrome strings live in an I18N dict
in app.js; a applyChrome(lang) swaps them on toggle.
Deterministic "fix-it" generator (no model call). For analyzer/linter
tools, add a pure generate() that assembles a corrected artifact from the same
rules โ for each failing rule, emit its canonical clause (stored alongside the
rule). Write each clause to contain the phrase the analyzer matches, then
unit-test the property: analyze(generate(bad)) >= threshold. This gives a
genuinely useful "rough input โ satisfying output" feature that stays 100%
client-side and self-proving.
Lower the paste hurdle: load external content client-side (CORS-aware).
Let users load by URL / drag-drop / a bundled catalog instead of only pasting.
Rules learned the hard way:
CORS decides feasibility.raw.githubusercontent.com and
api.github.com send Access-Control-Allow-Origin: * โ browser-fetchable.
Many catalog sites (e.g. skills.sh) send no CORS header โ you cannot fetch
them from the page. Snapshot such a catalog at build time (Node, where CORS
doesn't apply) into data/*.json and ship it; fetch the actual content from a
CORS-open host (GitHub raw) on selection.
Normalize + pre-flight (pure, testable).normalizeSourceUrl (github.com
/blob/ โ raw) and isCheckable (reject HTML error pages / binaries / too-short)
run before the checker, with clear reasons. Then extractHarness pulls the
text + any fenced JSON. All three are pure โ unit-tested + audited.
Verify end-to-end against real files, not just fixtures ([[evaluator-must-act]]).
State the egress honestly in SECURITY.md: loading a URL is an outbound GET
of a public file (no credentials, no other input sent) โ not the same as "no
network ever". Reference: harness-quality-checker loaders + data/skills.json.
One engine, many rubrics. For a family of analyzers, the scoring engine is
rubric-agnostic โ a different data/rules.jsonis a different checker. To spin
up a sibling, copy the working tool (not the bare template), swap rules.json
(the axes/signals), examples.json (fixtures + bands), and the copy; keep the
engine, audit harness, loaders, and generator untouched. Rewrite the Python
audit's ANCHORS for the new axes but leave its generic score()/parity intact.
Proven: harness-quality-checker (harness axes) and skill-quality-checker
(SKILL.md authoring axes) share one engine; only the rubric differs โ so the
same input scores F on one and B on the other, each correctly. Verify the new
rubric discriminates on real inputs (a good artifact should out-score a thin
one), not just on synthetic fixtures.
Notes
The template lives at sylvanus4/agent-webtool-template (a GitHub template
repo). --template-repo lets you point at any static-web-tool repo to fork the
pattern from. For a sibling analyzer, point it at the closest existing tool
instead (e.g. sylvanus4/harness-quality-checker) and swap the rubric.
Prefer main as the default branch (both workflows and Pages assume it).