Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8928ce9
docs: add migration automation design spec
f4-lex Apr 8, 2026
bff7911
docs: clarify how SCAN step identifies essencium-origin files
f4-lex Apr 8, 2026
1f2f45f
docs: add migration automation implementation plan
f4-lex Apr 8, 2026
51f291a
chore: add migration manifest for v9.4.5 (accessibility and CVE fixes)
f4-lex Apr 8, 2026
7b1eb31
chore: add migration manifest for v9.5.0 (React Compiler + Next.js 16)
f4-lex Apr 8, 2026
b55d623
feat: add /author-migration skill for release manifest generation
f4-lex Apr 8, 2026
10e25ce
chore: remove spec and plan docs from repository
f4-lex Apr 8, 2026
6ed441b
refactor: move author-migration skill to .claude/skills/
f4-lex Apr 8, 2026
1e06e26
docs: add CLAUDE.md with project purpose and structure
f4-lex Apr 8, 2026
6c01275
docs: remove version numbers from CLAUDE.md tech stack
f4-lex Apr 8, 2026
6cd962f
chore: add migration manifests for v6.0.0, v6.1.0, v6.1.1
f4-lex Apr 8, 2026
d596459
chore: add migration manifests for v7.0.0 through v7.3.0
f4-lex Apr 8, 2026
c552082
chore: add migration manifests for v7.4.0 through v7.10.0
f4-lex Apr 8, 2026
846b568
chore: add migration manifests for v8.1.0 through v9.4.4
f4-lex Apr 8, 2026
53b61ef
fix: correct manifest schema violations in v6.0.0 through v7.3.0
f4-lex Apr 8, 2026
b4b69bd
fix: correct manifest schema violations in v7.4.0 through v9.4.0
f4-lex Apr 8, 2026
1938fc0
fix: remaining schema violations in v7.4.0 and v7.8.0 manifests
f4-lex Apr 8, 2026
72b0df5
chore: add migration manifest for v8.0.0
f4-lex Apr 8, 2026
165b89c
fix: address code review feedback on migration tooling
f4-lex Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 additions & 0 deletions .claude/skills/author-migration/SKILL.md
Comment thread
PhilKsr marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
---
name: author-migration
description: "Generate a migration manifest (YAML) for a new essencium-frontend release. Use when preparing a release to document app-level changes for downstream projects."
argument-hint: "[version]"
---

# Author Migration Manifest

Generate a migration manifest that documents all app-level changes between two releases of essencium-frontend. The manifest helps downstream projects understand what changed and how to migrate.

## Workflow

### Step 1: Determine versions

1. If a version argument was provided, use it as the **target version**. Otherwise, read the `version` field from `packages/app/package.json`.
2. Find the **previous release tag** by running:
```bash
git tag --list 'essencium-app-v*' --sort=-v:refname
```
- If the target version already has a tag, pick it as current and the next entry as previous.
- If the target version does not have a tag yet, use `HEAD` as the current ref and the first entry in the tag list as the previous tag.
3. Confirm both versions with the user before proceeding. Display:
- Previous version / tag
- Target version / ref (tag or HEAD)

### Step 2: Diff the app package

Run these commands to collect the raw change data:

```bash
# Full diff of the app package between the two refs
git diff <previous-tag>..<current-ref> -- packages/app/

# Commit log with PR references
git log --oneline --grep='#' <previous-tag>..<current-ref> -- packages/app/

# Also get the full log for context
git log --oneline <previous-tag>..<current-ref> -- packages/app/

# List newly added files
git diff --diff-filter=A --name-only <previous-tag>..<current-ref> -- packages/app/

# List deleted files
git diff --diff-filter=D --name-only <previous-tag>..<current-ref> -- packages/app/

# List modified files
git diff --diff-filter=M --name-only <previous-tag>..<current-ref> -- packages/app/
```

Extract PR numbers from commit messages (look for patterns like `#123`, `pull/123`, or full GitHub URLs) and construct links in the format:
`https://github.com/Frachtwerk/essencium-frontend/pull/NNN`

### Step 3: Classify changes

Categorize every change into one of 7 types. Process them in this order:

#### 3a. `dependency_migration` — Dependency version changes

Compare `packages/app/package.json` between the two refs to find dependency changes:

```bash
git diff <previous-tag>..<current-ref> -- packages/app/package.json
```

For each changed dependency:
- Determine old and new version numbers
- **Major version bumps** (e.g., 2.x -> 3.x): set `scope: project_wide` — downstream code using that library may need changes
- **Minor/patch bumps** (e.g., 2.1 -> 2.3): set `scope: package` — just bumping the version is sufficient
- Exception: if a minor bump introduces known breaking behavior, use `scope: project_wide` and explain in `notes`
- Set `reference` to the library's changelog or releases page
- Write a concise `notes` describing the impact

#### 3b. `infrastructure` — Config/build tool changes

Check for modifications to these config files:
- `next.config.js` / `next.config.mjs`
- `postcss.config.cjs` / `postcss.config.mjs`
- `tsconfig.json` / `tsconfig.base.json`
- `eslint.config.mjs` / `.eslintrc.json`
- `tailwind.config.*`
- `vitest.config.*`
- `playwright.config.*`
- `Dockerfile`, `docker-compose.*`

Each infrastructure entry should describe what changed and why, list affected files with their action (modified/added), and include a PR link if available.

#### 3c. `translation` — Locale key changes

Check `packages/app/public/locales/` for changes:

```bash
git diff <previous-tag>..<current-ref> -- packages/app/public/locales/
```

For each locale file changed:
- Diff the JSON keys to identify `keys_added`, `keys_removed`, and `keys_changed`
- A key is "changed" if its value was modified but the key still exists
- Group all locale changes into a single entry per logical change (e.g., if `de` and `en` both got the same new key, that is one entry)
- List affected locales in the `locales` array

#### 3d. `env_variable` — Environment variable changes

Check `.env*` files for changes:

```bash
git diff <previous-tag>..<current-ref> -- packages/app/.env*
```

Document each added, removed, or changed variable with its name, whether it is required, and optionally a default value (from `.env.example` or the `.env` file in the diff). The `default` field is recommended wherever a sensible default exists; omit it when the value is project-specific.

#### 3e. `new_file` — Newly added files

From the `--diff-filter=A` output, create an entry for each new file. Describe the file's purpose by reading its content. Include PR links where possible.

#### 3f. `file_removal` — Deleted files

From the `--diff-filter=D` output, create an entry for each deleted file. Explain why it was removed and what replaces it (check the commit message and surrounding changes for context).

#### 3g. `file_tracking` — All other modified files

All remaining modified files that were not already classified above go here. Group related files into a single entry when they are part of the same PR or feature. Describe what changed and why.

### Step 4: Generate the manifest YAML

Save the manifest to `packages/app/manifests/<version>.yaml`.

Before writing, review existing manifests in `packages/app/manifests/` as format examples (especially `9.4.5.yaml` for a small release and `9.5.0.yaml` for a large release).

The manifest must follow this exact schema:

```yaml
# Top-level fields (all required)
version: "X.Y.Z" # The version being released
from: "X.Y.Z" # The previous version
date: "YYYY-MM-DD" # Today's date

changes: # Array of change entries

# ── 1. dependency_migration — library version bumps ──────────────────
- type: dependency_migration
package: "package-name"
from: "old-version"
to: "new-version"
scope: project_wide | package # project_wide if API changes, package if just bump
reference: "url-to-changelog"
notes: "description of impact"

# ── 2. infrastructure — config/build tool changes ────────────────────
- type: infrastructure
description: "what changed"
files:
- path: "relative/to/app/root"
action: modified | added
pr: "https://github.com/Frachtwerk/essencium-frontend/pull/NNN" # optional
notes: "additional context" # optional

# ── 3. file_tracking — modified existing files ───────────────────────
- type: file_tracking
description: "what changed and why"
files:
- path: "relative/to/app/root"
action: modified
pr: "https://github.com/Frachtwerk/essencium-frontend/pull/NNN" # optional

# ── 4. new_file — newly added files ─────────────────────────────────
- type: new_file
path: "relative/to/app/root"
description: "purpose of the file"
pr: "https://github.com/Frachtwerk/essencium-frontend/pull/NNN" # optional

# ── 5. file_removal — deleted files ──────────────────────────────────
- type: file_removal
path: "relative/to/app/root"
description: "why it was removed and what replaces it"
pr: "https://github.com/Frachtwerk/essencium-frontend/pull/NNN" # optional

# ── 6. translation — locale key changes ──────────────────────────────
- type: translation
description: "what translations changed"
locales: ["de", "en"]
keys_added: ["dotted.key.path"]
keys_removed: ["dotted.key.path"]
keys_changed: ["dotted.key.path"]

# ── 7. env_variable — new/changed environment variables ──────────────
- type: env_variable
description: "what variables changed"
variables:
- name: "VARIABLE_NAME"
required: true | false
default: "optional-default-value" # optional — if present, the migration plugin uses this as the initial value
```

#### Key rules for the manifest

- **File paths are ALWAYS relative to the app package root** — use `src/...` not `packages/app/src/...`. Strip the `packages/app/` prefix from all paths.
- **PR links** should be included wherever a PR exists. Omit only for changes that span multiple PRs or were direct pushes without a PR.
- **`scope: project_wide`** on dependency_migration means downstream code using that library may need changes. **`scope: package`** means just bumping the version is sufficient.
- **Group related changes** — if multiple files were changed in the same PR/feature, put them in a single `file_tracking` entry with multiple files.
- **Order changes** by type: infrastructure first, then dependency_migration (major/project_wide before minor/package), then new_file, file_removal, file_tracking, translation, env_variable.
- **Use comments** as section separators in the YAML (see existing manifests for style).

### Step 5: Validate the YAML

After writing the file, verify it is valid YAML:

```bash
python3 -c "import yaml; yaml.safe_load(open('packages/app/manifests/<version>.yaml')); print('YAML is valid')"
```

If validation fails, fix the syntax errors and re-validate.

### Step 6: Present for review

Display the complete manifest to the user. Ask them to:
1. Review each entry for accuracy
2. Confirm dependency scopes are correct
3. Check that no changes were missed
4. Verify PR links are correct

Only commit the manifest after the user confirms it is ready.
43 changes: 43 additions & 0 deletions CLAUDE.md
Comment thread
PhilKsr marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Essencium Frontend

Monorepo for the Essencium frontend framework. Provides a component library, shared types, and a Next.js boilerplate that downstream projects scaffold via [create-essencium-app](https://github.com/Frachtwerk/create-essencium-app) and then customize.

## Packages

| Package | Published | Purpose |
|---------|-----------|---------|
| `packages/app` | No (private) | Next.js boilerplate — copied by downstream projects as their starting point |
| `packages/lib` | `@frachtwerk/essencium-lib` | Component library (React, Mantine, Tailwind) |
| `packages/types` | `@frachtwerk/essencium-types` | Shared TypeScript types and Zod schemas |
| `packages/eslint-config` | `@frachtwerk/eslint-config-essencium` | Shared ESLint config |
| `packages/prettier-config` | `@frachtwerk/prettier-config-essencium` | Shared Prettier config |
| `packages/docs` | No (private) | Documentation site (Nextra) |

## Downstream projects

Multiple projects are built on top of this repo. They install `essencium-lib` and `essencium-types` as npm dependencies, and their codebase started as a copy of `packages/app` which they then customized (new pages, modified components, different config, custom API hooks).

When this repo releases a new version, downstream projects need to migrate. Migration manifests in `packages/app/manifests/` describe what changed per release. The `/author-migration` skill (in `.claude/skills/`) helps generate these manifests. A separate [migration plugin](https://github.com/Frachtwerk/essencium-frontend-migration-plugin) helps downstream projects apply the changes.

## Release tags

Release tags follow the pattern `essencium-app-vX.Y.Z` (e.g., `essencium-app-v9.5.0`).

## Commands

- `pnpm build` — Build all packages
- `pnpm dev` — Run app + lib in dev mode with hot reload
- `pnpm lint` — ESLint across all packages
- `pnpm test` — Run all tests (unit + e2e)
- `pnpm test:unit` — Vitest unit tests
- `pnpm test:e2e` — Playwright e2e tests
- `pnpm format:check` / `pnpm format:write` — Prettier

## Tech stack

- **Runtime:** Node, pnpm
- **App:** Next.js, React, Mantine, Tailwind CSS, TanStack Query
- **Lib:** Rollup, React Compiler
- **Types:** Zod, Rollup
- **Testing:** Vitest, Playwright
- **Linting:** ESLint (flat config), Prettier
4 changes: 2 additions & 2 deletions packages/app/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
APP_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000

API_URL=https://backend.staging.essencium.dev
NEXT_PUBLIC_API_URL=https://backend.staging.essencium.dev
API_URL=http://localhost:8098
NEXT_PUBLIC_API_URL=http://localhost:8098

OAUTH_REDIRECT_URI=https://staging.essencium.dev

Expand Down
Loading
Loading