chore: drop 'hanzo' prefix from file/identifier names, use 'gui'/'Gui'

Internal renames so source matches the published @hanzogui/[email protected] dist
(Gui.ts, createGui.ts, views/GuiProvider.mjs, views/GuiRoot.mjs).

Renames applied:
- Files: Hanzogui.ts -> Gui.ts, createHanzogui.ts -> createGui.ts,
  HanzoguiProvider.tsx -> GuiProvider.tsx, HanzoguiRoot[.native].tsx ->
  GuiRoot[.native].tsx, HanzoguiPlugin.ts -> GuiPlugin.ts,
  withHanzogui.ts -> withGui.ts, loadHanzogui.ts -> loadGui.ts,
  v4-hanzogui.ts -> v4-gui.ts, *.d.ts mirrors, hanzogui.config.ts ->
  gui.config.ts, hanzogui.build.ts -> gui.build.ts, hanzogui.css ->
  gui.css, hanzogui-build.js -> gui-build.js, etc.
- Directories: pkgs/core/create-hanzogui -> pkgs/core/create-gui,
  apps/sandbox/config/hanzogui -> apps/sandbox/config/gui.
- Identifiers: Hanzogui* -> Gui*, createHanzogui -> createGui, withHanzogui
  -> withGui, loadHanzogui -> loadGui, HANZOGUI_* env -> GUI_*,
  __hanzogui* globals -> __gui*, hanzoguiOptions/hanzoguiConfig/
  hanzoguiPlugin etc. -> guiOptions/guiConfig/guiPlugin, CSS vars
  --hanzogui-* -> --gui-*, data-hanzogui-* -> data-gui-*, [hanzogui]
  log prefix -> [gui].
- Removed duplicate pkgs/packages/hanzogui-dev-config; the canonical
  pkgs/packages/gui-dev-config (@hanzogui/dev-config) already existed
  with the correct shape. apps/demos now consumes @hanzogui/dev-config.

Preserved (public npm names):
- "hanzogui" umbrella package (pkgs/ui/hanzogui/package.json)
- "@hanzogui/*" namespace
- "hanzogui-loader" package name (pkgs/compiler/loader)
- "hanzogui-build-test-*" test fixture names
- "hanzogui-publish-smoke" workflow id
- pkgs/core/helpers-hanzogui dir (not on rename list)
- apps/gui.hanzo.ai/ marketing site directory
- AGENTS.md symlink restored after perl -i clobbered it

