Infrastructure patch. Foundation for the v0.2 security track. No user-visible change.
src/render/safe.ts— single source of truth for every HTML/JS/JSON splice. Four helpers, one per context:escHtml(s)— HTML text contentescAttr(s)— HTML attribute value (delegates toescHtmlfor now)jsStr(s)— JS string-literal context, safe insideonclick='…'safeJSON(v)— JSON embedding in<script>, escapes<,>,&,U+2028,U+2029
tests/safe.test.ts— 22 tests for null/undefined collapse, character escapes, script-tag breakout, line-terminator handling, and a cross-helper invariant (no adversarial payload leaks a raw</script>).tsconfig.test.json+dist-test/— isolated test compilation so the stdlibnode:testrunner can execute compiled test files.package.jsonscripts:typecheck(tsc --noEmit),test(compile tests then runnode --test dist-test/tests/).- README "Developing" section with the new script invocations.
jsStr—JSON.stringifyleavesU+2028/U+2029raw, but the JS parser treats them as line terminators inside string literals, silently breaking the string. Added explicit\u2028/\u2029escapes. Caught by test 15 on the harness's first run.
- Zero new runtime dependencies. Zero new dev-dependencies — the test harness uses Node 18's built-in
node:testmodule.