Repository navigation
feat(migrate): widen conversion and add manifest, replacement, and structural checks - #69
Merged
Merged
Conversation
Migrate now accepts what the analysis rates Astro-convertible: arrow functions, a declaration named by export default, expression statements, and any object pattern of a component's props. Pages that read params stay preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every migration now writes .frameshift/manifest.json with the plan hash, the binding, and the origin and digest of every other output file (D-105). It is the base for replace-managed output and verification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only a real directory that holds the staging marker is removed, so the option cannot delete a directory that a person created. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An existing output is replaced only if its manifest records it exactly, so no manual edit can be lost. The old tree moves next to the output and is never deleted, and it moves back if the commit fails (D-106). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--strict writes nothing and exits with 1 when a unit is rated unknown or unsupported, and --show-files lists every operation of a real run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A generated script or Astro frontmatter must parse again, its runtime imports must name planned files or packages other than Next.js, and no React directive may remain. A file that fails is preserved with its reason, so a rule defect cannot reach the output (D-107). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A comment between the parentheses and the markup of a returned root lay inside the root's span, so the conversion treated it as checked, but the markup conversion only reads what the parentheses enclose, and the comment was lost. The fuzzer's astro target found it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.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.
Summary
First M7 steps: migrate now converts what the analysis rates Astro-convertible, every migration writes a provenance record, and an existing or interrupted output can be handled safely.
Conversion.
migrate::converthands the component function toconvert_componentinstead of reading the body itself. That adds arrow functions, a function orconstnamed byexport default <name>, expression statements before the finalreturn, and any object pattern of a component's props, such as default values. Pages that readparamsand anonymous component functions stay preserved with their reason.Manifest (D-105).
.frameshift/manifest.jsonholds the plan hash, the plan's binding, and the origin and digest of every other output file. It is an operation of the plan, but it stays outside the plan document and hash, because it names that hash.verify, which will also read it, remains planned.Replacing output (D-106).
--on-existing replace-managedreplaces an existing output only if its file set and digests match the manifest exactly. The old tree moves to.<name>.frameshift-previousand is never deleted, and it moves back if the commit fails.Interrupted runs.
--clean-stagingremoves a staging directory only when it is a real directory with the Frameshift marker.--strictand--show-files.--strictwrites nothing and exits with 1 when a unit is ratedunknownorunsupported;--show-fileslists every operation of a real run.Structural postcondition (D-107). Every generated script and Astro frontmatter must parse again, runtime imports must name planned files or packages other than Next.js, and no React directive may remain. A failing file is preserved with its reason, so a rule defect cannot reach the output. The Astro template is not re-parsed yet.
Validation
The existing goldens did not change with the conversion refactor, so previously converted files keep their exact output.
static-sitegained an arrow page behindexport default <name>, a page with an expression statement, and an arrow component with a default prop value.Its output was built with the pinned
astro7-preact10profile outside the repository: 8 pages, noscripttag in any page. The arrow component rendered its default and explicit prop values, and the expression statement ran before the markup.A real-world check over the 211 App Router package directories of the approved corpus (read-only, no project code run): every
planexited with 0, two plans of a package were byte-identical, everymigrate --plansucceeded, all 12,954 written files matched their manifest digests, and the sampled sources stayed unchanged, also with a second--on-existing replace-managedrun per package. The structural postcondition preserved 5 files that would have kept a React directive and refused nothing else. IMPLEMENTATION.md section 52 records what stays preserved and why.Test plan
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --offline --locked -- -D warningscargo test --workspace --offline --lockedpwsh -NoProfile -File .github/scripts/check.ps1🤖 Generated with Claude Code