fix: pull writes canonical model files and detects changes reliably - #243
Merged
Conversation
Model canonicalization sorted keys only one level deep, so structurally identical models with reordered keys inside nested config objects (e.g. an Image field's constraint) compared as different, causing pull to rewrite unchanged files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4 tasks
Sync compared raw remote JSON against canonical local files, so any remote change re-synced every model whose key order differed. Sync now uses pull's comparison: the remote model's canonical form against the local file as parsed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pull now has a test that pulled files keep field order, a second pull changes nothing, and non-canonical files (types and slices) are rewritten in canonical form. The status reorder test also covers a slice and checks that push writes nothing. The scramble helper moves to test/it.ts and handles slice field maps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lize # Conflicts: # src/commands/sync.ts
Deep key sorting also sorted a Slices field's choices, which is the slice order shown in the editor, and the field maps inside legacy slices. Rebuild both from the unsorted input, like group fields. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fixtures already hold their keys in a non-canonical order, so writing them to disk gives the same coverage as the scramble helper without restating which maps are position-significant. Cover a slice zone and a legacy slice too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pulled file only proved that field order survives. Assert the sorted key order of the model, a field, a thumbnail, a slice, and a variation, and add a second tab and thumbnail so tab and array order are covered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Write the unsorted fixture locally before the pull so one run covers both the rewrite and the canonical output. Compare the pulled models to the fixture for content, then assert key order at each kind of object, including the slice zone and a legacy slice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Write the unsorted fixture locally instead of pulling first, so status and push run against a non-canonical file in two CLI runs. Move the Choices type next to the function that uses it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
angeloashmore
marked this pull request as ready for review
August 7, 2026 00:06
The watch loop hashed the raw remote JSON. A change in key order flipped the hash without a real model change. The loop then ran generateTypes() and logged "Changes detected in" with no suffix. Hash the canonicalized models instead. Run generateTypes() and log changes only on the initial sync or when there are operations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d72140d. Configure here.
lihbr
approved these changes
Aug 14, 2026
lihbr
left a comment
Member
There was a problem hiding this comment.
LGTM but I think there's an issue to check with select fields, see bellow :)
Replace a Text field in the slice with a Select field. The options are not in alphabetical order. The test makes sure that pull sorts the config keys but keeps the option order. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Resolves:
Description
Model comparison now sorts JSON keys at every depth before it compares. Field and tab order stays the same. This corrects three faults:
1.
pullrewrote files that had no changesprismic pull. The API returns nested keys (inside a field'sconfig, for example) in a different order.git diffshowed only key-order movement.2.
pulldid not rewrite files with a non-canonical key order3.
sync --watchreported changes that did not existpushandstatuscontinue to ignore key order. They push nothing and report nothing when only the key order is different.Checklist
Preview
How to QA 1
prismic pull. The command rewrites the files.prismic pullagain. The command prints "Already up to date." and leaves no dirty files.prismic sync --watch. The command does not report changes when the remote models do not change.🤖 Generated with Claude Code
Note
Medium Risk
Touches core model diffing for pull, push, status, and sync; incorrect canonicalization could hide real model changes or skip needed type generation, but behavior is heavily covered by new integration tests.
Overview
Model comparison and on-disk format now treat nested JSON key order as insignificant while preserving field/tab order and slice-zone choice order.
canonicalizeCustomType/canonicalizeSlicerecurse through configs (Groups, Slices zones, legacySlicechoices) andsortKeyswalks arrays and nested objects.pullcompares remote models to already-canonical local files (canonicalize(remote)vslocal), so a first pull normalizes Slice Machine–style key order and repeat pulls report “Already up to date.” without noisy rewrites.sync --watchhashes canonicalized remote payloads, uses the same equality for diffs, runsgenerateTypesonly on initial sync or when models actually change, and logs which resource types changed (e.g. slices only) instead of empty “Changes detected” spam.Tests cover canonical pull idempotency, status/push staying quiet on key reorder, and sync reporting slice-only updates.
Reviewed by Cursor Bugbot for commit 6f8185e. Bugbot is set up for automated code reviews on this repo. Configure here.
Footnotes
Please use these labels when submitting a review:
⚠️ #issue: Strongly suggest a change.
❓ #ask: Ask a question.
💡 #idea: Suggest an idea.
🎉 #nice: Share a compliment. ↩