readCanvases sorts file canvases newest-first by updatedAt. The canvases route then merged them via Map.set in iteration order, which overwrites earlier (newer) entries with later (older) ones. If an agent wrote `result-v1.json` and `result-v2.json` with the same canvas id, the user would see the OLDER payload — the exact opposite of the intended last-write-wins behavior. Fix: extract the merge into a pure helper (merge.ts) with explicit first-write-wins semantics. Synthesized seeds the map first (preserves the pass-9 reservation that core- prefix wins on collision); file canvases skip ids already present, so the newest wins. Adds 5 regression tests covering: empty input, synth + file mix, duplicate-id newest-wins (the regression), synth-vs-file collision, and final sort order. Also adds a "Why no HTML canvas type?" section to the feature writeup HTML — the most-asked design question, answered honestly so reviewers don't have to ask. Covers the trust-hierarchy-inversion argument (agents are lowest-trust + LLMs are prompt-injectable + same-origin HTML = supervisor JS execution), the leaky-sanitizer argument, and the legitimate sandboxed-iframe path for v0.5+. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| ao | ||
| cli | ||
| core | ||
| integration-tests | ||
| plugins | ||
| web | ||