Repository navigation
Conversation
A final sync phase, opt-in per run, that deletes the target counterpart of every mapped entity whose source is gone: URL redirections, pages (children first), content, containers, templates, models, assets and galleries, in dependency order. Only entities reached through a mapping are considered. Safety rules: - Content and pages are confirmed deleted against the source API (404 or state 3); a full pull also omits unpublished items, which are kept. - An empty source list for a type is never read as "everything deleted". - A target edited since the last sync is a conflict unless --overwrite. - A target that something staying on the target still uses (child pages, linking content or pages, container items, model usage, embedded asset URLs, gallery assets) is kept and reported. - Mass-delete guard: more than 50% and more than 10 of one type deletes nothing and fails unless --allowMassDeletes. - Refused with --pages, --containers, --models, --models-with-deps; not primed from .env. Deleted and already-gone targets drop their mapping records. --preflight reports planned deletes with a new "delete" action; --jsonSummary gets a syncDeletes phase and option. URL redirections are deleted through the Management API's bulk DELETE endpoint, called directly until the CLI moves to an SDK release with urlRedirectionMethods.deleteUrlRedirections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--syncDeletes now deletes redirections with apiClient.urlRedirectionMethods.deleteUrlRedirections (management SDK 0.2.0-beta.3) instead of its own fetch call, and chunks by the SDK's MAX_URL_REDIRECTIONS_PER_REQUEST. The CLI's hand-rolled delete helper and its result type are removed. Bumps @agility/management-sdk to ^0.2.0-beta.3. That version is not on npm yet, so the lockfile is regenerated once it is published. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Closing: everything here is in #254 (release/1.3.0-beta.0), which takes these changes to main for the 1.3.0 beta. This branch has no commits that #254 doesn't. The description and review threads here still apply. 🤖 Generated with Claude Code |
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
Adds
--syncDeletes, an opt-in final phase forsync/push/reverse-sync. It deletes on the target what was deleted in the source since the last sync. All eight entity types are covered and deleted in dependency order: URL redirections, pages (children first), content, containers, templates, models, assets, galleries.Only entities reached through a mapping record are considered. Anything created directly on the target is never touched.
How each candidate is decided
A candidate is a mapping whose source entity is missing from the source pull.
--overwrite). The mapping is removed.--overwrite.Safety rules
--allowMassDeleteslifts this.--syncDeletesis refused with--pages,--containers,--modelsand--models-with-deps.--elementslimits which types are considered..envdefault: the flag is not read from.env, so a destructive mode is chosen per run.Reporting
--preflightlists the planned deletes underDelete …phases, using a newdeletepreflight action.--jsonSummarygets asyncDeletesphase and asyncDeletesoption.URL redirections
Redirections are deleted with
apiClient.urlRedirectionMethods.deleteUrlRedirections, in chunks of the SDK'sMAX_URL_REDIRECTIONS_PER_REQUEST(250). The method comes from agility/agility-cms-management-sdk-typescript#62, and this PR bumps@agility/management-sdkto^0.2.0-beta.3for it.Draft: still to verify against a clone pair
Run
--preflightfirst.Known limits
--elementsdependency auto-inclusion applies to the deletes too:--elements=Contentalso brings in models, containers and so on.Testing
src/lib/deleters/tests/delete-plan.test.ts: decision rules, mapping parsing, the mass-delete guard and reference scanning.src/lib/deleters/tests/sync-deletes.test.ts: a fixture with a mapped entity of every type. Covers conflict, blocked, unpublished,--overwrite, preflight, a failed delete, a target that disappears before its delete, an empty source list,--elements, and the mass-delete guard.src/tests/sync/sync-deletes.test.ts: hermetic end-to-end runs through the real orchestrator. Sync, delete in the source, re-sync with the flag. Also checks that nothing is deleted without the flag, a blocked model, preflight writing nothing, redirection deletes going throughurlRedirectionMethods, and the scoped-run refusal.delete: 0in their totals.0.2.0-beta.3(cleannpm ci).type-checkandtype-check:testsare clean.🤖 Generated with Claude Code