Concerns: pushword/api, pushword/flat
.md API intakeThe flat .md format now has a single owner, PageFileSerializer (flat): the exporter, the importer and the new API intake all go through it. New endpoints:
PUT/POST /api/content/page/{host}/{slug} accept the raw file text (text/markdown) and answer with the canonical file text a fresh export would write — editor clients no longer parse or dump YAML at all.GET /api/editor/sync.js serves the matching Node sync client (Claude Code PostToolUse hook); editor repos should curl it on each snapshot pull instead of vendoring a copy.Behavior changes to review:
holdPublicationAt and extendedPage from frontmatter (previously silently dropped) and rejects unparseable publishedAt/holdPublicationAt values with a 422 instead of silently storing null — a typo'd date no longer unpublishes a page.Title\n---\nText setext heading in a body is no longer rewritten into a horizontal rule with padding on each sync.PageFrontmatterMapper::dumpFrontmatterYaml() was removed (dead code — a second, disagreeing YAML writer). PageExporter's constructor now takes the serializer instead of the converter registry and revision calculator.pushword/api now requires pushword/flat in composer (it already was a hard code dependency via the flat converters).