Skip to content

chore(promotion): promote next to 1.1.0 - #3029

Merged
mfal merged 150 commits into
mainfrom
release/1.1.0
Aug 31, 2026
Merged

chore(promotion): promote next to 1.1.0#3029
mfal merged 150 commits into
mainfrom
release/1.1.0

Conversation

@mfal

@mfal mfal commented Aug 31, 2026

Copy link
Copy Markdown
Member

Release 1.1.0

Source → Target nextmain
Version 1.0.161.1.0
Bump minor (18 feat commits, no breaking changes)

This PR graduates the line to the stable 1.1.0 (version + changelog already
bumped on the branch). Merging publishes all @mittwald/flow-* packages to npm
under latest, tags 1.1.0, and creates the GitHub release from the curated
notes below.

The branch is next (which carries main through 1.0.16) plus three commits:
the stable changelogs taken from main, the figure below, and the graduation.
It touches no source file of its own.

Upgrade across Flow versions with one command

Highlights

  • npx @mittwald/flow-codemods@latest upgrade bumps every Flow dependency,
    installs, and runs the codemods for the range it crossed.
  • The new @mittwald/flow-codemods package carries the migration catalogue that
    MIGRATION.md is generated from — 23 entries, each carrying a codemod where
    the change can be applied mechanically.
  • flow-codemods list <revision> shows what a target version would touch before
    you commit to it.
  • Rating takes a segment count (maxValue), single-segment filling
    (fill="single"), and individual RatingSegment children with their own
    icons and labels.
  • @mittwald/flow-react-components now ships USAGE.md and a JSON component
    index, so a coding agent can answer component questions without the docs site.

The upgrade CLI

Upgrading Flow used to mean reading MIGRATION.md, deciding which entries
applied to your jump, and running codemods one at a time. The new
@mittwald/flow-codemods package does that for you.

# Bump every Flow dependency, install, and run the codemods for the range.
# Defaults to "minor", which stays inside your current major.
npx @mittwald/flow-codemods@latest upgrade

# Or name a target: patch | minor | major | a dist-tag | an exact version.
npx @mittwald/flow-codemods@latest upgrade latest

# See what a target version would touch before committing to it.
npx @mittwald/flow-codemods@latest list latest

# Without a revision: the whole catalogue, offline.
npx @mittwald/flow-codemods@latest list

# Run a single migration by its catalogue id.
npx @mittwald/flow-codemods@latest imports-to-package-root src

upgrade detects your package manager, refuses to run on a dirty working tree
(--allow-dirty overrides), and reports every file it declined. --dry writes
nothing, --print shows the transformed output, and --json makes list
machine-readable.

The catalogue is the single source for both the CLI and MIGRATION.md: an entry
describes what changed and how to migrate, and carries a codemod when the change
can be decided mechanically. Entries without one still tell you what to do by
hand — for those, the prose is the migration.

Rating: segment count, single fill, individual segments

Rating gained maxValue (default 5) for the number of segments, and
fill="single" to fill only the selected segment instead of every segment up to
it.

import { Rating, RatingSegment } from "@mittwald/flow-react-components";

<Rating maxValue={10} defaultValue={7}>
  <Label>Cantina rating</Label>
</Rating>;

For a scale whose segments are not interchangeable, pass RatingSegment
children — they define how many segments there are (maxValue no longer
applies) and each one takes its own icons and accessible label.

<Rating fill="single" defaultValue={3}>
  <Label>How was your stay on Tatooine?</Label>
  <RatingSegment
    aria-label="Terrible"
    iconEmpty={<Icon><IconMoodSad /></Icon>}
    iconFilled={<Icon color="danger"><IconMoodSadFilled /></Icon>}
  />
  <RatingSegment
    aria-label="Great"
    iconEmpty={<Icon><IconMoodHappy /></Icon>}
    iconFilled={<Icon color="success"><IconMoodHappyFilled /></Icon>}
  />
</Rating>;

Both the component and RatingSegment work in mStudio extensions.

Rating: a ten-segment scale, single-segment filling, and individual RatingSegment children

Documentation a coding agent can read