Smoke build (turbo run build): 169/169 workspaces successful.
Sample tests: pkgs/core/core-test getSplitStyles.android* + createGui.web
all green.
This commit is contained in:
2026-05-26 18:25:52 -07:00
parent d95b92ab78
commit ba9f436467
1095 changed files with 1084260 additions and 5989 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ node_modules
**/*/node_modules
**/*/dist
**/*/.turbo
**/*/.hanzogui
**/*/.gui
# expo
**/*/.expo
@@ -1,9 +1,9 @@
name: Publish hanzogui + @hanzogui/admin
name: Publish gui + @hanzogui/admin
# Triggered only on `release/hanzogui-v*` tags. Bumping a workspace
# Triggered only on `release/gui-v*` tags. Bumping a workspace
# version alone does NOT publish — a tag push gates the run so an
# accidental version bump on `main` cannot ship to npm. Tag scheme:
# release/hanzogui-v7.1.0 → hanzo[email protected] + @hanzogui/admin@<own>
# release/gui-v7.1.0 → [email protected] + @hanzogui/admin@<own>
#
# NPM_TOKEN is sourced from KMS (kms.hanzo.ai) at runtime via Universal
# Auth. No long-lived NPM_TOKEN secret lives in GitHub. Same shape as
@@ -16,7 +16,7 @@ name: Publish hanzogui + @hanzogui/admin
on:
push:
tags:
- 'release/hanzogui-v*'
- 'release/gui-v*'
permissions:
contents: read
@@ -76,7 +76,7 @@ jobs:
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc
- name: Typecheck @hanzogui/admin
# `hanzogui` (umbrella) ships pre-built types via the
# `gui` (umbrella) ships pre-built types via the
# static-extractor pipeline and has no separate typecheck
# script — its types are validated transitively by every
# consumer. `@hanzogui/admin` ships TypeScript source and
@@ -94,7 +94,7 @@ jobs:
# no-op rebuild. Verifying the two dist trees exist is
# enough — pack will fail loudly if they don't.
run: |
test -d pkgs/ui/hanzogui/dist || (echo "::error::hanzogui/dist missing"; exit 1)
test -d pkgs/ui/hanzogui/dist || (echo "::error::gui/dist missing"; exit 1)
# @hanzogui/admin publishes source-only (no dist needed for
# `import` field — the `source`/`default` conditions point
# at ./src/*.ts, and downstream bundlers compile it).
@@ -133,13 +133,13 @@ jobs:
console.log('mapped', Object.keys(map).length, 'workspace packages');
"
- name: Pack hanzogui
- name: Pack gui
# `npm pack` does NOT resolve `workspace:*` specifiers; the resulting
# tarball would ship literal `workspace:*` and break consumers. We
# mirror what `scripts/release.ts` does — copy to a temp dir, rewrite
# every `workspace:*` to the matching package's on-disk version (from
# the workspace map built above), then pack.
id: pack-hanzogui
id: pack-gui
run: |
set -eu
tmpdir=$(mktemp -d)
@@ -196,7 +196,7 @@ jobs:
- name: Smoke-test packed tarballs from /tmp consumer
env:
HANZOGUI_TGZ: ${{ steps.pack-hanzogui.outputs.tgz }}
GUI_TGZ: ${{ steps.pack-gui.outputs.tgz }}
ADMIN_TGZ: ${{ steps.pack-admin.outputs.tgz }}
run: |
set -eu
@@ -204,9 +204,9 @@ jobs:
cd "$consumer"
# Minimal consumer — installs both tarballs and requires them.
# Catches: missing files in `files`, broken `exports` map,
# wrong `main`/`module` paths, Hanzogui→hanzogui rename leaks.
# NEVER call this package "Hanzogui" anywhere in published
# artifacts — the brand is hanzogui.
# wrong `main`/`module` paths, Gui→gui rename leaks.
# NEVER call this package "Gui" anywhere in published
# artifacts — the brand is gui.
cat > package.json <<'EOF'
{
"name": "hanzogui-publish-smoke",
@@ -216,7 +216,7 @@ jobs:
}
EOF
npm install --no-audit --no-fund --silent \
"${HANZOGUI_TGZ}" \
"${GUI_TGZ}" \
"${ADMIN_TGZ}" \
react@^19 react-dom@^19 react-router-dom@^7
# Static extractor scans for the literal `'hanzogui'` import
@@ -229,12 +229,12 @@ jobs:
node -e "require('hanzogui/package.json')"
node -e "require('@hanzogui/admin/package.json')"
- name: Publish hanzogui
- name: Publish gui
env:
NPM_TOKEN: ${{ steps.kms.outputs.npm_token }}
NODE_AUTH_TOKEN: ${{ steps.kms.outputs.npm_token }}
TGZ: ${{ steps.pack-hanzogui.outputs.tgz }}
working-directory: pkgs/ui/hanzogui
TGZ: ${{ steps.pack-gui.outputs.tgz }}
working-directory: pkgs/ui/gui
run: |
version=$(node -p "require('./package.json').version")
if npm view "hanzogui@${version}" version >/dev/null 2>&1; then
@@ -257,22 +257,22 @@ jobs:
fi
npm publish "${TGZ}" --access public --tag stable
- name: Pack + Publish @hanzo/gui (alias of hanzogui)
- name: Pack + Publish @hanzo/gui (alias of gui)
# Republish the umbrella tarball under the @hanzo/gui scoped name so
# downstream consumers can import either alias. Same dist tree as
# hanzogui — only `name` differs. The static extractor scans for the
# literal 'hanzogui' import token, so this alias is purely a consumer
# gui — only `name` differs. The static extractor scans for the
# literal 'gui' import token, so this alias is purely a consumer
# ergonomics shim and never participates in extractor input. We reuse
# the prepared tmpdir from the hanzogui pack step (workspace specs
# the prepared tmpdir from the gui pack step (workspace specs
# already rewritten) and only mutate `name`.
env:
NPM_TOKEN: ${{ steps.kms.outputs.npm_token }}
NODE_AUTH_TOKEN: ${{ steps.kms.outputs.npm_token }}
TMPDIR_HANZOGUI: ${{ steps.pack-hanzogui.outputs.tmpdir }}
TMPDIR_GUI: ${{ steps.pack-gui.outputs.tmpdir }}
run: |
set -eu
aliasdir=$(mktemp -d)
cp -R "$TMPDIR_HANZOGUI"/. "$aliasdir/"
cp -R "$TMPDIR_GUI"/. "$aliasdir/"
cd "$aliasdir"
jq '.name = "@hanzo/gui"' package.json > package.json.new
mv package.json.new package.json
+2 -2
View File
@@ -1,6 +1,6 @@
**/test-results/*
**/.maestro-debug
**/.hanzogui/
**/.gui/
# keep types in repo to track them
# **/types/**/*.d.ts
@@ -34,7 +34,7 @@ node_modules
code/kitchen-sink/ios
.hanzogui
.gui
.idea
+1 -1
View File
@@ -1,2 +1,2 @@
code/tests/next-turbopack/src/TestComponent.tsx
**/.hanzogui/
**/.gui/
+1 -1
View File
@@ -21,7 +21,7 @@
"**/*.lock",
"**/*.generated.*",
"**/generated-*",
"**/.hanzogui/**",
"**/.gui/**",
"**/node_modules/**",
],
}
+4 -4
View File
@@ -1,5 +1,5 @@
# local build dockerfile - uses bento from ../bento
# build from PARENT directory: docker build -f hanzogui5/Dockerfile.local -t hanzogui-site .
# build from PARENT directory: docker build -f gui5/Dockerfile.local -t gui-site .
FROM node:22
# install bun
@@ -46,14 +46,14 @@ WORKDIR /root
# copy both repos
COPY bento /root/bento
COPY hanzogui5 /root/hanzogui
COPY gui5 /root/gui
WORKDIR /root/hanzogui
WORKDIR /root/gui
# init git (allow empty commit if nothing to commit)
RUN git config --global user.email "[email protected]" && git config --global user.name "Docker Build" && git init . && git add -A && (git commit -m 'add' > /dev/null || true)
# install hanzogui deps first
# install gui deps first
RUN bun install
# setup bento - merge deps and symlink node_modules
+3 -3
View File
@@ -19,8 +19,8 @@
<br />
- `@hanzogui/web` - Universal style library for React.
- `hanzogui` - UI kit that adapts to every platform.
- `@hanzogui/static` - Optimizing compiler that works with `@hanzogui/web` and `hanzogui`.
- `gui` - UI kit that adapts to every platform.
- `@hanzogui/static` - Optimizing compiler that works with `@hanzogui/web` and `gui`.
<br />
@@ -32,7 +32,7 @@ It does this with an optimizing compiler that outputs platform-specific optimiza
The entirety of Hanzo GUI works at compile time and runtime, and can be set up gradually, with initial usage as simple as importing it and using the base views and styled function.
We recommend checking out the starters with `npm create hanzogui@latest`, they range from a simple learning example to a production-ready monorepo.
We recommend checking out the starters with `npm create gui@latest`, they range from a simple learning example to a production-ready monorepo.
The compiler optimizes most styled components by flattening them to plain `div`s (web) or `View`s (native) at build time. Real-world apps see double-digit Lighthouse improvements.
+5 -5
View File
@@ -6,23 +6,23 @@
// variables that we layer on top of Hanzo GUI's `dark` theme, NOT
// by mutating the themes object.
//
// IMPORTANT: this config file imports from `hanzogui` (workspace
// IMPORTANT: this config file imports from `gui` (workspace
// umbrella), NOT `@hanzo/gui`. Source code uses `@hanzo/gui`; the
// Vite alias in vite.config.ts routes that to this same workspace
// package at bundle time.
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
export const config = createHanzogui(defaultConfig)
export const config = createGui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
declare module '@hanzogui/web' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
+4 -4
View File
@@ -1,4 +1,4 @@
// Entry point. Wires HanzoguiProvider, BrowserRouter, and the route
// Entry point. Wires GuiProvider, BrowserRouter, and the route
// tree for the Hanzo Agents admin SPA.
//
// Operator chrome — orgs, API keys, billing, observability. Lives
@@ -8,7 +8,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import { PageShell } from '@hanzogui/admin'
import config from '../gui.config'
import App from './App'
@@ -23,7 +23,7 @@ if (!root) throw new Error('root element missing')
ReactDOM.createRoot(root).render(
<React.StrictMode>
<HanzoguiProvider config={config} defaultTheme="dark">
<GuiProvider config={config} defaultTheme="dark">
<BrowserRouter basename="/_/agents">
<Routes>
<Route path="/" element={<App />}>
@@ -36,6 +36,6 @@ ReactDOM.createRoot(root).render(
</Route>
</Routes>
</BrowserRouter>
</HanzoguiProvider>
</GuiProvider>
</React.StrictMode>,
)
+7 -7
View File
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite'
import path from 'node:path'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { guiPlugin } from '@hanzogui/vite-plugin'
// Hanzo Agents admin app.
//
@@ -18,8 +18,8 @@ const APP_VERSION = process.env.VITE_APP_VERSION ?? '0.1.0'
export default defineConfig({
plugins: [
hanzoguiPlugin({
components: ['hanzogui'],
guiPlugin({
components: ['gui'],
config: path.resolve(__dirname, 'gui.config.ts'),
}),
react(),
@@ -31,8 +31,8 @@ export default defineConfig({
process.env.VITE_API_PREFIX ?? '/v1/agents',
),
__DEV__: process.env.NODE_ENV !== 'production' ? 'true' : 'false',
'process.env.HANZOGUI_TARGET': JSON.stringify('web'),
'process.env.HANZOGUI_REACT_19': '"1"',
'process.env.GUI_TARGET': JSON.stringify('web'),
'process.env.GUI_REACT_19': '"1"',
},
resolve: {
alias: {
@@ -51,7 +51,7 @@ export default defineConfig({
'react',
'react-dom',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -65,7 +65,7 @@ export default defineConfig({
'react-dom/client',
'react/jsx-runtime',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+68 -68
View File
@@ -1,73 +1,73 @@
vite v8.0.13 building client environment for production...

➡ [hanzogui] built config, components, prompt (312ms)

transforming... 🐥 [hanzogui] web CollectionCRUD · 52 found · 46 opt · 32 flat 190ms
🐥 [hanzogui] web BatchActionBar · 9 found · 9 opt · 6 flat 12ms
🐥 [hanzogui] web Alert · 4 found · 3 opt · 2 flat 5ms
🐥 [hanzogui] web Badge · 2 found · 2 opt · 0 flat 3ms
🐥 [hanzogui] web WorkflowsTable · 11 found · 9 opt · 8 flat 30ms
🐥 [hanzogui] web ErrorBoundary · 4 found · 3 opt · 3 flat 11ms
🐥 [hanzogui] web SummaryCard · 4 found · 4 opt · 2 flat 3ms
🐥 [hanzogui] web EmptyVariants · 12 found · 10 opt · 10 flat 13ms
🐥 [hanzogui] web SearchInput · 11 found · 11 opt · 10 flat 40ms
🐥 [hanzogui] web BrandMark · 1 found · 1 opt · 0 flat 5ms
🐥 [hanzogui] web AuthGate · 10 found · 9 opt · 9 flat 13ms
🐥 [hanzogui] web WorkflowFilters · 8 found · 8 opt · 6 flat 16ms
🐥 [hanzogui] web Sidebar · 18 found · 17 opt · 17 flat 45ms
🐥 [hanzogui] web PageShell · 1 found · 1 opt · 0 flat 5ms
🐥 [hanzogui] web AdminApp · 4 found · 4 opt · 4 flat 1ms
🐥 [hanzogui] web CopyField · 3 found · 3 opt · 2 flat 4ms
🐥 [hanzogui] web Breadcrumbs · 4 found · 4 opt · 4 flat 13ms
🐥 [hanzogui] web DataTable · 13 found · 13 opt · 6 flat 24ms
🐥 [hanzogui] web Captcha · 11 found · 8 opt · 5 flat 10ms
🐥 [hanzogui] web TopBar · 48 found · 48 opt · 41 flat 159ms
🐥 [hanzogui] web ForgotPassword · 19 found · 14 opt · 12 flat 18ms
🐥 [hanzogui] web MfaSetup · 24 found · 19 opt · 17 flat 20ms
🐥 [hanzogui] web Login · 21 found · 16 opt · 10 flat 39ms
🐥 [hanzogui] web MfaVerify · 17 found · 15 opt · 9 flat 14ms
🐥 [hanzogui] web Empty · 15 found · 12 opt · 12 flat 8ms
🐥 [hanzogui] web QrCode · 5 found · 2 opt · 3 flat 7ms
🐥 [hanzogui] web RecoveryCodes · 11 found · 11 opt · 7 flat 15ms
🐥 [hanzogui] web SettingsMenu · 10 found · 10 opt · 8 flat 8ms
🐥 [hanzogui] web Signup · 28 found · 18 opt · 12 flat 36ms
🐥 [hanzogui] web SavedViewsRail · 4 found · 4 opt · 3 flat 13ms
🐥 [hanzogui] web SiteList · 16 found · 16 opt · 10 flat 17ms
🐥 [hanzogui] web ResourceList · 26 found · 25 opt · 19 flat 27ms
🐥 [hanzogui] web FormList · 18 found · 18 opt · 12 flat 27ms
🐥 [hanzogui] web SiteEdit · 18 found · 13 opt · 12 flat 23ms
🐥 [hanzogui] web ServerList · 19 found · 19 opt · 12 flat 28ms
🐥 [hanzogui] web RecordList · 40 found · 39 opt · 33 flat 32ms
🐥 [hanzogui] web ServerEdit · 22 found · 14 opt · 13 flat 30ms
🐥 [hanzogui] web TicketList · 23 found · 22 opt · 15 flat 25ms
🐥 [hanzogui] web RuleList · 21 found · 21 opt · 15 flat 30ms
🐥 [hanzogui] web TicketEdit · 31 found · 26 opt · 24 flat 48ms
🐥 [hanzogui] web OrgEdit · 8 found · 7 opt · 6 flat 15ms
🐥 [hanzogui] web RuleEdit · 19 found · 13 opt · 13 flat 34ms
🐥 [hanzogui] web UserEdit · 8 found · 7 opt · 6 flat 21ms
🐥 [hanzogui] web FormEdit · 19 found · 15 opt · 14 flat 26ms
🐥 [hanzogui] web GroupList · 20 found · 19 opt · 13 flat 20ms
🐥 [hanzogui] web UserList · 33 found · 28 opt · 19 flat 50ms
🐥 [hanzogui] web GroupEdit · 8 found · 7 opt · 6 flat 10ms
🐥 [hanzogui] web RoleEdit · 8 found · 7 opt · 6 flat 12ms
🐥 [hanzogui] web GroupTree · 18 found · 16 opt · 9 flat 29ms
🐥 [hanzogui] web RoleList · 19 found · 18 opt · 13 flat 21ms
🐥 [hanzogui] web LoginShowcase · 4 found · 4 opt · 4 flat 3ms
🐥 [hanzogui] web ManagementPage · 5 found · 3 opt · 5 flat 1ms
🐥 [hanzogui] web OrgList · 21 found · 19 opt · 12 flat 31ms
🐥 [hanzogui] web SystemInfo · 35 found · 26 opt · 28 flat 15ms
🐥 [hanzogui] web LdapSync · 38 found · 34 opt · 29 flat 49ms
🐥 [hanzogui] web Setting · 24 found · 19 opt · 17 flat 30ms
🐥 [hanzogui] web EntryPage · 2 found · 1 opt · 2 flat 2ms
🐥 [hanzogui] web Field · 14 found · 10 opt · 9 flat 19ms
🐥 [hanzogui] web LdapEdit · 22 found · 17 opt · 10 flat 55ms
🐥 [hanzogui] web WebhookList · 20 found · 18 opt · 15 flat 23ms
🐥 [hanzogui] web SyncerList · 21 found · 19 opt · 15 flat 28ms
🐥 [hanzogui] web SyncerEdit · 35 found · 20 opt · 11 flat 96ms
🐥 [hanzogui] web InvitationList · 22 found · 20 opt · 17 flat 43ms
🐥 [hanzogui] web VerificationList · 18 found · 16 opt · 16 flat 26ms
🐥 [hanzogui] web InvitationEdit · 31 found · 21 opt · 13 flat 43ms
🐥 [hanzogui] web WebhookEdit · 28 found · 21 opt · 11 flat 43ms
➡ [gui] built config, components, prompt (312ms)

transforming... 🐥 [gui] web CollectionCRUD · 52 found · 46 opt · 32 flat 190ms
🐥 [gui] web BatchActionBar · 9 found · 9 opt · 6 flat 12ms
🐥 [gui] web Alert · 4 found · 3 opt · 2 flat 5ms
🐥 [gui] web Badge · 2 found · 2 opt · 0 flat 3ms
🐥 [gui] web WorkflowsTable · 11 found · 9 opt · 8 flat 30ms
🐥 [gui] web ErrorBoundary · 4 found · 3 opt · 3 flat 11ms
🐥 [gui] web SummaryCard · 4 found · 4 opt · 2 flat 3ms
🐥 [gui] web EmptyVariants · 12 found · 10 opt · 10 flat 13ms
🐥 [gui] web SearchInput · 11 found · 11 opt · 10 flat 40ms
🐥 [gui] web BrandMark · 1 found · 1 opt · 0 flat 5ms
🐥 [gui] web AuthGate · 10 found · 9 opt · 9 flat 13ms
🐥 [gui] web WorkflowFilters · 8 found · 8 opt · 6 flat 16ms
🐥 [gui] web Sidebar · 18 found · 17 opt · 17 flat 45ms
🐥 [gui] web PageShell · 1 found · 1 opt · 0 flat 5ms
🐥 [gui] web AdminApp · 4 found · 4 opt · 4 flat 1ms
🐥 [gui] web CopyField · 3 found · 3 opt · 2 flat 4ms
🐥 [gui] web Breadcrumbs · 4 found · 4 opt · 4 flat 13ms
🐥 [gui] web DataTable · 13 found · 13 opt · 6 flat 24ms
🐥 [gui] web Captcha · 11 found · 8 opt · 5 flat 10ms
🐥 [gui] web TopBar · 48 found · 48 opt · 41 flat 159ms
🐥 [gui] web ForgotPassword · 19 found · 14 opt · 12 flat 18ms
🐥 [gui] web MfaSetup · 24 found · 19 opt · 17 flat 20ms
🐥 [gui] web Login · 21 found · 16 opt · 10 flat 39ms
🐥 [gui] web MfaVerify · 17 found · 15 opt · 9 flat 14ms
🐥 [gui] web Empty · 15 found · 12 opt · 12 flat 8ms
🐥 [gui] web QrCode · 5 found · 2 opt · 3 flat 7ms
🐥 [gui] web RecoveryCodes · 11 found · 11 opt · 7 flat 15ms
🐥 [gui] web SettingsMenu · 10 found · 10 opt · 8 flat 8ms
🐥 [gui] web Signup · 28 found · 18 opt · 12 flat 36ms
🐥 [gui] web SavedViewsRail · 4 found · 4 opt · 3 flat 13ms
🐥 [gui] web SiteList · 16 found · 16 opt · 10 flat 17ms
🐥 [gui] web ResourceList · 26 found · 25 opt · 19 flat 27ms
🐥 [gui] web FormList · 18 found · 18 opt · 12 flat 27ms
🐥 [gui] web SiteEdit · 18 found · 13 opt · 12 flat 23ms
🐥 [gui] web ServerList · 19 found · 19 opt · 12 flat 28ms
🐥 [gui] web RecordList · 40 found · 39 opt · 33 flat 32ms
🐥 [gui] web ServerEdit · 22 found · 14 opt · 13 flat 30ms
🐥 [gui] web TicketList · 23 found · 22 opt · 15 flat 25ms
🐥 [gui] web RuleList · 21 found · 21 opt · 15 flat 30ms
🐥 [gui] web TicketEdit · 31 found · 26 opt · 24 flat 48ms
🐥 [gui] web OrgEdit · 8 found · 7 opt · 6 flat 15ms
🐥 [gui] web RuleEdit · 19 found · 13 opt · 13 flat 34ms
🐥 [gui] web UserEdit · 8 found · 7 opt · 6 flat 21ms
🐥 [gui] web FormEdit · 19 found · 15 opt · 14 flat 26ms
🐥 [gui] web GroupList · 20 found · 19 opt · 13 flat 20ms
🐥 [gui] web UserList · 33 found · 28 opt · 19 flat 50ms
🐥 [gui] web GroupEdit · 8 found · 7 opt · 6 flat 10ms
🐥 [gui] web RoleEdit · 8 found · 7 opt · 6 flat 12ms
🐥 [gui] web GroupTree · 18 found · 16 opt · 9 flat 29ms
🐥 [gui] web RoleList · 19 found · 18 opt · 13 flat 21ms
🐥 [gui] web LoginShowcase · 4 found · 4 opt · 4 flat 3ms
🐥 [gui] web ManagementPage · 5 found · 3 opt · 5 flat 1ms
🐥 [gui] web OrgList · 21 found · 19 opt · 12 flat 31ms
🐥 [gui] web SystemInfo · 35 found · 26 opt · 28 flat 15ms
🐥 [gui] web LdapSync · 38 found · 34 opt · 29 flat 49ms
🐥 [gui] web Setting · 24 found · 19 opt · 17 flat 30ms
🐥 [gui] web EntryPage · 2 found · 1 opt · 2 flat 2ms
🐥 [gui] web Field · 14 found · 10 opt · 9 flat 19ms
🐥 [gui] web LdapEdit · 22 found · 17 opt · 10 flat 55ms
🐥 [gui] web WebhookList · 20 found · 18 opt · 15 flat 23ms
🐥 [gui] web SyncerList · 21 found · 19 opt · 15 flat 28ms
🐥 [gui] web SyncerEdit · 35 found · 20 opt · 11 flat 96ms
🐥 [gui] web InvitationList · 22 found · 20 opt · 17 flat 43ms
🐥 [gui] web VerificationList · 18 found · 16 opt · 16 flat 26ms
🐥 [gui] web InvitationEdit · 31 found · 21 opt · 13 flat 43ms
🐥 [gui] web WebhookEdit · 28 found · 21 opt · 11 flat 43ms
🐥 [gui] web LabelRow · 4 found · 3 opt · 2 flat 5ms
✓ 1042 modules transformed.
rendering chunks...
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -10,15 +10,15 @@
import React from 'react'
import { NavigationContainer } from '@react-navigation/native'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import BaseAdminApp from '@hanzo/base-ui/App'
import hanzoguiConfig from './gui.config'
import guiConfig from './gui.config'
function Provider({ children }: { children: React.ReactNode }) {
return (
<HanzoguiProvider config={hanzoguiConfig} defaultTheme="light">
<GuiProvider config={guiConfig} defaultTheme="light">
{children}
</HanzoguiProvider>
</GuiProvider>
)
}
+3 -3
View File
@@ -3,12 +3,12 @@ module.exports = function (api) {
return {
presets: ['babel-preset-expo'],
plugins: [
// hanzogui / @hanzogui/* are React Native + web universal; the
// hanzogui babel plugin does the import-tree-shake and reads the
// gui / @hanzogui/* are React Native + web universal; the
// gui babel plugin does the import-tree-shake and reads the
// active design config from `gui.config.ts`.
[
'@hanzogui/babel-plugin',
{ components: ['hanzogui'], config: './gui.config.ts' },
{ components: ['gui'], config: './gui.config.ts' },
],
],
}
+5 -5
View File
@@ -1,12 +1,12 @@
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
const hanzoguiConfig = createHanzogui(defaultConfig)
const guiConfig = createGui(defaultConfig)
export type Conf = typeof hanzoguiConfig
export type Conf = typeof guiConfig
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
export default hanzoguiConfig
export default guiConfig
+2 -2
View File
@@ -11,7 +11,7 @@ config.resolver.unstable_enablePackageExports =
// block unnecessary directories from metro file crawling
config.resolver.blockList = [
/code\/hanzogui\.dev\//,
/code\/gui\.dev\//,
/code\/.*\/__tests__\//,
/code\/.*\/\.maestro\//,
]
@@ -22,5 +22,5 @@ config.resolver.nodeModulesPaths = [
path.resolve(monorepoRoot, 'node_modules'),
]
// no withHanzogui, no unstable_conditionNames — same shape as kitchen-sink-go
// no withGui, no unstable_conditionNames — same shape as kitchen-sink-go
module.exports = config
+1 -1
View File
@@ -1,6 +1,6 @@
node_modules/
dist/
.hanzogui/
.gui/
*.log
.DS_Store
.vite/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+9 -9
View File
@@ -1,26 +1,26 @@
// Hanzogui config for Hanzo Base admin UI.
// Gui config for Hanzo Base admin UI.
//
// Same shape as admin-tasks — uses @hanzogui/config v5 default so
// runtime theme registry resolves. Brand recoloring lives in
// src/index.css as CSS variables layered over Hanzogui's `dark` theme.
// src/index.css as CSS variables layered over Gui's `dark` theme.
//
// IMPORTANT: imports from `hanzogui` (workspace umbrella). The static
// extractor copies this file into `.hanzogui/` at build time and
// re-resolves imports from there — that temp dir can find `hanzogui`
// IMPORTANT: imports from `gui` (workspace umbrella). The static
// extractor copies this file into `.gui/` at build time and
// re-resolves imports from there — that temp dir can find `gui`
// via standard node_modules walk-up.
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
export const config = createHanzogui(defaultConfig)
export const config = createGui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
declare module '@hanzogui/web' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
@@ -1,4 +1,4 @@
// Hanzogui SectionCard. Replaces the legacy HTML/CSS version. Used as
// Gui SectionCard. Replaces the legacy HTML/CSS version. Used as
// the chrome for each settings sub-form: title row + optional
// description + content slot.
+4 -4
View File
@@ -1,4 +1,4 @@
// Entry point. Wires HanzoguiProvider, BrowserRouter, and the route
// Entry point. Wires GuiProvider, BrowserRouter, and the route
// tree. Login is unguarded; everything else routes through App's
// AdminApp shell with an auth gate.
//
@@ -17,7 +17,7 @@ import {
useLocation,
useParams,
} from 'react-router-dom'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import { PageShell } from '@hanzogui/admin'
import config from '../gui.config'
import App from './App'
@@ -59,7 +59,7 @@ if (!root) throw new Error('root element missing')
ReactDOM.createRoot(root).render(
<React.StrictMode>
<HanzoguiProvider config={config} defaultTheme="dark">
<GuiProvider config={config} defaultTheme="dark">
<BrowserRouter basename="/_">
<Routes>
<Route path="/login" element={<Login />} />
@@ -97,6 +97,6 @@ ReactDOM.createRoot(root).render(
</Route>
</Routes>
</BrowserRouter>
</HanzoguiProvider>
</GuiProvider>
</React.StrictMode>,
)
+8 -8
View File
@@ -1,11 +1,11 @@
import { defineConfig } from 'vite'
import path from 'node:path'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { guiPlugin } from '@hanzogui/vite-plugin'
// Hanzo Base admin SPA.
//
// Mirrors admin-tasks shape (same hanzogui static-extractor pipeline,
// Mirrors admin-tasks shape (same gui static-extractor pipeline,
// same dedupe list, same optimizeDeps include set). One way across
// every admin surface.
//
@@ -32,8 +32,8 @@ const IAM_TARGET = process.env.VITE_IAM_URL ?? BASE_TARGET
export default defineConfig({
plugins: [
hanzoguiPlugin({
components: ['hanzogui'],
guiPlugin({
components: ['gui'],
config: path.resolve(__dirname, 'gui.config.ts'),
}),
react(),
@@ -58,8 +58,8 @@ export default defineConfig({
process.env.VITE_BRAND_MARK_URL ?? '',
),
__DEV__: process.env.NODE_ENV !== 'production' ? 'true' : 'false',
'process.env.HANZOGUI_TARGET': JSON.stringify('web'),
'process.env.HANZOGUI_REACT_19': '"1"',
'process.env.GUI_TARGET': JSON.stringify('web'),
'process.env.GUI_REACT_19': '"1"',
},
resolve: {
alias: {
@@ -74,7 +74,7 @@ export default defineConfig({
'react',
'react-dom',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -88,7 +88,7 @@ export default defineConfig({
'react-dom/client',
'react/jsx-runtime',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
+1 -1
View File
@@ -1,6 +1,6 @@
node_modules/
dist/
.hanzogui/
.gui/
*.log
.DS_Store
.vite/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7 -7
View File
@@ -6,23 +6,23 @@
// the themes object — spreading it through a JS module breaks the
// static shape getThemeProxied() depends on.
//
// IMPORTANT: this config file imports from `hanzogui` (workspace
// umbrella). The static extractor copies this file into `.hanzogui/`
// at build time; that temp dir can find `hanzogui` via standard
// IMPORTANT: this config file imports from `gui` (workspace
// umbrella). The static extractor copies this file into `.gui/`
// at build time; that temp dir can find `gui` via standard
// node_modules walk-up.
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
export const config = createHanzogui(defaultConfig)
export const config = createGui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
declare module '@hanzogui/web' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
+4 -4
View File
@@ -1,4 +1,4 @@
// Entry point for admin-bot. Wires HanzoguiProvider, BrowserRouter,
// Entry point for admin-bot. Wires GuiProvider, BrowserRouter,
// and the route tree. Tabs mirror the legacy Lit nav (chat / control:
// overview, channels, instances, sessions, usage, cron / agent: agents,
// skills, nodes / settings: config, debug, logs).
@@ -8,7 +8,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import { PageShell } from '@hanzogui/admin'
import config from '../gui.config'
import App from './App'
@@ -31,7 +31,7 @@ if (!root) throw new Error('root element missing')
ReactDOM.createRoot(root).render(
<React.StrictMode>
<HanzoguiProvider config={config} defaultTheme="dark">
<GuiProvider config={config} defaultTheme="dark">
<BrowserRouter basename="/_/bot">
<Routes>
<Route path="/" element={<App />}>
@@ -52,6 +52,6 @@ ReactDOM.createRoot(root).render(
</Route>
</Routes>
</BrowserRouter>
</HanzoguiProvider>
</GuiProvider>
</React.StrictMode>,
)
+8 -8
View File
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite'
import path from 'node:path'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { guiPlugin } from '@hanzogui/vite-plugin'
// Hanzo Bot admin app.
//
@@ -21,10 +21,10 @@ const APP_VERSION = process.env.VITE_APP_VERSION ?? '0.1.0'
export default defineConfig({
plugins: [
hanzoguiPlugin({
components: ['hanzogui'],
guiPlugin({
components: ['gui'],
// Absolute path — keeps the extractor from getting confused
// when it copies the config into a `.hanzogui/` temp dir.
// when it copies the config into a `.gui/` temp dir.
config: path.resolve(__dirname, 'gui.config.ts'),
}),
react(),
@@ -36,8 +36,8 @@ export default defineConfig({
process.env.VITE_API_PREFIX ?? '/v1/bot',
),
__DEV__: process.env.NODE_ENV !== 'production' ? 'true' : 'false',
'process.env.HANZOGUI_TARGET': JSON.stringify('web'),
'process.env.HANZOGUI_REACT_19': '"1"',
'process.env.GUI_TARGET': JSON.stringify('web'),
'process.env.GUI_REACT_19': '"1"',
},
resolve: {
alias: {
@@ -52,7 +52,7 @@ export default defineConfig({
'react',
'react-dom',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -66,7 +66,7 @@ export default defineConfig({
'react-dom/client',
'react/jsx-runtime',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -1,19 +1,19 @@
// Hanzo GUI config for the Commerce admin SPA. Mirrors admin-tasks —
// uses @hanzogui/config v5 default so the static extractor can resolve
// the theme registry from the generated .hanzogui temp dir.
// the theme registry from the generated .gui temp dir.
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
export const config = createHanzogui(defaultConfig)
export const config = createGui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
declare module '@hanzogui/web' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
+4 -4
View File
@@ -1,10 +1,10 @@
// Entry point. Wires HanzoguiProvider, BrowserRouter, and the route
// Entry point. Wires GuiProvider, BrowserRouter, and the route
// tree. PageShell wraps each page for consistent padding.
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import { PageShell } from '@hanzogui/admin'
import config from '../gui.config'
import App from './App'
@@ -22,7 +22,7 @@ if (!root) throw new Error('root element missing')
ReactDOM.createRoot(root).render(
<React.StrictMode>
<HanzoguiProvider config={config} defaultTheme="dark">
<GuiProvider config={config} defaultTheme="dark">
<BrowserRouter basename="/_/commerce/ui">
<Routes>
<Route path="/" element={<App />}>
@@ -38,6 +38,6 @@ ReactDOM.createRoot(root).render(
</Route>
</Routes>
</BrowserRouter>
</HanzoguiProvider>
</GuiProvider>
</React.StrictMode>,
)
+7 -7
View File
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite'
import path from 'node:path'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { guiPlugin } from '@hanzogui/vite-plugin'
// Hanzo Commerce admin app.
//
@@ -14,8 +14,8 @@ const APP_VERSION = process.env.VITE_APP_VERSION ?? '1.38.0'
export default defineConfig({
plugins: [
hanzoguiPlugin({
components: ['hanzogui'],
guiPlugin({
components: ['gui'],
config: path.resolve(__dirname, 'gui.config.ts'),
}),
react(),
@@ -24,8 +24,8 @@ export default defineConfig({
define: {
'import.meta.env.VITE_APP_VERSION': JSON.stringify(APP_VERSION),
__DEV__: process.env.NODE_ENV !== 'production' ? 'true' : 'false',
'process.env.HANZOGUI_TARGET': JSON.stringify('web'),
'process.env.HANZOGUI_REACT_19': '"1"',
'process.env.GUI_TARGET': JSON.stringify('web'),
'process.env.GUI_REACT_19': '"1"',
},
resolve: {
alias: {
@@ -40,7 +40,7 @@ export default defineConfig({
'react',
'react-dom',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -54,7 +54,7 @@ export default defineConfig({
'react-dom/client',
'react/jsx-runtime',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
+1 -1
View File
@@ -1,6 +1,6 @@
node_modules/
dist/
.hanzogui/
.gui/
*.log
.DS_Store
.vite/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+11 -11
View File
@@ -1,16 +1,16 @@
# `@hanzo/tasks`
The Hanzo Tasks SPA. Vite, Hanzogui via the `hanzogui` umbrella, composed
The Hanzo Tasks SPA. Vite, Gui via the `gui` umbrella, composed
from `@hanzogui/admin` chrome + transport-agnostic data hooks. Ships
standalone to `tasks.hanzo.ai` and is also embedded in `tasksd` (Go
binary) under `/_/tasks/`.
## Why this lives in `gui`
This app consumes `hanzogui`, `@hanzogui/core`, and `@hanzogui/admin`
This app consumes `gui`, `@hanzogui/core`, and `@hanzogui/admin`
through `workspace:*`. That's the only place the static extractor's
bundled-config worker can re-resolve those imports when it copies
`hanzogui.config.ts` into `.hanzogui/hanzogui.config.mjs` at build time.
`gui.config.ts` into `.gui/gui.config.mjs` at build time.
Outside the workspace, hoisting can't reach the temp file and the
extractor crashes on `cannot find @hanzogui/core`. Inside, every dep
resolves through the root `node_modules` and the extractor emits the
@@ -21,7 +21,7 @@ theme CSS layer cleanly.
- The package name is **`@hanzo/tasks`** — top-level under `@hanzo/*`,
same namespace as the product binary (`tasksd`) and the public domain
(`tasks.hanzo.ai`).
- All gui-internals (the umbrella `hanzogui`, deep packages
- All gui-internals (the umbrella `gui`, deep packages
`@hanzogui/admin`, `@hanzogui/core`, `@hanzogui/web`,
`@hanzogui/lucide-icons-2`, `@hanzogui/config`, etc.) stay under
`@hanzogui/*`. The line is: **`@hanzogui/*` = gui internals, `@hanzo/*`
@@ -38,7 +38,7 @@ target — anyone running `tasksd start` gets the embedded UI for free,
no Node.js required.
`@hanzo/tasks` is a different deployment target: the cloud
SPA at `tasks.hanzo.ai`. Same backend (`/v1/tasks/*`), Hanzogui chrome,
SPA at `tasks.hanzo.ai`. Same backend (`/v1/tasks/*`), Gui chrome,
and the bigger surface for namespaces / batches / deployments / nexus
that we want first-class on the web.
@@ -71,7 +71,7 @@ bun run preview # serve dist/ for a sanity check
| Total | 1.5 MB | **0.68 MB** |
| Gzip JS | 294,962 B | **201,529 B** (-32%) |
Hanzogui's static extractor hoists the style props it can resolve at
Gui's static extractor hoists the style props it can resolve at
build time into atomic class names in a single CSS file, then strips
the style runtime call sites in JS. The savings come from both the
removed style-prop arguments AND the dropped runtime style code.
@@ -82,8 +82,8 @@ removed style-prop arguments AND the dropped runtime style code.
|---|---|
| `package.json` | bun workspace manifest — every gui dep via `workspace:*` |
| `tsconfig.json` | strict TS, bundler resolution, JSX react-jsx |
| `vite.config.ts` | Vite 8 + `@vitejs/plugin-react` + `hanzoguiPlugin`; aliases `react-native` → `react-native-web` and `react-native-svg` → `@hanzogui/react-native-svg`; proxies `/v1/tasks` → `127.0.0.1:7243`; serves under `/_/tasks/` to match tasksd's path |
| `hanzogui.config.ts` | extends `@hanzogui/config`'s v5 default — clean, no runtime spread |
| `vite.config.ts` | Vite 8 + `@vitejs/plugin-react` + `guiPlugin`; aliases `react-native` → `react-native-web` and `react-native-svg` → `@hanzogui/react-native-svg`; proxies `/v1/tasks` → `127.0.0.1:7243`; serves under `/_/tasks/` to match tasksd's path |
| `gui.config.ts` | extends `@hanzogui/config`'s v5 default — clean, no runtime spread |
| `index.html` | SPA shell, dark `<body>`, Inter font preconnect |
| `src/main.tsx` | React root, BrowserRouter at basename `/_/tasks` |
| `src/App.tsx` | wires `@hanzogui/admin` chrome with tasks-specific nav config |
@@ -99,16 +99,16 @@ removed style-prop arguments AND the dropped runtime style code.
been ported across yet. Single-page focus first.
- **Auth flow** — currently relies on identity headers injected by
`hanzoai/gateway` in production. Local dev runs without auth.
- **Mobile target** — Hanzogui compiles to react-native for iOS/Android
- **Mobile target** — Gui compiles to react-native for iOS/Android
but no native shell exists yet. Future work.
## Conventions
- Strict TypeScript. `noUnusedLocals` / `noUnusedParameters` on.
- No HTML / CSS DOM primitives. Hanzogui only.
- No HTML / CSS DOM primitives. Gui only.
- All gui deps via `workspace:*`. Never pin a version on a package
that lives in this repo.
- Extractor stays enabled. If a Hanzogui type widening breaks the
- Extractor stays enabled. If a Gui type widening breaks the
build, fix the type — don't disable extraction.
- Versioning tracks upstream `temporalio/ui` major.minor. Don't bump
majors for internal UI rewrites — that's how we ended up at v3.x.x
+11 -11
View File
@@ -1,34 +1,34 @@
// Hanzogui config for Hanzo Tasks UI v2.
// Gui config for Hanzo Tasks UI v2.
//
// Use the canonical @hanzogui/config v5 default (same shape the
// starter at ~/work/hanzo/gui/code/starters/expo-router uses) so
// Hanzogui's runtime theme registry resolves cleanly. Hanzo brand
// Gui's runtime theme registry resolves cleanly. Hanzo brand
// recoloring lives in src/index.css as CSS variables that we layer
// on top of Hanzogui's `dark` theme, NOT by mutating the themes
// on top of Gui's `dark` theme, NOT by mutating the themes
// object — spreading it through a JS module breaks the static
// shape Hanzogui's getThemeProxied() depends on.
// shape Gui's getThemeProxied() depends on.
// IMPORTANT: this config file imports from `hanzogui` (workspace
// IMPORTANT: this config file imports from `gui` (workspace
// umbrella), NOT `@hanzo/gui`. Source code uses `@hanzo/gui` (the
// canonical Hanzo umbrella name) — the Vite alias in vite.config.ts
// routes that to this same workspace package at bundle time. The
// static extractor copies this file into `.hanzogui/` at build time
// static extractor copies this file into `.gui/` at build time
// and re-resolves imports from there — that temp dir can find
// `hanzogui` via standard node_modules walk-up but NOT `@hanzo/gui`,
// `gui` via standard node_modules walk-up but NOT `@hanzo/gui`,
// which has no walk-up reach from a generated subdir.
import { defaultConfig } from '@hanzogui/config/v5'
import { createHanzogui } from 'hanzogui'
import { createGui } from 'hanzogui'
export const config = createHanzogui(defaultConfig)
export const config = createGui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
declare module '@hanzogui/web' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
}
@@ -1,6 +1,6 @@
// CronEditor — pure logic tests for the validator and preset table.
// We do not render the component itself: hanzogui Input pulls in the
// Hanzogui theme extractor at module-eval, which is wired up in the
// We do not render the component itself: gui Input pulls in the
// Gui theme extractor at module-eval, which is wired up in the
// kitchen-sink shell, not here. Behavioural coverage that requires
// the provider lives there.
@@ -6,7 +6,7 @@ import {
} from '../event/event-attribute-rows'
import { buildHistoryEvent } from '../../test/factories'
// EventAttributeTable.tsx pulls in the hanzogui Hanzogui provider chain
// EventAttributeTable.tsx pulls in the gui Gui provider chain
// (Text/XStack/Badge), which under jsdom requires the full theme
// extractor (see WorkflowStatusPill.test.tsx for the same trade-off).
// The load-bearing pieces are pure: row derivation per event-type and
@@ -1,7 +1,7 @@
import { describe, it } from 'vitest'
// FEATURE-1 shipped src/components/workflow/WorkflowStatusPill.tsx. The
// component pulls in the hanzogui HanzoguiProvider chain transitively
// component pulls in the gui GuiProvider chain transitively
// (Text/XStack/Badge), which under jsdom requires the full theme
// extractor to have run. Wiring that up at the unit-test layer is
// disproportionate to the value — the pill renders a single Badge with
@@ -13,6 +13,6 @@ import { describe, it } from 'vitest'
// - if FEATURE-1 (or a follow-up) wires a lightweight test provider
// into @hanzogui/admin, this file is the one place to enable RTL
// coverage for the pill.
describe.skip('WorkflowStatusPill (needs hanzogui test provider)', () => {
describe.skip('WorkflowStatusPill (needs gui test provider)', () => {
it('placeholder', () => {})
})
@@ -1,6 +1,6 @@
// Pure-logic tests for cluster + migration components. We assert the
// exported predicates (effectiveHealth, canSubmitMigration) directly
// to avoid the hanzogui provider chain — same reasoning as
// to avoid the gui provider chain — same reasoning as
// WorkflowStatusPill.test.tsx.
import { describe, it, expect } from 'vitest'
@@ -18,7 +18,7 @@ export interface ValidatorTableProps {
export type EffectiveHealth = 'healthy' | 'laggy' | 'failed' | 'unknown'
// Predicate exported separately so unit tests can assert without
// rendering the full table component (avoids the hanzogui provider
// rendering the full table component (avoids the gui provider
// chain that would otherwise need a test-mode shim).
export function effectiveHealth(v: Validator, lagThresholdMs = 500): EffectiveHealth {
if (v.health === 'failed') return 'failed'
@@ -7,7 +7,7 @@
// drawer.
//
// Implementation notes:
// - hanzogui doesn't yet export a Drawer primitive; we mirror the
// - gui doesn't yet export a Drawer primitive; we mirror the
// same fixed-position YStack pattern used by ActionDialog so the
// visual language stays consistent with the rest of admin-tasks.
// - Native checkboxes + label rows; no a11y libraries needed.
@@ -12,7 +12,7 @@
// MarkerRecorded with one populated header doesn't spam 8 nulls.
//
// The pure logic lives in ./event-attribute-rows so the unit test can
// exercise row derivation + payload decoding without a Hanzogui provider.
// exercise row derivation + payload decoding without a Gui provider.
import { useMemo, useState } from 'react'
import { Button, Text, XStack, YStack } from 'hanzogui'
@@ -1,10 +1,10 @@
// Pure logic for EventAttributeTable. Lives in its own file (no JSX,
// no Hanzogui imports) so unit tests can exercise the row-derivation
// and the proto-payload decoder without spinning the hanzogui
// no Gui imports) so unit tests can exercise the row-derivation
// and the proto-payload decoder without spinning the gui
// provider.
//
// EventAttributeTable.tsx imports from here for the actual rendering;
// the React component layers a Hanzogui table + EventLink + PayloadDecoder
// the React component layers a Gui table + EventLink + PayloadDecoder
// on top of these rows.
import type { HistoryEvent } from '../../lib/types'
@@ -167,8 +167,8 @@ function EncodingSelect({
onChange: (v: PayloadEncoding) => void
disabled?: boolean
}) {
// hanzogui has no Select primitive yet (see WorkflowSearchBar etc.);
// a native <select> nested inside a hanzogui XStack styles cleanly
// gui has no Select primitive yet (see WorkflowSearchBar etc.);
// a native <select> nested inside a gui XStack styles cleanly
// enough and stays a11y-friendly without extra deps.
return (
<select
@@ -1,7 +1,7 @@
// CronEditor — 5-field standard cron + 6-field with seconds. Live
// describes the cron via `describeCron` and previews the next 5 fire
// times via `nextCronAfter`. Validation is pure so it can be unit-
// tested without rendering hanzogui primitives.
// tested without rendering gui primitives.
import { useMemo } from 'react'
import { Button, Input, Text, XStack, YStack } from 'hanzogui'
+4 -4
View File
@@ -1,4 +1,4 @@
// Entry point. Wires HanzoguiProvider, BrowserRouter, and the route
// Entry point. Wires GuiProvider, BrowserRouter, and the route
// tree. Workflows renders edge-to-edge; every other page wraps in
// PageShell for consistent padding.
//
@@ -11,7 +11,7 @@
import React, { Suspense, lazy } from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
import { HanzoguiProvider } from 'hanzogui'
import { GuiProvider } from 'hanzogui'
import { PageShell, Loading } from '@hanzogui/admin'
import config from '../gui.config'
import App from './App'
@@ -149,7 +149,7 @@ const activityTabs = [
ReactDOM.createRoot(root).render(
<React.StrictMode>
<HanzoguiProvider config={config} defaultTheme="dark">
<GuiProvider config={config} defaultTheme="dark">
<BrowserRouter basename="/_/tasks">
<Suspense fallback={<Fallback />}>
<Routes>
@@ -360,6 +360,6 @@ ReactDOM.createRoot(root).render(
</Routes>
</Suspense>
</BrowserRouter>
</HanzoguiProvider>
</GuiProvider>
</React.StrictMode>,
)
+1 -1
View File
@@ -34,7 +34,7 @@ if (typeof window !== 'undefined' && typeof window.matchMedia !== 'function') {
}),
})
}
// ResizeObserver is also missing under jsdom — Hanzogui layout helpers poke it.
// ResizeObserver is also missing under jsdom — Gui layout helpers poke it.
if (typeof globalThis.ResizeObserver === 'undefined') {
;(globalThis as { ResizeObserver?: unknown }).ResizeObserver = class {
observe() {}
+15 -15
View File
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite'
import path from 'node:path'
import react from '@vitejs/plugin-react'
import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
import { guiPlugin } from '@hanzogui/vite-plugin'
// Hanzo Tasks admin app.
//
@@ -9,7 +9,7 @@ import { hanzoguiPlugin } from '@hanzogui/vite-plugin'
// @hanzogui/core + @hanzo/admin all resolve cleanly — @hanzo/gui from
// npm, @hanzo/admin via workspace:*. That's what lets the static
// extractor's bundled-config worker re-resolve those imports when it
// copies hanzogui.config.ts into the .hanzogui temp dir.
// copies gui.config.ts into the .gui temp dir.
//
// Build target: a Vite SPA served from tasks.hanzo.ai. The base path
// /_/tasks/ matches what tasksd's Go server strips before delegating
@@ -23,10 +23,10 @@ const APP_VERSION = process.env.VITE_APP_VERSION ?? '2.49.0'
export default defineConfig({
plugins: [
hanzoguiPlugin({
components: ['hanzogui'],
guiPlugin({
components: ['gui'],
// Absolute path — keeps the extractor from getting confused
// when it copies the config into a `.hanzogui/` temp dir and
// when it copies the config into a `.gui/` temp dir and
// tries to re-resolve workspace deps from there.
config: path.resolve(__dirname, 'gui.config.ts'),
// Extraction is required for production. If the temp-dir
@@ -44,8 +44,8 @@ export default defineConfig({
process.env.VITE_API_PREFIX ?? '/v1/tasks',
),
__DEV__: process.env.NODE_ENV !== 'production' ? 'true' : 'false',
'process.env.HANZOGUI_TARGET': JSON.stringify('web'),
'process.env.HANZOGUI_REACT_19': '"1"',
'process.env.GUI_TARGET': JSON.stringify('web'),
'process.env.GUI_REACT_19': '"1"',
},
resolve: {
alias: {
@@ -63,15 +63,15 @@ export default defineConfig({
// @hanzogui/* primitives from THIS app's node_modules, not from
// a sibling workspace's nested copy. Without dedupe the dev server
// serves two parallel module graphs (one for admin-tasks, one
// for @hanzo/admin), each with its own HanzoguiProvider context
// for @hanzo/admin), each with its own GuiProvider context
// — children rendered through the @hanzo/admin Sidebar don't see
// the provider mounted in admin-tasks's main.tsx, throw "Can't
// find Hanzogui configuration", page goes blank.
// find Gui configuration", page goes blank.
dedupe: [
'react',
'react-dom',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -79,7 +79,7 @@ export default defineConfig({
],
},
optimizeDeps: {
// Force ALL hanzogui packages through ONE pre-bundled ESM module
// Force ALL gui packages through ONE pre-bundled ESM module
// graph. Without this, the @hanzo/gui umbrella and direct
// `@hanzogui/core` imports (e.g. via @hanzogui/lucide-icons-2 →
// @hanzogui/helpers-icon → @hanzogui/core's Text) end up as
@@ -93,7 +93,7 @@ export default defineConfig({
'react-dom/client',
'react/jsx-runtime',
'react-native-web',
'hanzogui',
'gui',
'@hanzogui/core',
'@hanzogui/web',
'@hanzogui/themes',
@@ -113,7 +113,7 @@ export default defineConfig({
sourcemap: false,
assetsInlineLimit: 16 * 1024,
target: 'es2020',
// Vendor split — keep React + router + the hanzogui runtime in
// Vendor split — keep React + router + the gui runtime in
// long-lived chunks so per-page lazy chunks stay small.
rollupOptions: {
output: {
@@ -132,10 +132,10 @@ export default defineConfig({
return 'ui-overlay'
}
// Workspace UI lives in pkgs/ui*, resolved via the `source`
// condition. Group it with hanzogui so small primitives don't
// condition. Group it with gui so small primitives don't
// each get their own chunk.
if (
id.includes('node_modules/hanzogui') ||
id.includes('node_modules/gui') ||
id.includes('node_modules/@hanzogui/') ||
id.includes('/pkgs/ui-admin/') ||
id.includes('/pkgs/ui/')
+1 -1
View File
@@ -3,7 +3,7 @@ import react from '@vitejs/plugin-react'
import path from 'node:path'
// Standalone vitest config — we intentionally do NOT extend vite.config.ts
// because the hanzogui static-extractor plugin requires a workspace
// because the gui static-extractor plugin requires a workspace
// gui.config.ts at runtime which is unrelated to test execution. Tests
// only need React JSX support + jsdom.
export default defineConfig({
+4
View File
@@ -0,0 +1,4 @@
{
"config": "./src/gui.config.ts",
"components": ["hanzogui"]
}
-4
View File
@@ -1,4 +0,0 @@
{
"config": "./src/hanzogui.config.ts",
"components": ["hanzogui"]
}
+5 -5
View File
@@ -40,10 +40,10 @@
"access": "public"
},
"scripts": {
"build": "hanzogui-build --skip-types",
"watch": "hanzogui-build --skip-types --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build"
"build": "gui-build --skip-types",
"watch": "gui-build --skip-types --watch",
"clean": "gui-build clean",
"clean:build": "gui-build clean:build"
},
"dependencies": {
"@hanzogui/animate-presence": "workspace:*",
@@ -75,7 +75,7 @@
"@hanzogui/switch": "workspace:*",
"@hanzogui/switch-headless": "workspace:*",
"@hanzogui/tabs": "workspace:*",
"@hanzogui/hanzogui-dev-config": "workspace:*",
"@hanzogui/dev-config": "workspace:*",
"@hanzogui/theme": "workspace:*",
"@hanzogui/toast": "workspace:*",
"hanzogui": "workspace:*"
+1 -1
View File
@@ -12,7 +12,7 @@ import React from 'react'
import { Button } from 'hanzogui'
/**
* Menu Demo using Hanzogui Menu component.
* Menu Demo using Gui Menu component.
* Automatically uses native menus on iOS/Android, web menus on web.
* No configuration needed - it just works!
*/
+1 -1
View File
@@ -3,7 +3,7 @@ import React from 'react'
import type { FontSizeTokens, SelectProps } from 'hanzogui'
import { Adapt, Label, Select, Sheet, Theme, XStack, YStack, getFontSize } from 'hanzogui'
import { LinearGradient } from 'hanzogui/linear-gradient'
import { LinearGradient } from 'gui/linear-gradient'
export function SelectDemo() {
return (
+1 -1
View File
@@ -3,7 +3,7 @@ import { Paragraph, Separator, XStack, YStack } from 'hanzogui'
export function SeparatorDemo() {
return (
<YStack width="100%" maxW={300} mx={16}>
<Paragraph fontWeight="800">Hanzogui</Paragraph>
<Paragraph fontWeight="800">Gui</Paragraph>
<Paragraph>A cross-platform component library.</Paragraph>
<Separator my={15} />
<XStack height={20} items="center">
@@ -1,12 +1,12 @@
import { config } from '@hanzogui/hanzogui-dev-config'
import { createHanzogui } from 'hanzogui'
import { config } from '@hanzogui/dev-config'
import { createGui } from 'hanzogui'
const tamaConf = createHanzogui(config)
const tamaConf = createGui(config)
export type Conf = typeof tamaConf
declare module 'hanzogui' {
interface HanzoguiCustomConfig extends Conf {}
interface GuiCustomConfig extends Conf {}
interface TypeOverride {
groupNames(): 'card' | 'takeoutBody' | 'content' | 'item'
+2 -2
View File
@@ -1,5 +1,5 @@
// Include hanzogui config types for proper type checking
import type {} from './hanzogui.config'
// Include gui config types for proper type checking
import type {} from './gui.config'
export * from './AccordionDemo'
export * from './AddThemeDemo'
+1 -1
View File
@@ -19,7 +19,7 @@
"path": "../../pkgs/packages/lucide-icons"
},
{
"path": "../../pkgs/packages/hanzogui-dev-config"
"path": "../../pkgs/packages/gui-dev-config"
},
{
"path": "../../pkgs/ui/avatar"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ import React from 'react'
import type { LoaderProps } from 'one'
import { useLoader } from 'one'
import { HeadInfo } from '~/components/HeadInfo'
import { HanzoguiExamples } from '~/components/HanzoguiExamples'
import { GuiExamples } from '~/components/GuiExamples'
import { BlogSlugPage } from '~/features/site/blog/BlogSlugPage'
import { getOgUrl } from '~/features/site/getOgUrl'
@@ -73,9 +73,9 @@ export default function BlogSlug() {
}}
/>
<HanzoguiExamples.Provider value={data.examples}>
<GuiExamples.Provider value={data.examples}>
<BlogSlugPage Component={Component} {...data} />
</HanzoguiExamples.Provider>
</GuiExamples.Provider>
</>
)
}
@@ -2,7 +2,7 @@ import { useLoader } from 'one'
import { H2, Paragraph, Spacer, XStack } from 'hanzogui'
import { ContainerLarge } from '~/components/Containers'
import { Link } from '~/components/Link'
import { HanzoguiCard } from '~/components/HanzoguiCard'
import { GuiCard } from '~/components/GuiCard'
import { authors } from '~/data/authors'
import { HeadInfo } from '~/components/HeadInfo'
@@ -33,7 +33,7 @@ export default function Blog() {
<XStack flexWrap="wrap" gap="$4" $md={{ flexDirection: 'column' }}>
{frontmatters.map((frontmatter) => (
<Link asChild key={frontmatter.title} href={`/blog/${frontmatter.slug}`}>
<HanzoguiCard
<GuiCard
title={frontmatter.title}
render="a"
width="calc(50% - var(--space-2))"
@@ -63,7 +63,7 @@ export default function Blog() {
}
>
{frontmatter.description}
</HanzoguiCard>
</GuiCard>
</Link>
))}
</XStack>
@@ -4,7 +4,7 @@ import { useLoader } from 'one'
import { useMemo } from 'react'
import { HeadInfo } from '~/components/HeadInfo'
import { SubTitle, nbspLastWord } from '~/components/SubTitle'
import { HanzoguiExamples } from '~/components/HanzoguiExamples'
import { GuiExamples } from '~/components/GuiExamples'
import { DocsPageFrame } from '~/features/docs/DocsPageFrame'
import { useDocsMenu } from '~/features/docs/useDocsMenu'
import { components } from '~/features/mdx/MDXComponents'
@@ -71,9 +71,9 @@ export default function DocIntroPage() {
<HomeH1>{nbspLastWord(frontmatter.title)}</HomeH1>
<SubTitle>{nbspLastWord(frontmatter.description || '')}</SubTitle>
<ThemeTint>
<HanzoguiExamples.Provider value={examples}>
<GuiExamples.Provider value={examples}>
<Component components={components as any} />
</HanzoguiExamples.Provider>
</GuiExamples.Provider>
</ThemeTint>
</DocsPageFrame>
)
@@ -22,7 +22,7 @@ import { ContainerBento } from '~/components/Containers'
import { HeadInfo } from '~/components/HeadInfo'
import { BentoPageFrame } from '~/features/bento/BentoPageFrame'
import { useBentoStore } from '~/features/bento/BentoStore'
import { DropHanzoguiConfig } from '~/features/bento/DropHanzoguiConfig'
import { DropGuiConfig } from '~/features/bento/DropGuiConfig'
import { useSubscriptionModal } from '~/features/site/purchase/useSubscriptionModal'
export const generateStaticParams = async () => {
@@ -179,7 +179,7 @@ export const DetailHeader = (props: { children: string }) => {
$sm={{ y: 0, mt: 0, mb: 40, items: 'center' }}
>
<XStack gap="$4">
<DropHanzoguiConfig />
<DropGuiConfig />
<Button
icon={bentoStore.disableTint ? Paintbrush : CircleDashed}
+1 -1
View File
@@ -26,7 +26,7 @@ export async function loader() {
return getCompilationExamples()
}
export default function HanzoguiHomePage() {
export default function GuiHomePage() {
const { compilationExamples, animationCode } = useLoader(loader)
useEffect(() => {
+1 -1
View File
@@ -1,6 +1,6 @@
import '@hanzogui/core/reset.css'
import '~/app.css'
import '~/hanzogui.generated.css'
import '~/gui.generated.css'
import { LoadProgressBar, Slot } from 'one'
import { setupPopper } from 'hanzogui'
@@ -49,8 +49,8 @@ export default apiRoute(async (req) => {
const supportSubscriptions = allUserSubscriptions.filter((sub) =>
sub.subscription_items?.some(
(item) =>
item.price?.product?.name === ProductName.HanzoguiSupport ||
item.price?.product?.name === ProductName.HanzoguiChat
item.price?.product?.name === ProductName.GuiSupport ||
item.price?.product?.name === ProductName.GuiChat
)
)
@@ -69,14 +69,14 @@ export default apiRoute(async (req) => {
supportSubscriptions.forEach((supportSub) => {
const supportItems = supportSub.subscription_items?.filter(
(item) =>
item.price?.product?.name === ProductName.HanzoguiSupport ||
item.price?.product?.name === ProductName.HanzoguiChat
item.price?.product?.name === ProductName.GuiSupport ||
item.price?.product?.name === ProductName.GuiChat
)
if (supportItems?.length) {
// Check for chat support (base 2 invites)
const chatItem = supportItems.find(
(item) => item.price?.product?.name === ProductName.HanzoguiChat
(item) => item.price?.product?.name === ProductName.GuiChat
)
if (chatItem) {
hasChat = true
@@ -85,7 +85,7 @@ export default apiRoute(async (req) => {
// Check for support tiers (4 additional invites per tier)
const tierItem = supportItems.find(
(item) => item.price?.product?.name === ProductName.HanzoguiSupport
(item) => item.price?.product?.name === ProductName.GuiSupport
)
if (tierItem) {
// Use subscription's quantity field to determine tier level
@@ -25,7 +25,7 @@ export default apiRoute(async (req) => {
if (data?.id) {
return Response.redirect(
`https://github.com/apps/hanzoguibot/installations/new?state=${data.id}`
`https://github.com/apps/guibot/installations/new?state=${data.id}`
)
}
+5 -5
View File
@@ -10,28 +10,28 @@ export default apiRoute(async () => {
supabaseAdmin
.from('products')
.select('*, prices(*)')
.eq('name', ProductName.HanzoguiPro)
.eq('name', ProductName.GuiPro)
.single(),
supabaseAdmin
.from('products')
.select('*, prices(*)')
.eq('name', ProductName.HanzoguiSupport)
.eq('name', ProductName.GuiSupport)
.single(),
// V2 Products
supabaseAdmin
.from('products')
.select('*, prices(*)')
.eq('name', ProductName.HanzoguiProV2)
.eq('name', ProductName.GuiProV2)
.single(),
supabaseAdmin
.from('products')
.select('*, prices(*)')
.eq('name', ProductName.HanzoguiSupportDirect)
.eq('name', ProductName.GuiSupportDirect)
.single(),
supabaseAdmin
.from('products')
.select('*, prices(*)')
.eq('name', ProductName.HanzoguiSupportSponsor)
.eq('name', ProductName.GuiSupportSponsor)
.single(),
])
+2 -2
View File
@@ -21,8 +21,8 @@ type TestUserType = 'new' | 'v1' | 'v2'
*
* Creates/resets a test user with the specified subscription state:
* - new: clean user with no subscriptions
* - v1: user with V1 HanzoguiPro subscription (should see upgrade card)
* - v2: user with V2 HanzoguiProV2 subscription (normal account state)
* - v1: user with V1 GuiPro subscription (should see upgrade card)
* - v2: user with V2 GuiProV2 subscription (normal account state)
*
* Sets session cookies and redirects to /account
*/
@@ -93,7 +93,7 @@ export async function GET(req: Request) {
}}
>
<div style={{ width: '40px', height: '40px', opacity: 0.9, display: 'flex' }}>
<HanzoguiLogo size={40} />
<GuiLogo size={40} />
</div>
<div
style={{
@@ -329,7 +329,7 @@ export async function GET(req: Request) {
}}
>
<div style={{ width: '40px', height: '40px', opacity: 0.9, display: 'flex' }}>
<HanzoguiLogo size={40} />
<GuiLogo size={40} />
</div>
<div
style={{
@@ -793,7 +793,7 @@ type Theme = {
is_cached: boolean | null
}
const HanzoguiLogo = ({ size = 64 }: { size?: number }) => (
const GuiLogo = ({ size = 64 }: { size?: number }) => (
<svg
width={size}
height={size}
+1 -1
View File
@@ -27,7 +27,7 @@ export async function loader() {
return getCompilationExamples()
}
export default function HanzoguiHomePage() {
export default function GuiHomePage() {
const { compilationExamples, animationCode } = useLoader(loader)
useEffect(() => {
+4 -4
View File
@@ -1,5 +1,5 @@
import { createContext, useContext, useEffect, useState } from 'react'
import type { HanzoguiElement, ViewProps } from 'hanzogui'
import type { GuiElement, ViewProps } from 'hanzogui'
import { isWeb, View, withStaticProperties } from 'hanzogui'
// 3D Card Context - shared hover state between container and items
@@ -34,8 +34,8 @@ const Card3DContainer = ({
centered = false,
...rest
}: Card3DContainerProps) => {
const [_containerRef, setContainerRef] = useState<HanzoguiElement | null>(null)
const [perspectiveRef, setPerspectiveRef] = useState<HanzoguiElement | null>(null)
const [_containerRef, setContainerRef] = useState<GuiElement | null>(null)
const [perspectiveRef, setPerspectiveRef] = useState<GuiElement | null>(null)
const [isMouseEntered, setIsMouseEntered] = useState(false)
const containerRef = _containerRef as unknown as HTMLDivElement
@@ -114,7 +114,7 @@ export type Card3DItemProps = {
const Card3DItem = View.styleable<Card3DItemProps>(
({ translateZ = 0, children, ...rest }, forwardedRef) => {
const [ref, setRef] = useState<HanzoguiElement | null>(null)
const [ref, setRef] = useState<GuiElement | null>(null)
const [isMouseEntered] = useMouseEnter()
useEffect(() => {
@@ -2,7 +2,7 @@ import { H3, Paragraph, XStack } from 'hanzogui'
import { Card } from './Card'
export function HanzoguiCard({ children, title, subTitle, ...props }) {
export function GuiCard({ children, title, subTitle, ...props }) {
return (
<Card
p="$4"
@@ -4,13 +4,13 @@ import { Spacer } from 'hanzogui'
import { HeroContainer } from '~/features/docs/HeroContainer'
import { HomeExamples } from '~/features/site/home/HomeExamples'
export const HanzoguiExamples = createContext<ReturnType<
export const GuiExamples = createContext<ReturnType<
typeof getCompilationExamples
> | null>(null)
export function HanzoguiExamplesCode() {
export function GuiExamplesCode() {
try {
const examples = useContext(HanzoguiExamples)
const examples = useContext(GuiExamples)
return (
<HeroContainer noScroll noPad>
<Spacer />
+7 -7
View File
@@ -1,7 +1,7 @@
import { InitialPathContext, SeasonProvider } from '@hanzogui/logo'
import { SchemeProvider, useUserScheme } from '@vxrn/color-scheme'
import { HanzoguiProvider } from 'hanzogui'
import tamaConf from '~/hanzogui.config'
import { GuiProvider } from 'hanzogui'
import tamaConf from '~/gui.config'
import { PostHogProvider } from '~/features/posthog/PostHogProvider'
import { SearchProvider } from '~/features/site/search/SearchProvider'
import { ToastProvider } from '~/features/studio/ToastProvider'
@@ -12,9 +12,9 @@ export const Providers = (props: { children: any }) => {
<SchemeProvider>
<PostHogProvider>
<SeasonProvider>
<WebsiteHanzoguiProvider>
<WebsiteGuiProvider>
<SearchProvider>{props.children}</SearchProvider>
</WebsiteHanzoguiProvider>
</WebsiteGuiProvider>
</SeasonProvider>
</PostHogProvider>
</SchemeProvider>
@@ -22,12 +22,12 @@ export const Providers = (props: { children: any }) => {
)
}
function WebsiteHanzoguiProvider(props: { children: any }) {
function WebsiteGuiProvider(props: { children: any }) {
const { value } = useUserScheme()
return (
<HanzoguiProvider disableInjectCSS defaultTheme={value} config={tamaConf}>
<GuiProvider disableInjectCSS defaultTheme={value} config={tamaConf}>
<ToastProvider>{props.children}</ToastProvider>
</HanzoguiProvider>
</GuiProvider>
)
}
+20 -20
View File
@@ -1,13 +1,13 @@
import { LinearGradient } from '@hanzogui/linear-gradient'
import { ChevronDown, ChevronUp } from '@hanzogui/lucide-icons-2'
import type { SelectItemProps, SelectProps, SelectTriggerProps } from 'hanzogui'
import { Select as HanzoguiSelect, YStack, useProps, withStaticProperties } from 'hanzogui'
import { Select as GuiSelect, YStack, useProps, withStaticProperties } from 'hanzogui'
export const SelectItem = ({ children, index, ...props }: SelectItemProps) => {
return (
<HanzoguiSelect.Item index={index + 1} borderColor="transparent" {...props}>
<HanzoguiSelect.ItemText>{children}</HanzoguiSelect.ItemText>
</HanzoguiSelect.Item>
<GuiSelect.Item index={index + 1} borderColor="transparent" {...props}>
<GuiSelect.ItemText>{children}</GuiSelect.ItemText>
</GuiSelect.Item>
)
}
@@ -49,13 +49,13 @@ const SelectComponent = (
renderValue,
} as SelectProps
return (
<HanzoguiSelect {...selectProps} zIndex={1_000_000}>
<HanzoguiSelect.Trigger iconAfter={ChevronDown} {...selectTriggerProps}>
<HanzoguiSelect.Value placeholder={placeholder} />
</HanzoguiSelect.Trigger>
<GuiSelect {...selectProps} zIndex={1_000_000}>
<GuiSelect.Trigger iconAfter={ChevronDown} {...selectTriggerProps}>
<GuiSelect.Value placeholder={placeholder} />
</GuiSelect.Trigger>
<HanzoguiSelect.Content>
<HanzoguiSelect.ScrollUpButton
<GuiSelect.Content>
<GuiSelect.ScrollUpButton
items="center"
justify="center"
position="relative"
@@ -72,9 +72,9 @@ const SelectComponent = (
colors={['$background', '$background0']}
rounded="$4"
/>
</HanzoguiSelect.ScrollUpButton>
</GuiSelect.ScrollUpButton>
<HanzoguiSelect.Viewport
<GuiSelect.Viewport
opacity={1}
y={0}
enterStyle={{
@@ -91,9 +91,9 @@ const SelectComponent = (
borderColor="$borderColor"
>
{children}
</HanzoguiSelect.Viewport>
</GuiSelect.Viewport>
<HanzoguiSelect.ScrollDownButton
<GuiSelect.ScrollDownButton
items="center"
justify="center"
position="relative"
@@ -110,15 +110,15 @@ const SelectComponent = (
colors={['$background0', '$background']}
rounded="$4"
/>
</HanzoguiSelect.ScrollDownButton>
</HanzoguiSelect.Content>
</HanzoguiSelect>
</GuiSelect.ScrollDownButton>
</GuiSelect.Content>
</GuiSelect>
)
}
export const Select = withStaticProperties(SelectComponent, {
Item: SelectItem,
ItemText: HanzoguiSelect.ItemText,
Group: HanzoguiSelect.Group,
Label: HanzoguiSelect.Label,
ItemText: GuiSelect.ItemText,
Group: GuiSelect.Group,
Label: GuiSelect.Label,
})
+4 -4
View File
@@ -1,10 +1,10 @@
import { memo } from 'react'
import { type SwitchProps, Switch as HanzoguiSwitch, Theme } from 'hanzogui'
import { type SwitchProps, Switch as GuiSwitch, Theme } from 'hanzogui'
export const Switch = memo((props: SwitchProps) => {
return (
<Theme name={props.checked ? 'accent' : 'gray'}>
<HanzoguiSwitch
<GuiSwitch
transition={[
'bouncy',
{
@@ -19,7 +19,7 @@ export const Switch = memo((props: SwitchProps) => {
size="$3"
{...props}
>
<HanzoguiSwitch.Thumb
<GuiSwitch.Thumb
transition={[
'quickest',
{
@@ -34,7 +34,7 @@ export const Switch = memo((props: SwitchProps) => {
alignItems="center"
justifyContent="center"
/>
</HanzoguiSwitch>
</GuiSwitch>
</Theme>
)
})
@@ -14,7 +14,7 @@ import {
import { useClipboard } from './hooks'
import { useReplaceTokens } from './hooks/useReplaceTokens'
import useTokenMapper from './hooks/useTokenMapper'
import { useUserHanzoguiConfig } from './hooks/useUserHanzoguiConfig'
import { useUserGuiConfig } from './hooks/useUserGuiConfig'
interface Props {
code: string
isLoading?: boolean
@@ -179,9 +179,9 @@ function CopyCodeButton({ onCopy, hasCopied, oneTabLayout = false }) {
}
function CustomizationEnabledBanner() {
const userHanzoguiConfig = useUserHanzoguiConfig()
const userGuiConfig = useUserGuiConfig()
if (!userHanzoguiConfig) return null
if (!userGuiConfig) return null
return (
<YStack mt="$3" ml="$3">
<Theme name="green">
@@ -2,19 +2,19 @@ import { useState, useEffect, useMemo } from 'react'
import type { Tokens } from '@hanzogui/core'
import { getTokens } from '@hanzogui/core'
import { useUserHanzoguiConfig } from './useUserHanzoguiConfig'
import { useUserGuiConfig } from './useUserGuiConfig'
type MergedToken = Tokens & { userMatch: Tokens }
const useTokenMapper = () => {
const userHanzoguiConfig = useUserHanzoguiConfig()
const userGuiConfig = useUserGuiConfig()
const [mappedTokens, setMappedTokens] = useState<Tokens | null>(null)
const bentoTokens = getTokens()
useEffect(() => {
if (bentoTokens && userHanzoguiConfig) {
if (bentoTokens && userGuiConfig) {
try {
const userTokensConfig = JSON.parse(userHanzoguiConfig).guiConfig.tokens
const userTokensConfig = JSON.parse(userGuiConfig).guiConfig.tokens
const mapped = mapBentoTokensToUserTokens(
bentoTokens,
userTokensConfig
@@ -25,14 +25,14 @@ const useTokenMapper = () => {
setMappedTokens(null)
}
}
}, [bentoTokens, userHanzoguiConfig])
}, [bentoTokens, userGuiConfig])
const userTokens = userHanzoguiConfig
const userTokens = userGuiConfig
? (() => {
try {
return JSON.parse(userHanzoguiConfig)?.guiConfig?.tokens
return JSON.parse(userGuiConfig)?.guiConfig?.tokens
} catch (error) {
console.error('Failed to parse user gui config for tokens:', userHanzoguiConfig)
console.error('Failed to parse user gui config for tokens:', userGuiConfig)
return null
}
})()
@@ -0,0 +1,21 @@
import { useState, useEffect } from 'react'
/**
* Retrieves the user's GUI configuration from localStorage as a raw string.
* SSR-safe implementation that doesn't use client-only guards.
* @returns {string | null} userGuiConfig - The user's gui configuration
*/
export const useUserGuiConfig = () => {
const [userGuiConfig, setUserGuiConfig] = useState<string | null>(null)
useEffect(() => {
try {
const stored = localStorage.getItem('userGuiConfig')
setUserGuiConfig(stored || null)
} catch {
// localStorage not available
}
}, [])
return userGuiConfig
}
@@ -1,21 +0,0 @@
import { useState, useEffect } from 'react'
/**
* Retrieves the user's GUI configuration from localStorage as a raw string.
* SSR-safe implementation that doesn't use client-only guards.
* @returns {string | null} userHanzoguiConfig - The user's gui configuration
*/
export const useUserHanzoguiConfig = () => {
const [userHanzoguiConfig, setUserHanzoguiConfig] = useState<string | null>(null)
useEffect(() => {
try {
const stored = localStorage.getItem('userHanzoguiConfig')
setUserHanzoguiConfig(stored || null)
} catch {
// localStorage not available
}
}, [])
return userHanzoguiConfig
}
@@ -136,7 +136,7 @@ In your `webpack.config.js`:
```js
{
loader: 'gui-loader',
loader: 'hanzogui-loader',
options: {
config: './gui.config.ts',
components: ['@ourapp/components', '@hanzo/gui'],
@@ -12,7 +12,7 @@ yarn add -D webpack webpack-cli
Then install the Hanzo GUI plugin:
```bash
yarn add -D gui-loader
yarn add -D hanzogui-loader
```
### Configuration
@@ -23,7 +23,7 @@ Add the plugin to your `webpack.config.js`. If you have a `gui.build.ts`
no options are needed:
```tsx fileName="webpack.config.js"
const { GuiPlugin } = require('gui-loader')
const { GuiPlugin } = require('hanzogui-loader')
// reads from gui.build.ts automatically
config.plugins.push(new GuiPlugin())
@@ -32,7 +32,7 @@ config.plugins.push(new GuiPlugin())
Or pass options inline:
```tsx fileName="webpack.config.js"
const { GuiPlugin } = require('gui-loader')
const { GuiPlugin } = require('hanzogui-loader')
config.plugins.push(
new GuiPlugin({
@@ -81,12 +81,12 @@ We have a full example of a plain Webpack or Vite setup in the simple starter
accessible through `npm create hanzo-gui@latest`, which shows a complete
configuration with more detail.
Add `gui-loader` and set up your `webpack.config.js`.
Add `hanzogui-loader` and set up your `webpack.config.js`.
You can set it up more manually like so:
```js
const { shouldExclude } = require('gui-loader')
const { shouldExclude } = require('hanzogui-loader')
const guiOptions = {
config: './gui.config.ts',
@@ -125,7 +125,7 @@ module.exports = {
},
{
loader: 'gui-loader',
loader: 'hanzogui-loader',
options: guiOptions,
},
],
@@ -139,7 +139,7 @@ Or you can use the GuiPlugin which automates some of this setup for you.
If you have a `gui.build.ts`, you can pass no options:
```tsx
const { GuiPlugin } = require('gui-loader')
const { GuiPlugin } = require('hanzogui-loader')
module.exports = {
plugins: [
@@ -152,7 +152,7 @@ module.exports = {
Or pass options inline to override:
```tsx
const { GuiPlugin } = require('gui-loader')
const { GuiPlugin } = require('hanzogui-loader')
module.exports = {
plugins: [
@@ -14,9 +14,9 @@ import { Features } from '~/components/Features'
import { Code, CodeInline } from '~/components/Code'
import { useLocalStorageWatcher } from '~/hooks/useLocalStorageWatcher'
export const DropHanzoguiConfig = () => {
export const DropGuiConfig = () => {
const [show, setShow] = useState(false)
const config = useLocalStorageWatcher('userHanzoguiConfig', '')
const config = useLocalStorageWatcher('userGuiConfig', '')
const [dragging, setDragging] = useState(false)
useEffect(() => {
@@ -172,7 +172,7 @@ export const DropHanzoguiConfig = () => {
{!config.storageItem && (
<>
<Paragraph size="$4">
Drag and drop your <CodeInline>.hanzoai/hanzogui.config.json</CodeInline>{' '}
Drag and drop your <CodeInline>.hanzoai/gui.config.json</CodeInline>{' '}
here to customize the code we generate to your design system!
</Paragraph>
<Paragraph size="$4">
@@ -180,13 +180,13 @@ export const DropHanzoguiConfig = () => {
automatically. If not, use the CLI.
</Paragraph>
<Paragraph size="$4">
But first, set up a <CodeInline>hanzogui.build.ts</CodeInline>:
But first, set up a <CodeInline>gui.build.ts</CodeInline>:
</Paragraph>
<Features
items={[
<React.Fragment key="">
Create a <CodeInline>hanzogui.build.ts</CodeInline> at the root of
Create a <CodeInline>gui.build.ts</CodeInline> at the root of
your app and move your build configuration into it as a default
export. All of the bundler plugins load from this file on
startup.
@@ -196,7 +196,7 @@ export const DropHanzoguiConfig = () => {
<Code>npx @hanzogui/cli generate</Code>
</React.Fragment>,
<React.Fragment key="">
Drop the generated <Code>.hanzoai/hanzogui.config.json</Code> on this
Drop the generated <Code>.hanzoai/gui.config.json</Code> on this
window.
</React.Fragment>,
]}
@@ -21,11 +21,11 @@ export const hasProAccess = async (userId: string) => {
// check for current subscription-based access (active or trialing)
const validProProducts = [
ProductName.HanzoguiPro,
ProductName.HanzoguiProV2,
ProductName.HanzoguiProV2Upgrade,
ProductName.HanzoguiSupportDirect,
ProductName.HanzoguiSupportSponsor,
ProductName.GuiPro,
ProductName.GuiProV2,
ProductName.GuiProV2Upgrade,
ProductName.GuiSupportDirect,
ProductName.GuiSupportSponsor,
]
const hasSubscriptionAccess = subscriptions?.some((subscription) => {
@@ -66,7 +66,7 @@ const hasLegacyAccess = async (userId: string) => {
// check for direct Bento product ownership (legacy)
const hasDirectBentoAccess = result.data.some(
(ownership) => ownership.prices?.products?.name === ProductName.HanzoguiBento
(ownership) => ownership.prices?.products?.name === ProductName.GuiBento
)
if (hasDirectBentoAccess) {
@@ -118,7 +118,7 @@ export const docsRoutes = [
{
section: 'ui',
// title: 'hanzogui',
// title: 'gui',
pages: [
{ title: 'Install', route: '/ui/intro' },
{ title: 'Stacks', route: '/ui/stacks' },

Some files were not shown because too many files have changed in this diff Show More