Version: sequoia-cli 0.5.7
Command: publish
Summary #
publish decides whether a post needs (re)publishing by hashing only the raw
markdown file (frontmatter + body). The cover image is referenced by path in
frontmatter, but the image bytes are never part of the hash. As a result, if
you regenerate/replace a cover image without editing the post's text or
frontmatter, publish reports the post as up to date and the cover blob is
never re-uploaded. The coverImage on the site.standard.document record stays
stale until some unrelated text edit happens to change the hash.
Where #
packages/cli/src/commands/publish.ts — change detection:
const contentHash = await getContentHash(post.rawContent);
// ...
} else if (postState.contentHash !== contentHash) {
// Changed post
postsToPublish.push({ post, action: ..., reason: "content changed" });
}
packages/cli/src/lib/markdown.ts — getContentHash hashes the file string only:
export async function getContentHash(content: string): Promise<string> {
const data = new TextEncoder().encode(content);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
// ...
}
The update path itself is correct — updateDocument re-uploads the cover and
putRecords it in place — it just never fires for a cover-only change.
Reproduction #
- Publish a post that has a cover image (
ogImage/ cover frontmatter). Cover uploads fine. - Regenerate the cover image at the same path (new bytes, same filename), leaving the post's markdown and frontmatter untouched.
- Run
publishagain.
Expected: the post is detected as changed; the new cover blob is uploaded
and the document record's coverImage is updated.
Actual: "All posts are up to date. Nothing to publish." The stale cover blob remains on the record. Only an unrelated edit to the post text/frontmatter will trigger the re-upload.
Workaround #
publish --force re-uploads every cover and rewrites every record. Works, but
it's all-or-nothing (no per-post force) and churns every record/blob.
Suggested fix #
Fold the cover image's bytes into the change-detection hash when a post has a
resolved cover path — e.g. hash rawContent concatenated with the image file
contents (or the image's size + mtime as a cheaper proxy). Then a cover-only
change naturally trips change detection, no --force needed.
(Resolving the cover path currently happens later in publish.ts, after the
hash is computed, so this would mean resolving the image path before hashing.)
Sounds like a great solution - straight forward. Care to submit a PR?