@mittwald/flow-react-components now ships its own consumer guide, and the docs
site is published in machine-readable form.

  • USAGE.md, shipped inside the package: how to build an application with
    Flow — component selection, layout and spacing, what is safe to depend on, and
    the mistakes that come up most. Available offline, which is what makes it
    usable from an agent's tool loop.
  • @mittwald/flow-react-components/component-index — a JSON index of every
    public component with its lifecycle status and props.
  • The docs site at https://flow.mittwald.de serves /llms.txt, /llms.json,
    /llms-full.txt, and every page as Markdown at /raw/<path>.md.

Point your agent at USAGE.md and the component index; it stops guessing
component names and props.

Raw commits (148 total, 94 non-merge) — reference only, not published

feat (18)

  • feat(Rating): individual segments, segment count and single fill (feat(Rating): individual segments, segment count and single fill #2863)
  • feat(codemods): add detect/verify commands and the checks module shape
  • feat(codemods): add the list command
  • feat(codemods): add the migration catalogue and its generated module
  • feat(codemods): add the single-codemod command
  • feat(codemods): add the upgrade command
  • feat(codemods): adopt the transform suite and test harness from fix(codemods): make the composite codemod runnable from a URL #2942
  • feat(codemods): detect the package manager and guard a dirty tree
  • feat(codemods): find and rewrite Flow dependencies in a consumer manifest
  • feat(codemods): generate MIGRATION.md from the catalogue
  • feat(codemods): make list output readable in a terminal
  • feat(codemods): publish the package with a CLI entry point
  • feat(codemods): rename transforms to catalogue ids and retire the URL path
  • feat(codemods): resolve a revision to a published target version
  • feat(codemods): run a codemod by its catalogue id
  • feat(codemods): select catalogue entries for a version range
  • feat(codemods): wire the upgrade command into the CLI
  • feat: ship a consumer agent guide and a compact component index (feat: ship a consumer agent guide and a compact component index #2897)

fix (24)

  • fix(codemods): correct the since version of the package-root import migration
  • fix(codemods): cover a prerelease current and name every registry failure
  • fix(codemods): drive jscodeshift programmatically instead of scraping its output
  • fix(codemods): drop the lower bound for codemod catch-up, keep it for manual migrations
  • fix(codemods): drop the manual-entry lower bound, mark catch-up everywhere
  • fix(codemods): explain why a revision could not be resolved, not just that it couldn't
  • fix(codemods): make the catalogue generator deterministic and its detect runnable
  • fix(codemods): make the catalogue's detect, apply and verify fields true
  • fix(codemods): make the gate's exhaustiveness check and its prerelease test real
  • fix(codemods): make the interactive gate an input, not an environment read
  • fix(codemods): move list's summary below the entries, make colour deterministic
  • fix(codemods): pin the list command's tool asymmetry and lower its sentinel
  • fix(codemods): resolve the target from what every Flow dependency published
  • fix(codemods): rewrite value positions, catalogue the password-tools subpath
  • fix(codemods): satisfy the repo's lint rules in three modules
  • fix(codemods): set exitCode instead of calling process.exit
  • fix(codemods): shorten list header to three lines
  • fix(codemods): stop a guard test racing the remote-component generator
  • fix(codemods): stop a transform that declines every file reading as success
  • fix(codemods): stop imports-to-package-root corrupting current code
  • fix(codemods): stop the install and the dirty-tree guard failing silently
  • fix(codemods): stop upgrade damaging a project and reporting success
  • fix(codemods): tidy list/upgrade output — zero-width range, legend, and duplicate header
  • fix(codemods): wrap the catch-up legend like every other line

refactor (5)

  • refactor(codemods): colocate each migration's entry, codemod and test
  • refactor(codemods): cut detect and verify from the migration catalogue
  • refactor(codemods): drop detect/verify prose and list's title line
  • refactor(codemods): drop to-remote-package from the migration catalogue
  • refactor(codemods): make list take a revision instead of --from/--to

revert (1)

  • revert(codemods): take the detect and verify commands back out

test (2)

  • test(codemods): pin the manifest cases that could hide a defect
  • test(docs): keep the Vitest and node:test globs disjoint

docs (27)

  • docs(codemods): document the catalogue and the upgrade CLI
  • docs: adopt PR fix(codemods): make the composite codemod runnable from a URL #2942 into the plan and add the deprecation follow-up
  • docs: correct the ADR to the CLI that was actually built
  • docs: correct the docs-page layout and the cross-version CI split
  • docs: correct the prerelease target-resolution expectation
  • docs: do not hardcode the package version in the plan
  • docs: drive jscodeshift programmatically and respect the consumer's registry
  • docs: drop the execution plan
  • docs: fix the install and dirty-tree modules in the plan
  • docs: fix the since value and the tool filter in the plan
  • docs: format the plan document
  • docs: handle the string private flag in the package-list generator
  • docs: make the gate snippet exhaustive and its prerelease test discriminating
  • docs: pin the list command's tool asymmetry in the plan
  • docs: pin the manifest cases that could hide a defect
  • docs: plan detect and verify as executable modules
  • docs: plan the codemods upgrade CLI and migration catalogue
  • docs: point every migration pointer at the catalogue and the CLI
  • docs: reconcile task 14's AGENTS.md step with what task 4 already did
  • docs: record the ESM extension and tsc findings from task 1
  • docs: record the accepted red commit in task 3
  • docs: record the task 6 findings in the plan
  • docs: report declined files in the upgrade loop too
  • docs: restore the remoteScope invariant as a task 4 step
  • docs: stop the docs implying upgrade has a lower bound
  • docs: stop the plan from hardcoding the package version
  • docs: tell the installation page how to stay current

chore (17)

  • chore(codemods): wire the generators into nx
  • chore(release): bump version to 1.1.0-next.0
  • chore(release): bump version to 1.1.0-next.1
  • chore(release): bump version to 1.1.0-next.10
  • chore(release): bump version to 1.1.0-next.11
  • chore(release): bump version to 1.1.0-next.12
  • chore(release): bump version to 1.1.0-next.2
  • chore(release): bump version to 1.1.0-next.3
  • chore(release): bump version to 1.1.0-next.4
  • chore(release): bump version to 1.1.0-next.5
  • chore(release): bump version to 1.1.0-next.6
  • chore(release): bump version to 1.1.0-next.7
  • chore(release): bump version to 1.1.0-next.8
  • chore(release): bump version to 1.1.0-next.9
  • chore(sync): fix what the main → next merge left red
  • chore(sync): resolve forward-merge conflict (main into next) (chore(sync): resolve forward-merge conflict (main into next) #2969)
  • chore: ignore the superpowers scratch directory

mfal and others added 30 commits August 26, 2026 09:35
Co-authored-by: mathis <37186532+maaaathis@users.noreply.github.com>
Co-authored-by: maaaathis <maaaathis@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Lisa Stockmann <84317589+Lisa18289@users.noreply.github.com>
Co-authored-by: Lisa18289 <Lisa18289@users.noreply.github.com>
Three conflicts, plus two cross-side interactions the merge creates.

`loadProperties.ts` — `next` moved the properties table onto the generated
component index (#2897); `main` taught it to hide `@deprecatedValues` and to
tell that tag apart from a prop-level `@deprecated` (#2960, #2961). Kept
`next`'s data source and ported `main`'s value hiding onto the new prop shape
(key-based name, `type` as a string, optional `description`). Top-level
`undefined`/`null` are not filtered here any more — the index generator already
strips them, so the docs side only removes deprecated values.

`buildComponentIndex.ts` — `main`'s new `@deprecatedValues` tag contains the
substring `next`'s generator matched to set `deprecated: true`, so `Button`'s
`color` came out of the merge flagged deprecated as a whole. Uses `main`'s
`/@deprecated(?!\w)/` now; regression test added.

`RemoteRatingSegmentElement.ts` — `main` put react-aria's `render` on the
generator's global ignore list (#2966) after `next` had generated
`RatingSegment` (#2863). Regenerated, which drops the `render` property that
would have broken the whole mutation batch in remote.

ADR 0004 §3 — took `main`'s passage: it already carries both the
`publish-next.yml` → `publish.yml` rename (#2968) and the version-consistency
guard paragraph (#2958).

`pnpm-lock.yaml` — kept `next`'s. It is a strict superset of `main`'s (zero
entries only on `main`; `next` already had the Dependabot bumps), and
`pnpm install` reports it up to date against every merged manifest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts:
#	apps/docs/package.json
mittwald-machine and others added 10 commits August 31, 2026 08:54
Review found that dropping the gate's lower bound turned an era-specific
transform into a corrupter of correct code, and I reproduced all of it.

`imports-to-package-root` (since alpha.28) collapsed 94 subpath exports onto the
package root, and it did that with a catch-all `else`. With no lower bound it
reaches every 1.x project, where five of today's nine subpaths were collateral:
`all-layered.css` became a JS import with the stylesheet silently gone, and
`Rule` from `mittwald-password-tools-js` moved onto a root that does not export
it. A default import became a named specifier along the way.

It also cancelled another migration. Sorted by `since` it runs first, so it
flattened `…/password-tools` before `password-tools-subpath-renamed` — the entry
whose whole job is that path — could see it. Both then reported success while
the file no longer compiled.

Both have one cause, so one fix: an explicit leave-alone set. It holds every
subpath the package still exports, plus `password-tools`, which another entry
owns. Era code still migrates — verified both directions. Two independent tests
pin it, one comparing the set against the real `exports` map so a new subpath
cannot quietly become collateral again; both fail if a single entry is removed.

Idempotency could never have caught this, and a comment in manifest.ts leaned on
it as if it could. It proves a second pass over a transform's own output changes
nothing — not that an era-specific transform is harmless against later code.

Also from the review:

- The dirty-tree guard treated every git exit 128 as "not a repository", so
  `detected dubious ownership` — the minimal CI container the guard exists for —
  read as a clean tree. It now matches the message, with `LC_ALL=C` pinning it.
- `peerDependencies` were rewritten. A peer range states what a package
  supports, not what it installs; narrowing `^1.0.0` to `^1.0.14` is a breaking
  change to someone else's package made by a command they ran on their own. They
  are now reported and left, through one reporter `--dry` shares.
- `engines.node` was `>=24.0.0` on a CLI consumers reach through `npx`. The only
  thing needing 24 was an import attribute for reading the version; that is a
  `readFileSync` now, and the floor is `>=22.0.0`.
- `components-src` included the `MIGRATION.md` that `codemods:build` writes,
  with no edge between the projects, so its hash depended on task order.
  Excluded.
- Ctrl+C at the codemod prompt rejected out of `runUpgrade` after the bump and
  install, showing an inquirer trace instead of what had happened. It now
  reports that and runs nothing. `@inquirer/prompts` also loads lazily, so
  `list` no longer pays for it.
- `list --json` was a bare array that could not say which range it described —
  on the 1.x line `list` and `list minor` select the same entries. It now
  carries `range` and per-entry `catchUp`. This replaces a test that pinned the
  bare array; that test recorded the old shape, it did not defend it.
- `kind`'s docblock still described the selection it once drove. It is
  descriptive now, and says so.

Not fixed here, because it is not in the repo: `@mittwald/flow-codemods` does
not exist on npm, and npm binds one Trusted Publisher per package. The first
publish needs an npm-side bootstrap or `lerna publish from-package` aborts
mid-release with the packages ahead of it already out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… read

The `unit` job failed on the cancel case I added with the review fixes. It
passed here and failed on the runner for one reason: `createChoose` read
`process.env.CI` inside itself, underneath the parameters the caller passes. On
a runner `CI` is set, so the prompt never ran, so it never rejected, so the
cancel path the test asserts was unreachable.

That is the second time a hidden environment read under an explicit parameter
has produced a green local suite and a red CI one — picocolors self-disabling
beneath the `color` argument was the first. So `isCI` is an input now, stated by
`cli.ts` where reading the environment is the job, and TypeScript makes every
call site name it.

Two things fell out. The behaviour that read gave — a TTY on an unattended
runner must not prompt — was untested, because no test could reach it; it has a
case now. And the one existing test that wanted the prompt shown had to save,
delete and restore `process.env.CI` around itself, with a comment explaining
the workaround. That scaffolding is gone, and no test in this package touches
`process.env` any more.

Verified both ways: 251 tests with `CI=true` and with `CI` unset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mfal mfal self-assigned this Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for ./packages/components/

Status Category Percentage Covered / Total
🔵 Lines 78.69% 746 / 948
🔵 Statements 78.57% 763 / 971
🔵 Functions 80.09% 165 / 206
🔵 Branches 70.33% 377 / 536
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/components/dev/component-index/buildComponentIndex.ts 93.65% 83.67% 100% 93.54% 50, 107, 113, 129
packages/components/dev/component-index/filterProps.ts 100% 93.54% 100% 100%
packages/components/dev/component-index/remoteAvailability.ts 100% 100% 100% 100%
packages/components/src/components/propTypes/index.ts 100% 100% 100% 100%
Generated in workflow #6457 for commit 66aeb52 by the Vitest Coverage Report Action

@mfal
mfal marked this pull request as ready for review August 31, 2026 10:35
@mfal
mfal requested a review from a team August 31, 2026 10:35
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-3029.docs.review.flow-components.de
storybook pr-3029.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-3029
  • storybook: ghcr.io/mittwald/flow/storybook:pr-3029

@mfal
mfal enabled auto-merge (squash) August 31, 2026 11:08
@mfal
mfal disabled auto-merge August 31, 2026 11:17
@mfal
mfal enabled auto-merge (squash) August 31, 2026 11:17
mfal and others added 6 commits August 31, 2026 13:42
# Conflicts:
#	packages/components/MIGRATION.md
`guide.test.ts` pins the guide's newest anchor by id. The merge added a newer
entry (`use-design-tokens-build-metadata-removed`, `since: 1.0.16`), so the
expectation moves with it.

`eslint.config.js` arrives from `main` carrying the `no-restricted-imports` ban
on `@mittwald/flow-design-tokens/json/*` under `src/` — and `next` has a call
site `main` never saw. `collectTokensInPath` reads only `path` and `value`, so
`json-runtime/all-light.json` is a straight swap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
chore(sync): resolve forward-merge conflict (main into next)
The promotion direction inverts `**/CHANGELOG.md merge=ours` (ADR 0004 §3),
which is written for main → next. next's changelogs carry the prerelease line;
promoting them would overwrite the stable history publish.yml extracts GitHub
release bodies from. The graduation commit prepends the 1.1.0 entry.

Its own commit because the merge above is a no-op in the healthy steady state —
next already carries main — so there is no merge commit to absorb it (see #3030).
Captured from the Rating stories on this branch: maxValue={10}, fill="single"
and RatingSegment children, composed into one figure at 2x.

Committed rather than uploaded as a GitHub attachment: user-attachments has no
API, so that path cannot be automated. The release notes reference it by this
commit's SHA, which resolves during review and keeps resolving after the branch
is deleted — see #3030.
@mfal
mfal merged commit 3a17e79 into main Aug 31, 2026
26 of 27 checks passed
@mfal
mfal deleted the release/1.1.0 branch August 31, 2026 12:09
mfal added a commit that referenced this pull request Aug 31, 2026
The 1.1.0 promotion (#3029) brought feature work from `next` written against
the old, numbered docs paths. Two prose conflicts (Rating's scale guideline,
Align's codemod pointer) keep main's wording with this branch's paths, and the
two new Rating examples land in the renamed directory.

It also brought seven references to paths this branch removed, in files that
did not exist when the rename ran:

- `packages/codemods/project.json` pointed an nx input at
  `01-get-started/versioning/index.mdx`. A glob matching nothing contributes
  nothing to the task hash, so `test:unit` would have served stale cache when
  that page changed — silently.
- `documented.test.ts` and `mdxToMarkdown.test.ts` read or assert old paths.
- `USAGE.md` lists `/raw/**` paths for consumers.
- The CodeBlock migration entry links the old path, and while it was being
  touched, the legacy `/overview` tab redirect with it.

`MIGRATION.md` is an output of `nx build codemods`, so the fix went into
`entry.md` and the artifacts were regenerated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants