HtmlViewer injected host-app state into rendered documents: ~26 bare
theme tokens (--muted, --background, ...) written into :root and
re-applied inline on the author's documentElement on every host theme
flip, a `light` class toggled on the author's root, an asymmetric
color-scheme:light injection, and unconditional ins/del diff styles.
Documents defining the same token names rendered with wrong colors in
both Plannotator and @plannotator/ui consumers.
Arbitrary documents now render exactly as in a standalone tab:
- Host tokens are pushed only under the viewer-owned --pn-* prefix;
annotation CSS and the bridge read only var(--pn-*, fallback). The
bridge refuses non---pn- writes and never touches the root class
list unless the document opts in.
- Host theme-following is opt-in per document via
<meta name="plannotator-theme" content="host">, which restores the
bare-token push, the light class, and a symmetric color-scheme sync.
The visual-explainer skill now emits the tag in generated artifacts.
- Diff CSS is injected only while the version-diff view is active and
scoped to ins/del.plannotator-diff, which htmlDiff now emits on its
generated wrappers; author <ins>/<del> markup is never restyled.
The srcdoc injection logic moves to a pure module (srcdoc.ts) with
tests pinning the neutrality contract, including a DOM test that runs
the actual bridge script and asserts a theme flip lands nothing on the
author's root except --pn-* properties.
Claude-Session: https://claude.ai/code/session_01MDqD8jdgTbdjiXcVVigzV2
* feat(annotate): version diff for annotated files
Annotate mode never tracked version history, so the existing Plan Diff
(highlighted diff vs a previous version) only worked in plan mode. Wire
per-file version history into the annotate server so the same diff UI —
badge, Version Browser, block-level comments — works when annotating a
standalone .md/.txt/.html file.
- key history by file path (stable across edits) rather than the plan
flow's heading+date slug
- save the markdown (or raw HTML source) to history on each open, expose
previousPlan + versionInfo + diffCurrent on /api/plan
- add /api/plan/version and /api/plan/versions to the annotate server
Markdown lights up end to end; HTML needs frontend follow-ups (feed the
HTML source as the diff content, surface the badge on the html surface,
default to source diff mode).
* feat(annotate): rendered HTML version diff with inline highlights
For --render-html files, render the version diff as the real page with
inline <ins>/<del> highlights instead of a markdown/source diff:
- add packages/shared/html-diff.ts: a tag-aware htmlDiff() that wraps
changed text in <ins>/<del> while keeping tags balanced (script/style
opaque). 9 unit tests.
- annotate server computes diffHtml = rewriteHtml(htmlDiff(prev, current))
and exposes it on /api/plan
- HtmlViewer: inject ins/del highlight CSS, add a 'Show/Hide changes'
toggle in its action bar
- App: store diffHtml, swap the iframe to the diff page when toggled, and
suppress the markdown block-diff path on the HTML surface
Commenting still works because the diff page renders through the same
HtmlViewer iframe bridge.
* docs(annotate): document the annotate version diff + endpoints
* feat(annotate): mirror version diff into the Pi server
Parity for the Pi (node:http) runtime: per-file version history,
previousPlan/versionInfo/diffCurrent + diffHtml on /api/plan, the
/api/plan/version[s] endpoints, and project wiring from the Pi CLI.
Vendors @plannotator/shared/html-diff into pi-extension/generated.
* review fixes: pi diff dependency, attr-aware tokenizer, history opt-out, hide dead version picker on HTML
- apps/pi-extension/package.json: declare the 'diff' dependency —
generated/html-diff.js imports it at module load, so a standalone Pi
install failed to resolve it and broke every annotate session (the
monorepo masked this via root hoisting)
- packages/shared/html-diff.ts: tag tokenizer now consumes quoted
attribute values whole, so a '>' inside title="a > b" no longer
splits the tag and corrupts the diff output; 3 regression tests
- annotate history is now gated by PLANNOTATOR_ANNOTATE_HISTORY /
config.annotateHistory (default on) and disclosed in AGENTS.md —
it writes copies of annotated files into the data dir, which users
should be able to see coming and turn off
- packages/editor/App.tsx: hide the sidebar Versions tab on the HTML
surface — the base-version picker has nothing to drive there (the
HTML diff is fixed to current-vs-previous); the viewer's Show
changes toggle is unaffected
* fix(ui): document content clears the badge cluster dynamically
The repo/diff badge cluster is absolutely positioned in the card's top
padding, sized by guesswork (py-5..py-12). One chip row fit; the diff
badge's second row overflowed into the H1, and mobile wrapping made the
badge sit on top of the heading. Measure the cluster (ResizeObserver)
and insert exactly the clearance it needs — zero when it fits, so
existing single-row layouts don't shift. Pre-existing plan-mode bug
surfaced by the annotate version diff.
---------
Co-authored-by: Edouard Gouilliard <edouard.gouilliard13@gmail.com>
Co-authored-by: Michael Ramos <mdramos8@gmail.com>