githubnext/chopinPublic

Let's compose rich plans together

Drop empty paragraphs from canonical document projection

An empty Lexical paragraph exported as an empty MDAST paragraph, which
serializes as an extra blank line that parsing discards. Rooms persisted
that non-canonical source, and document-summary jobs then failed with
"Document source is not canonical." Projection now drops empty paragraphs
at every depth, matching the blocks that addressable() and digests()
already count.

Checkpoints written before this change still store the former blank
lines, so restore accepts a stored source whose canonical form matches
the projection.

Closes #211

Assistant-model: Claude Opus 5.5
Assistant-workflow: inline
Assistant-duration: 15m converged, estimated none given
Assistant-verification: bun test unit passed: 1659 pass, 2 skip, 0 fail; new convert and room regression tests failed before the fix
Assistant-verification: bun run test:postgres passed: 59 pass
Assistant-verification: bun run types passed: all workspaces and E2E
Assistant-verification: bun run ci passed: dprint, oxlint, tokens, type scale, Impeccable
Assistant-verification: bun run e2e passed: 236 Chromium tests
Assistant-verification: agent-browser E2E passed: typing text and two Enters stores canonical "…strings.\n" on this branch versus non-canonical "…strings.\n\n\n\n" on main; a document written by main opens, edits, and re-persists canonically on this branch
Co-authored-by: Alex Lavaee <lavaman131@github.com>
ALAlex Lavaee authored committed by Maggie Appleton
bae7818Patch
Parent6bd3e01
4 files changed+70-5
StackedSplit
apps/server/src/plan/room.test.ts+18 −1
apps/server/src/plan/room.ts+4 −1
packages/dialect/src/convert.test.ts+33 −2
packages/dialect/src/convert.ts+15 −1