ui: peer ranges stop letting the gui train split under a consumer
Publish Packages / detect-changes (push) Successful in 12s
Publish Packages / publish (${{ fromJson(needs.detect-changes.outputs.packages) }}) (push) Skipped
Hanzo CI/CD / cicd (push) Failing after 4m56s
CI/CD / cicd (push) Failing after 4m56s

@hanzo/ui peer-depended on `@hanzogui/config: >=8.0.0`, and an app satisfying
that with 8.0.1 got `@hanzogui/web@8.0.0` — beside the `web@8.1.0` its direct
`@hanzo/gui@8.1.0` pulls. Two copies of the gui runtime, both typechecking,
both building, and then the config singleton lives in one module while the
components read the other. hanzo.industries hit exactly this on a routine bump.

The loose peer range IS the split, so the fix is here rather than in an override
downstream: @hanzo/gui, @hanzogui/config and @hanzogui/next-theme all move to
`>=8.1.0`. An app can no longer land on the 8.0 train while holding 8.1.

Also closes the hole in the harness that let this reach an app at all. The
consumer test installed @hanzo/ui alone, so the ONE shape that can split — a
real app depending on @hanzo/gui DIRECTLY, beside @hanzo/ui — was never
exercised, and the one-copy check I added last night reported a clean single
copy while a real consumer got two. The test app now installs @hanzo/gui and
@hanzogui/config the way every real app does.

Mutation-proven both ways: restore the `>=8.0.0` peer, have the consumer satisfy
it with config@8.0.1, and the harness now fails naming both versions —
"2 copies of @hanzogui/web resolved: 8.1.0, 8.0.0". Before this commit that same
scenario passed.

289 unit, 28 browser, webpack green, one copy of @hanzogui/web.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
zeekay
2026-08-05 01:43:11 -07:00
co-authored by hanzo-dev
parent bbbef9c65e
commit b18b61a580
7 changed files with 13 additions and 11 deletions
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@hanzo/ui",
"version": "8.0.60",
"version": "8.0.61",
"type": "module",
"description": "Hanzo UI \u2014 the one canonical Hanzo component library, on @hanzo/gui + @hanzo/design. ONE substrate: every component renders through @hanzo/gui primitives, so the same import works on web, native (expo) and desktop (Tauri). Self-contained (theme.css), presentational, host-agnostic, clean-room.",
"exports": {
@@ -178,7 +178,7 @@
"test:consumer:webpack": "node scripts/consumer-webpack.mjs"
},
"dependencies": {
"@hanzo/design": "^0.4.6",
"@hanzo/design": "^0.4.7",
"@hanzo/logo": "^1.0.13",
"@hanzo/products": "^0.2.0",
"@hanzogui/lucide-icons-2": "^8.1.0",
@@ -191,10 +191,10 @@
"@hanzo/cd": ">=0.1.0",
"@hanzo/dashboard": ">=0.1.0",
"@hanzo/data": ">=1.2.0",
"@hanzo/gui": ">=8.0.0",
"@hanzo/gui": ">=8.1.0",
"@hanzo/usage": ">=0.1.0",
"@hanzogui/config": ">=8.0.0",
"@hanzogui/next-theme": ">=8.0.0",
"@hanzogui/config": ">=8.1.0",
"@hanzogui/next-theme": ">=8.1.0",
"next-themes": ">=0.2.1",
"react": ">=19",
"react-dom": ">=19",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 105 KiB

+3 -1
View File
@@ -9,7 +9,9 @@
"dependencies": {
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-native-web": "^0.21.2"
"react-native-web": "^0.21.2",
"@hanzo/gui": "^8.1.0",
"@hanzogui/config": "^8.1.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^5.1.0",
+5 -5
View File
@@ -956,8 +956,8 @@ importers:
specifier: '>=0.1.0'
version: 0.2.0(@hanzo/gui@8.1.0(react-dom@19.2.4(react@19.2.4))(react-native@0.86.0(@babel/core@7.29.7)(@react-native/metro-config@0.86.0(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.4)(utf-8-validate@5.0.10))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@hanzo/design':
specifier: ^0.4.6
version: 0.4.6
specifier: ^0.4.7
version: 0.4.7
'@hanzo/logo':
specifier: ^1.0.13
version: 1.0.13(react@19.2.4)
@@ -2962,8 +2962,8 @@ packages:
react: 19.2.4
react-dom: 19.2.4
'@hanzo/design@0.4.6':
resolution: {integrity: sha512-kRjnGKsGqMfGTg2kMUv+pPRDryarYk85rMOoblIqshFIZJp48pCKYcdv1DmfxbNyKm+7CqvqD1NjY3HhNPUQ/A==}
'@hanzo/design@0.4.7':
resolution: {integrity: sha512-8RTDyekMi2goIYnZ+9BK2XqbVpzGTChEpCnabEQNJkGv2KcOEGljul21/+hoAivEyg5rBZX/bE9Pegp3VBb9pQ==}
hasBin: true
'@hanzo/docs-core@16.5.3':
@@ -16751,7 +16751,7 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
'@hanzo/design@0.4.6': {}
'@hanzo/design@0.4.7': {}
'@hanzo/docs-core@16.5.3(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.577.0(react@19.2.4))(mdast-util-mdx-jsx@3.2.0)(next@16.2.9(@babel/core@7.29.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.61.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.4.3)':
dependencies: