Rebuild the vendored marked bundle at 18.0.10 - #32
Conversation
The pin lives in scripts/vendor-marked.sh as a shell variable, so dependabot cannot see it; the weekly sweep is what catches the drift. 18.0.8 through 18.0.10 are bug fixes to emphasis, blockquote continuation, task-list checkboxes, and EOF backtick fences. No API change, so leaf.js's Marked construction is untouched.
leaf-agent
left a comment
There was a problem hiding this comment.
Reviewed as a self-authored PR, so this is a COMMENT rather than an approval. No findings against the diff — the bump verifies out, and the one red check is not this change.
The bundle is authentic. npm pack marked@18.0.10 and sha256 on package/lib/marked.esm.js gives 4cf47dfebb7f614a08fc0a579ab0fe407ff0ed2b717bf953040c85b2f493a4f0, byte-identical to the vendored copy — so the file is exactly what scripts/vendor-marked.sh produces at the new pin, with no hand-edit in it. 18.0.10 is npm's current latest, and the upstream release notes for 18.0.8–18.0.10 are bug fixes only, matching the description's account of them.
The runtime's construction still holds. Loading the new bundle in node and building it the way leaf.js does — new Marked({breaks: true, renderer: {html: (t) => escapeHtml(t.text)}}) — Marked/Lexer/Parser/Renderer are all still exported, a single newline renders <br>, and both block and inline raw HTML route through the html override: <div onclick="x"> and <img src=x onerror=alert(1)> come back escaped, and `Vec<T>` stays a codespan.
The red test is unrelated to this diff, and is a shape #26 has already diagnosed and fixed. Run 32632120929 reports 1 failed, 1010 passed, 6 skipped, the failure being test_an_open_tab_reloads_before_posting_through_a_revendored_layer — a layer-epoch test that never renders a thread body, so it never loads this bundle at all.
Why it is the unroute instrument and not a poll that answered wrong
The assertion prints its counters unchanged across the whole 30s wait: the wait began on sends=1 acked=1 pending=0 asked=2 heard=2 and gave up on sends=1 acked=1 pending=0 asked=2 heard=2. Nothing was outstanding and nothing new went out — the page issued no poll for thirty seconds, rather than issuing one that came back wrong.
That is what a stranded first poll looks like from outside. The runtime starts its timer behind the first poll settling — pollAndPresent().finally(() => setInterval(pollAndPresent, POLL_MS)) (leaf.js#L12156) — so a fetch that never settles leaves setInterval unstarted for the life of the tab. And the lift immediately before the wait is page.unroute("**/api/state*") (test_render.py#L3308), which is exactly the instrument #26 names: the handler is taken away while a request is in its hands, and that request is then neither continued nor refused.
#26 already carries this test converted — cut = CutOff().hold(page) with cut.restore() in place of the unroute — so it needs nothing here beyond that PR landing.
Rerunning the failed job.
Weekly vendored-bundle sweep.
scripts/vendor-marked.shheldMARKED_VERSION=18.0.7while upstream is at 18.0.10 — the pin is a shell variable rather than a manifest entry, so dependabot cannot see it and the drift is silent until this step reads it. Bumped the variable and reran the script; the rebuilt bundle is the change, not the version string.marked ships one browser-native ESM file, so the script is a copy out of the published package and the bundle tracks the version directly. 18.0.8 through 18.0.10 are bug fixes only — emphasis and strong runs staying literal when unmatched, blockquote continuations no longer nesting spuriously, task-list checkboxes placed after list-looseness is finalized, and EOF backtick fences parsed after paragraphs. No API change, so
leaf.js'snew Marked({breaks: true, renderer: {html: ...}})construction is untouched.Verification
The new bundle exports the same surface (
Marked,Lexer,Parser,Renderer,parse, and the rest), and the runtime's exact construction still behaves:breaks: truerenders a single newline as<br>, and thehtmlrenderer override escapes raw HTML rather than passing it through — the property that keeps a message body from injecting markup, since a widget reaches a message only through the CLI-validatedmarkupfield.Full suite green on this branch —
uv run pytest tests --run-nightlygave1011 passed, 6 skipped in 613.65s.test_a_reply_renders_the_markdown_it_was_written_inandtest_a_state_waiting_for_markdown_cannot_overwrite_a_newer_oneare the readings that load this bundle in a real browser.