Migrate an essencium-frontend based project to a newer version. Detects current version, analyzes customizations, and applies upstream changes interactively. Use when upgrading @frachtwerk/essencium-lib or @frachtwerk/essencium-types.
You are performing an interactive, version-by-version migration of a downstream project that is based on essencium-frontend. This is a collaborative process -- be patient, explain what you are doing, and always wait for developer confirmation before making destructive or ambiguous changes.
Before you begin, be aware of two reference documents bundled with this skill:
./references/categories.md -- Detailed handling instructions for each of the 7 change categories. You MUST read this file during the APPLY phase (step 2c)../references/manifest-format.md -- The YAML schema for migration manifests. Read this file if you need to understand the structure of a manifest entry.The upstream essencium-frontend repository is at: https://github.com/Frachtwerk/essencium-frontend Git tags follow the pattern: (e.g., ).
essencium-app-v<version>essencium-app-v9.4.5Migration manifests are fetched directly from the essencium-frontend GitHub repository at runtime. They are not bundled with this plugin — this means new manifests are available immediately when essencium-frontend publishes a release, without requiring a plugin update.
https://api.github.com/repos/Frachtwerk/essencium-frontend/contents/packages/app/manifestshttps://raw.githubusercontent.com/Frachtwerk/essencium-frontend/main/packages/app/manifests/<version>.yamlThis skill fetches manifests and upstream files from GitHub. Use the correct method for each type of request:
raw.githubusercontent.com URLs via WebFetch. Do NOT use gh api repos/.../contents/... for this — that endpoint returns base64-encoded JSON, not raw content, and requires extra decoding.
https://raw.githubusercontent.com/Frachtwerk/essencium-frontend/main/packages/app/manifests/<version>.yamlhttps://raw.githubusercontent.com/Frachtwerk/essencium-frontend/essencium-app-v<version>/packages/app/<path>GET https://api.github.com/repos/Frachtwerk/essencium-frontend/contents/packages/app/manifests
Accept: application/vnd.github.v3+json
Unauthenticated requests are limited to 60/hour. For multi-version migrations, if the user has a GITHUB_TOKEN environment variable set, use it in WebFetch headers (Authorization: token <value>) to increase the rate limit to 5000/hour. If rate limiting is encountered, suggest the developer set a GITHUB_TOKEN.
Before starting the migration, establish baselines and verify the environment is ready.
Clean git state. Run git status. If there are uncommitted changes, ask the developer to commit or stash them before proceeding. The migration must start from a clean working tree so that git history accurately reflects migration work.
Baseline type check. Run the project's type-check command (typically npx tsc --noEmit or pnpm typecheck). Record whether it passes or fails, and how many errors exist. This baseline is critical: during verification, only errors that are NEW compared to this baseline are attributed to the migration. Pre-existing errors are ignored.
Baseline test run. Run the project's test command. Record pass/fail counts. Same rationale: pre-existing failures are not migration failures.
Manifest pre-checks. After loading each manifest (step 2a), if it contains a pre_checks array, execute each check before applying any changes for that version. If any check with severity: blocker fails, stop and help the developer resolve it before proceeding.
Determine the current state of the downstream project and calculate the migration path.
Read the downstream project's package.json to find the currently installed versions of @frachtwerk/essencium-lib and @frachtwerk/essencium-types. These tell you the current essencium version the project is based on.
Determine the target version. If the developer passed a target version as $ARGUMENTS, use that. Otherwise, default to the latest (highest) version available from the manifest listing.
List all available manifest files by fetching the GitHub API:
https://api.github.com/repos/Frachtwerk/essencium-frontend/contents/packages/app/manifests
Parse the version number from each filename in the response (e.g., 9.4.5.yaml means version 9.4.5). Sort them in ascending semver order.
Calculate the migration path. Starting from the current version, collect every manifest version that is greater than the current version and less than or equal to the target version. These are the steps to execute, in ascending order. Each manifest's from field tells you which version it migrates from -- use this to verify the chain is valid.
Not all versions have manifests. Manifests are only created for releases that contain app-level changes relevant to downstream projects. Patch releases that only touch library internals or docs will not have a manifest. This is by design — the migration path only includes versions with actual migration steps.
from field in that manifest indicates the intended baseline, not a hard requirement — patch versions between manifests typically don't introduce breaking changes that would invalidate the manifest.Present the migration path to the developer and ask for confirmation before proceeding:
For each version in the migration path, execute these sub-steps in order. Do NOT skip ahead to the next version until the current one passes verification.
https://raw.githubusercontent.com/Frachtwerk/essencium-frontend/main/packages/app/manifests/<version>.yaml
type field. The 7 types are:
dependency_migrationinfrastructurefile_removalnew_filefile_trackingtranslationenv_variable./references/categories.md file to understand the handling instructions for each category.For each change entry in the manifest, assess its impact on the downstream project:
For dependency_migration entries:
package.json.scope: project_wide: use Grep to scan the entire downstream project for imports and usage of the affected package. Note how many files use it and whether the usage matches patterns that would need updating.scope: package: note that this is a simple version bump.For file_tracking entries:
from version tag using WebFetch:
https://raw.githubusercontent.com/Frachtwerk/essencium-frontend/essencium-app-v<from-version>/packages/app/<path>
For new_file entries:
For file_removal entries:
For translation entries:
For env_variable entries:
.env* files in the downstream project root for existing variables.For infrastructure entries:
Present a summary of the plan to the developer:
Version 9.4.5 migration plan:
- [dependency] axios 1.8.2 -> 1.12.0: package bump only
- [dependency] vite 6.2.7 -> 6.3.6: package bump only
- [file_tracking] src/app/.../RightsView.tsx: customized (2 extra functions) -- INTERACTIVE
- [translation] 1 key to add to de/en locale files -- AUTO
Ask the developer to confirm the plan before applying changes.
Before applying, read ./references/categories.md for the detailed handling procedures. Follow those instructions precisely.
Process changes in this exact order (dependencies first, then structural, then content):
Before processing other changes, update @frachtwerk/essencium-lib and @frachtwerk/essencium-types in the downstream project's package.json to match this version step's target version. Run the package manager install command to fetch the updated packages. This ensures the downstream project has the correct lib/types for this version before applying other changes.
dependency_migrationscope: package: Auto-apply. Update the version in the downstream package.json.scope: project_wide: Interactive.
package.json.setupTests.*, vitest.setup.*, jest.setup.*, or equivalent) for global mocks or configuration of the migrated library.**/*.test.*, **/*.spec.*) for local mocks of the migrated package (e.g., vi.mock('<old-package>'), jest.mock('<old-package>')).test_infrastructure field, use its files and patterns as the starting point for this scan.scope: project_wide migrations.infrastructurepr field is provided.file_removalnew_filehttps://raw.githubusercontent.com/Frachtwerk/essencium-frontend/essencium-app-v<target-version>/packages/app/<path>
Create it in the downstream project. Auto-apply.file_trackingfrom version): auto-apply the upstream diff.added and a removed path):
new_file entry.translationpublic/locales/<locale>/common.json).keys_added: Add each key if it does not already exist. Fetch values from the essencium-frontend repo at the target version tag. Preserve all existing custom keys. Auto-apply.keys_changed: Check if the downstream value matches the old upstream value. If so, update automatically. If the downstream has a custom value, flag for review.keys_removed: Always flag for developer review. The downstream project may still use these keys.env_variable.env* files in the downstream project root..env* file: skip..env file (or .env.local if that matches the project's pattern). Use the default value if specified in the manifest, otherwise add with a # TODO: set value comment.After applying all changes for this version step:
Run the build command. Detect from the downstream package.json scripts -- typically npm run build or pnpm build. If using a monorepo, identify the correct workspace command.
Run the linter if available (npm run lint or pnpm lint).
Run tests if available (npm test or pnpm test).
If any command fails:
If all pass:
git status to review all changesgit add -A as it may stage sensitive files (.env.local, credentials) or unrelated work-in-progressMove to the next version in the migration path and go back to step 2a. Continue until all versions have been migrated.
After all version steps have been successfully migrated:
Present a summary of everything that was done:
Remind the developer to take the following final actions:
# TODO comments that were added during the migration.When a manifest entry includes a pr field (a GitHub PR URL), use WebFetch to fetch the PR diff page to understand what changed upstream. If WebFetch is unavailable or fails, fall back to the manifest entry's description and notes fields to understand the change.
If a file_tracking entry references a file that does not exist in the downstream project, do NOT silently skip it. Flag it and ask the developer whether the upstream change is relevant to their project.
If the change described in a manifest entry is already present in the downstream file (the code already matches the target state), skip it and note that it was already applied. Do not re-apply or flag as a conflict.
When a dependency migration (step 2c.1) affects files that also appear in file_tracking entries (step 2c.5), the dependency migration scan may have already transformed those files. During file_tracking processing, check whether the relevant change was already applied before attempting to apply it again.
Some file_tracking entries contain both an added and a removed file path. This represents a rename. Handle by moving/renaming the old file to the new path, then applying any content changes from the upstream diff.
When a dependency migration or file tracking change requires the same mechanical transformation across many files (more than 20), do NOT edit files one by one. Instead:
If the manifest entry includes a batch_hint field, use its pattern, replacement, and file_glob to generate the codemod script.
git stash or git reset --hard. These risk losing all migration changes accumulated so far. To determine whether a failure is pre-existing, consult the baseline recorded in Step 0 rather than stashing or resetting.sleep commands. Run commands synchronously. If a command is asynchronous by nature, use a proper wait mechanism, not a timed sleep.git checkout -- <file> or git restore on migrated files. If a change needs to be undone, edit the file back explicitly so the developer can see exactly what was reversed.When generating or modifying code during the migration:
.mjs, .cjs, .ts), the "type" field in the nearest package.json, and whether the project uses a bundler. Do not use require() in ESM files or import in CommonJS files.import.meta.dirname, available since Node 21.2.0), verify the Node.js version the downstream project targets. Use older equivalents (e.g., path.dirname(fileURLToPath(import.meta.url))) when compatibility requires it.This migration skill is designed to be interactive and patient. Always explain what you are about to do. Always wait for developer confirmation before making ambiguous or destructive changes. Present clear summaries and diffs. If the developer wants to skip a change or handle it differently, respect their decision and note it for the summary.
Current: @frachtwerk/[email protected]
Target: 9.5.0
Migration path: 9.4.4 -> 9.4.5 -> 9.5.0
(Only versions with migration manifests are shown. Your version 9.4.2 has no manifest — starting from the next available: 9.4.4)
Proceed? (y/n)
If the developer declines, stop. If they confirm, proceed to step 2.