feat(core): carry elementContext through html-anchor host helpers - #1549
Merged
backnotprop merged 5 commits intoSep 17, 2026
Merged
Conversation
Persist and project elementContext through the core host helpers; move the validator into core and drop the ui mirror; add outline-less export option. Closes backnotprop#1521.
`packages/core/html-anchor.ts` gained its own `MAX_PAGE_URL_LENGTH` when `parseHtmlElementContext` moved there, leaving a second copy in `useHtmlAnnotation.ts` — exactly the hand-mirrored-constant shape the move was meant to end. Delete the ui copy, import the core one, and re-export it from `components/html-viewer` so the host import site and the live-protocol tests keep reading it from where they already do.
HANDOFF.md still told hosts the element-context gap was open — that `@plannotator/core/html-anchor` does not carry `elementContext` and that they must persist and project it themselves. It ships in the ui tarball, so that line was about to be wrong in a consumer's node_modules. - HANDOFF.md: the stale gap sentence now names 0.39.0 as the release it describes and points forward. A new "Element context through the host seam" section says where the validator lives (`parseHtmlElementContext` in `@plannotator/core/html-anchor`, re-exported unchanged from `components/html-viewer`), what a host passes (`elementContext` on the build source, `context` per additional target, `elementContext` on a `HostThread`), what it gets back (`PersistedHtmlAnchor.elementContext`, `HtmlAnnotationTarget.context`, both on the projection) with the fixed key order that keeps context-less rows byte-identical on the wire, and that the caps, the attribute allowlist, the shed order and the 16 KiB budget are all unchanged — contexts are simply shed before targets. Plus a publishing bullet: core moves, so publish core first. - README.md: the host-seam bullet now mentions the round trip. - html-anchor.ts: the module doc claimed the validators mirror what ui enforces. They no longer mirror it; they are it.
Owner
|
Thanks @FNDEVVE, this closes #1521 cleanly. The validator move is byte-faithful (no cap, allowlist, or fail-closed path changed), and it is what Workspaces needs to stop carrying a copy. I pushed three small commits onto your branch rather than round-tripping: a single definition of Publish order for this one is core 0.25.3 first, then ui 0.40.0 with the pin bumped, since ui now imports a symbol that published core 0.25.2 lacks. That lands in the 0.40.0 bundle PR going up shortly. Merging now. |
backnotprop
added a commit
that referenced
this pull request
Sep 17, 2026
…heme-aware diagrams; core 0.25.3 (#1557) * chore(ui): mermaid 12.0.0 (exact), ELK layout by default Bump @plannotator/ui's mermaid dependency from ^11.17.2 to an exact 12.0.0 and regenerate bun.lock. Mermaid 12 lays flowchart, state, class, ER and requirement diagrams out with ELK by default (elkjs is now bundled in mermaid itself), targets Safari 17.4+ / ES2024, and drops the legacy flowchart/class/state diagram ids. We take 12's defaults rather than pinning the 11 ones. No API or type changes were needed: MERMAID_CONFIG (securityLevel 'strict') and the theme mapping apply unchanged, every generated SVG id keeps its 11.x shape, and the katex import Mermaid makes for $$ labels is the same call (the math-slot bridge is untouched). The visual-explainer skill's render gate now expects Mermaid 12. * feat(editor): load the Mermaid runtime lazily on the first diagram Drop the eager registration import (@plannotator/ui/utils/mermaid-eager) from the plan editor entry. Since Mermaid 12 the runtime plus ELK is about 1.8 MB larger, so a plan with no diagram must not pay for it: the block now resolves the runtime through utils/mermaid's own import('mermaid') on the first MermaidBlock render. In the chunked share-portal build that moves mermaid.core (~640 KB) out of the entry chunk; the single-file builds still inline it through inlineDynamicImports, so nothing changes there except Mermaid 12's own size. MermaidBlock shows the source fence under a role=status "Rendering diagram" line until the first render lands, never the error panel, and applyMermaidTheme is keyed on the runtime object so the lazily loaded runtime is themed on its first render like an eagerly registered one. mermaid-eager stays exported for hosts that want startup registration. tests/entry-assets.test.ts now asserts the eager Mermaid marker is absent from both app bundles; DiagramBlock.lazyRetry.test.tsx pins the pending state. * docs(ui): HANDOFF 0.40.0 section for Mermaid 12 and the lazy runtime Add the "Mermaid 12 (0.40.0)" section hosts need to adopt the bump: ELK layout by default and the other 12 changes we take, the concrete SVG id patterns (unchanged 11 -> 12, per family), the g.edgePaths declaration-order change and the select-by-id rule, the Safari 17.4+ / ES2024 floor, the lazy-load contract (the plan editor no longer imports mermaid-eager; how a host keeps startup registration; the pending state; measured chunk and single-file sizes), the theming contract with and without tokens, the 0.40 contrast re-sweep (104 combinations, 0 failures), and the publish order core 0.25.3 -> ui 0.40.0. Retitle the theme and element-context sections to 0.40.0, fold the two unreleased publishing bullets into the current pair, and update the 0.32.0 lazy-renderer text, README and AGENTS for the new policy. * chore(core): bump @plannotator/core to 0.25.3 Carries the #1549 html-anchor element-context exports (parseHtmlElementContext, MAX_ELEMENT_CONTEXT_BYTES, MAX_PAGE_URL_LENGTH) that @plannotator/ui 0.40.0 imports. Publish this before ui 0.40.0. * chore(ui): bump @plannotator/ui to 0.40.0 on core 0.25.3 Mermaid 12.0.0 (exact), lazy runtime loading in the plan editor, the theme-aware diagram mapping from #1556, and the #1549 element-context host seam. Pins @plannotator/core 0.25.3 exactly; bun.lock records both workspace versions. Publish core 0.25.3 first, then this. * chore: pin lodash-es 4.18.1 over chevrotain's vulnerable exact pin Mermaid 12 pulls chevrotain 11.1.2 (via langium), which pins lodash-es exactly 4.17.23 (CVE-2026-4800 high, CVE-2026-2950 medium), so the workspace resolved a second, vulnerable copy beside the 4.18.1 that dagre-d3-es already resolves. A root "overrides" entry forces every lodash-es range to 4.18.1 (published 2026-04-01, past the 7-day gate); bun.lock now records a single lodash-es@4.18.1. chevrotain still parses every diagram grammar under it: all 15 eval diagrams render with zero errors in the built plan editor, typecheck, the ui utils and MermaidBlock tests, and the package smoke pass, and the built bundles are byte-for-byte the same size.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the five follow-up requirements from the Workspaces host review so hosts persisting through the core helpers no longer lose element context:
parseHtmlElementContextmoves into@plannotator/core/html-anchornext toparseHtmlElementAnchor;useHtmlAnnotationimports and re-exports it and the hand-mirrored validator is deleted.PersistedHtmlAnchorgainselementContext?(serialized afterhtmlAdditionalTargets, so rows without it are byte-identical) andHtmlAnnotationTargetgainscontext?.buildPersistedHtmlAnchorsheds per-target contexts, then the primary context, before dropping targets undermaxBytes; the 16 KiB cap is unchanged.projectHostThreadsprojects both context fields through to host panels and per-row copy.includeOutlineexport option (default true, output unchanged) prints the identity lines without the fenced outline for model turns.Testing:
bun test packages/core/html-anchor.test.ts packages/ui/utils/parser.test.ts(214 pass, incl. wire-fingerprint, shed-order, projection, and outline-less export tests), fullbun run typecheckclean.Closes #1521.