195 Commits
Author SHA1 Message Date
zeekayandHanzo Dev acdf9136fa A section path may carry no whitespace, control character or backslash
A browser strips a tab out of a URL before it parses it, so /<tab>/host arrived
as //host: another site, drawn as this app's own section.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-25 01:59:12 -07:00
zeekayandHanzo Dev ba57d99f89 The frame draws only sound doors, mounts the scope once, and acts only on plain ids
A section points at a path of the app or an https address on another host;
a protocol-relative, script or bare address is not drawn, and the home mark
falls back to the app's root. The scope renders in exactly one place, the bar
or the phone's sheet, so there is one selection and one set of reads. A
notification is marked read or archived only when its id is a single plain
segment, and a reason the server names is looked up in a Map. The scope's
keys are per workspace, not per person, and the README says the host clears
them when the person changes. `.auth/` is ignored.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-25 01:52:44 -07:00
zeekayandHanzo Dev faed55df10 One frame for the signed-in app: Frame, Account, Scope, Notifications
hanzo.ai and the Hanzo App each drew their own copy of the workspace shell,
and the copies had drifted. The frame is here now, once: the rail of
sections, the sidebar with the workspace switcher at its top and the account
at its foot, the bar, the pane, and the column beside it that a room fills
through Beside.

The rail is the sidebar shut on a laptop (an explicit toggle kept per device,
never hover) and the tab bar on a phone. The far-left strip that stands beside
an open sidebar is opt-in through `strip`, off by default. The account menu is
Profile, Notifications, Appearance, Security, Sign out, and carries no
balance. Scope puts project and environment in the bar, kept per workspace
and never carried across one. Notifications reads the reader's own through
the host's call; the package holds no credential.

The frame follows the host's theme, so its inks are the host's own rungs
(FRAME in theme.ts). Its layout lives in shellStyles.ts beside the chrome's,
injected by an insertion effect so the grid is in place before first paint.

@hanzogui/shell 8.3.19

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-25 01:37:19 -07:00
zooqueen 6f965b7885 The menu plane is opaque, because a plane inside the filtered bar cannot blur the page
Every plane hangs inside the header, and the header carries backdrop-filter,
which makes it a backdrop root: a descendant's own blur samples only what the
bar paints, never the page. So the 72% glass plane showed the hero straight
through the menu in Chromium and WebKit alike. The plane is the opaque panel
now, the bar wears that same ground while a plane or the sheet hangs from it,
and the veil dims deep enough to recede without its blur. The scrolled bar is
still glass, where the blur is real. No API change.

@hanzogui/shell 8.3.18
2026-09-24 16:45:24 -07:00
zooqueenandHanzo Dev 31ad1f039e Team is its own repo now
apps/team moved to hanzo-apps/team with its history, and builds there
against the published @hanzo/gui. It leaves the workspace list, the
lockfile, and the Written-at-Hanzo list in every NOTICE (ten names
become nine).


Co-authored-by: Hanzo Dev <[email protected]>
2026-09-23 15:53:45 -07:00
zeekayandHanzo Dev f606295c76 Name the legal center in the footer's legal bar
The bar linked Privacy, Terms and Cookies. The Acceptable Use Policy, the
Data Processing Addendum and the subprocessor register — what a procurement
review asks for first — were reachable only from inside another document.
hanzo.ai/legal indexes all of them; the bar now names it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-23 01:48:01 -07:00
zeekayandHanzo Dev c0da5afbca Format the five manifests the check rejects
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 23:48:04 -07:00
zeekayandHanzo Dev de1199a687 Read one menu column at a time, two by two when narrow
Hovering a column lights it and steps the others back, and below the
rail's width the four sections are peers rather than one tall column
with three stubs under it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 23:13:16 -07:00
zeekay ab754ba686 Every published package carries the license it is under
151 packages of Tamagui-derived code are on npm with no license text in
them. Checked four tarballs at 8.3.5 — @hanzogui/core, @hanzogui/web,
@hanzogui/shell and @hanzo/gui — and not one contains a LICENSE file.

MIT asks for one thing: "The above copyright notice and this permission
notice shall be included in all copies or substantial portions of the
Software." Shipping the code without it does not meet that.

The cause is mechanical rather than deliberate. npm includes a LICENSE
that sits in the package directory, and ours sits at the monorepo root,
where it reaches no tarball. So the license is now in each of the 153
publishable packages, and NOTICE beside it — that one npm will not take on
its own, so 152 manifests name it in `files`.

Verified by dry-run pack: 1.3kB LICENSE, 2.8kB NOTICE.

Already-published tarballs are immutable, so this corrects on the next
publish and not before.
2026-09-07 23:06:05 -07:00
zeekayandHanzo Dev 954d41e603 Retire Cloud and Team as products of their own
The platform is what they were, so the menus name it once and the column
under it lists what the platform actually offers.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 22:57:40 -07:00
zeekayandHanzo Dev e233a1e78f Let the Platform column name what the platform offers
Dev and Platform are the door, not entries beside the things behind it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 22:47:53 -07:00
zeekayandHanzo Dev 6b0765cbda @hanzogui/shell 8.3.14
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 22:44:01 -07:00
zeekayandHanzo Dev 89d2f40176 Let the platform stand for what it runs
Cloud and Team are what the platform does rather than products beside
it, so one name carries all three and one door opens the console.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 22:41:40 -07:00
zooqueen fe3e8a3417 shell: the wordmark sits inside the gutter, not on it
The brand pill pads by 12 and handed all 12 back, which put the NAME itself
exactly on the page's column. That is right for body text and wrong for a
wordmark: set in bold beside the window's edge it reads as flush, and the
gutter looks like it was forgotten.

Four of the twelve are kept. The lit pill still grows outward into the
gutter, and the name now sits a hair inside the column instead of on it.
2026-09-07 10:05:39 -07:00
zeekay 2de0604a52 v8.3.5 2026-09-07 02:06:21 -07:00
zeekay 2510c51f33 Let the shell tests read the bar and the estate as they are
The bar and its drape spread the glass recipe now, and the public estate
names eight doors; both suites still asserted the earlier shape.
2026-09-07 01:49:59 -07:00
zeekay 3eed379d13 Format the shell registry and settle the lockfile 2026-09-07 01:42:06 -07:00
zooqueen e5ff6f0228 shell: the bar and its plane are one glass — 8.3.13
An open menu is a layer over the page: the plane wears GLASS, the grounded bar
wears the same, so from the top of the screen to the bottom of the menu there is
one ground, one blur and no edge.
2026-09-06 21:32:07 -07:00
zooqueen 5df897d849 shell: eight doors, named as the products are — 8.3.12
App, Bot, CLI, Cloud, Dev, IDE, Platform, Team, each with the line its product
page says under the name. Chat and Base stay products and leave the estate
menu. Every console address is platform.hanzo.ai.
2026-09-06 21:20:56 -07:00
zooqueen 9f5ea05ef6 shell: the console surface lives at platform.hanzo.ai — 8.3.11
The surface record names the host a reader is sent to, and that host is
platform.hanzo.ai. 8.3.11 carries the built dist beside the source.
2026-09-06 21:14:41 -07:00
zooqueen ede5a99ad0 shell: the console is platform.hanzo.ai
Every door that opened console.hanzo.ai opens platform.hanzo.ai — the same
console, simplified for the people who use it — and the menu row wears the
product's name, Hanzo Platform.
2026-09-06 21:13:32 -07:00
zooqueen 8698edcdf5 shell: the estate menu names the seven products, in order
App, Bot, CLI, Dev, IDE, Platform, Team — then Cloud and Chat. CLI and Platform
become flagship products (hanzo.ai/cli and platform.hanzo.ai both serve), and
Team is released rather than beta, so a signed-out reader meets all seven.

The order is stated once, where the menu derives it, so the product table stays
a table of what exists and a new product sorts to the end until it is ranked.
2026-09-06 21:12:09 -07:00
zooqueen 72fa7aed30 The footer mark closes the row, and the brand says it opens
The bottom bar reads left to right as the page does: whose it is, what
governs it, then the mark closing the column.

The brand wears the chevron every other trigger in the bar wears. It was
the one control that opens a menu and did not say so, so a reader looking
for the products read past it.
2026-09-06 21:10:44 -07:00
zeekay b424fd5871 v8.3.4 2026-09-06 18:54:23 -07:00
zeekay c4074a9dd0 v8.3.3 2026-09-06 13:48:41 -07:00
zeekay c183da5389 Drop webpack from the stack
The loader and the Next plugin only existed to drive webpack; Next runs
on Turbopack and Vite has its own plugin. kitchen-sink and the
integration app serve through vite, the optimizer suite drops the
webpack name, and its fixture packages join the workspace so a fresh
checkout links @my/ui.
2026-09-06 08:17:57 -07:00
zeekay 5a07cee3b1 v8.3.2 2026-09-05 03:11:37 -07:00
zeekayandHanzo Dev dab83dc050 Run the optimizer's native pass under Node again
Node's require never selects a package's react-native condition and
cannot load an ES module whose sources say a bare require, so the
extractor resolves that entry itself and translates such a file to
CommonJS as it loads. Directories are walked with the filesystem's
glob, negative numbers become AST through valueToNode, the swallowed
load error is named under DEBUG, and the optimize fixture is its
source again with the suite restoring it after each run.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-05 02:00:02 -07:00
zeekayandHanzo Dev af24fc040a Emit the native build as CommonJS
Native sources say a bare require, which Metro provides and an ES
module cannot; marking dist/native CommonJS like dist/cjs lets Node
load it as written, so the optimizer's native pass runs again. The
.cjs sibling answers there too, the CLI imports its commands, the
loader names its css file by the emitted name, and the extractor
tolerates a dependency whose tsconfig extends a preset it lacks.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-05 00:14:46 -07:00
zeekayandHanzo Dev 9366f98ade Read the shell's own imports as written in its source tests
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 23:13:19 -07:00
zeekayandHanzo Dev 44a5d08e34 Name every relative import and drop the root-level shims
A relative import without its extension survives the emit unchanged
and nothing but a bundler can load it, and the .cjs and directory
shims at package roots pointed at emits no build produces. The exports
map is the one entry; the worker each emit runs is the worker of its
own kind.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 22:46:29 -07:00
zeekayandHanzo Dev 42bd70986b Ship source, ESM, CommonJS and types from each package
Every published manifest now states the same exports: types, the
native emit where the package builds one, ESM under import and
CommonJS under require, with src, types and dist in files. The nine
packages that read import.meta do so in one here.ts each, with a
here.cjs.ts sibling for the CommonJS emit; the stragglers on bun,
esbuild, plain tsc or hand-written shims build with the runner like
everything else, and the root-level .cjs shims that pointed at emits
no build produces are gone, as is the vite-plugin-cjs mirror.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 21:07:06 -07:00
zeekayandHanzo Dev 391f839385 Load the suites under the ESM emit
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 21:07:04 -07:00
zeekayandHanzo Dev fd796e3eb4 Emit CommonJS for every package
The CJS pass ran only where a manifest named a require entry, so an
ESM-only package could drift into the tree and a package marked
commonjs could carry ESM files. Now every package gets all three emits
from tsgo; a .cjs.ts sibling answers for the one file that needs
import.meta, and the CommonJS output is parsed as a script so a module
that cannot load there fails the build by name.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 21:07:03 -07:00
zeekay 834a904e48 Format with oxfmt 2026-09-04 09:04:51 -07:00
zeekay a06c66ff41 feat(shell): add zoo foundation link to footer 2026-09-04 01:08:10 -07:00
zooqueenandzeekay f16e187783 The two drapes off one bar start at the same x, and a head is one rank
Four defects in the shell's nav, all measured on hanzo.ai.

THE GUTTER RODE A BOX INSIDE THE PLANE, not the plane. A host must
style `[data-hanzo-plane]` to break a full-bleed drape out of its page
rail — hanzo.ai does — so the host's gutter REPLACED the local nav
card's and STACKED on these two. The local card opened its first column
at x=80 at every width; MeetHanzoMenu opened at 121 / 127 / 138 / 152 at
1024 / 1180 / 1440 / 1920. Two menus off one bar, drifting further apart
the wider the window. One gutter now, on the element the host can see.
Both start at 80.

THE BACK ROW WAS CENTRED. `<button>` with display:flex and no
justify-content takes Chrome's UA `button{justify-content:center}`, and
this was the only sheet row not wearing `sheetRow` — which states
space-between and never met it. `textAlign:'left'` was already there and
cannot help: text-align does not place flex items. "‹ Home" moved from
x=346.6 to x=49, which is where Documentation, API Reference, SDKs and
CLI already were.

THE PALETTE THREW AWAY MARKS IT WAS HANDED. `TRY_HANZO_GROUPS` carries a
`glyph` on every row and `PaletteRow` already had an unused `icon` prop;
the rows in between dropped it. Ten rows now wear the same marks the
mega-menu wears — one product, one icon, read from the registry rather
than a second copy. `anyMark` holds the column so glyph-less page rows
keep their title x.

A HEAD WAS THREE RANKS. 13/600/.92 on the drape and the local nav plane,
11/600/dim in the palette, 11/400/.45 in the mobile sheet. One rank now,
on all four, and 10px of air under it rather than 6.

(cherry picked from commit d4a4d6f8ecba353771adc30af1df2ab8d6f0f7e9)
2026-09-03 21:51:23 -07:00
zooqueenandzeekay 2defe71e9d feat(shell): add hideBrandCrumb to OrgHeader
(cherry picked from commit 9ff65d7ed2be3269257127281032a3a74303dc89)
2026-09-03 21:51:23 -07:00
zeekay de489abd1e Resolve every sibling package through node_modules
The project files inherited the root paths map, so a package's typecheck
read its siblings' source instead of their published declarations and
failed on files that were never its own. An ESM-only manifest now names
no dist/cjs path under any condition, the native emit names its renamed
map, and the runner has a test of its own again.
2026-09-03 18:02:50 -07:00
zeekay 3011889b77 Publish shell 8.3.5 with Enso ahead of Models
npm holds 8.3.4 already, published from outside this tree, so the next
number that can ship is 8.3.5.
2026-09-03 17:34:14 -07:00
zeekay de76b04d20 Name Enso before the models it chooses between
In the platform column and the Meet menu, Enso is the product and Models is
the catalogue it draws on, so the product comes first.
2026-09-03 17:32:46 -07:00
zeekay 77e8398deb Build every package with the TypeScript compiler alone
Babel and esbuild were never here for TypeScript. Babel carried the static
optimizing compiler and one plugin that appended extensions to esbuild's
emitted imports; source now names its own extensions and the compiler rewrites
them on emit. A sixty-line runner replaces the tool: an ESM emit with
declarations, a CommonJS emit where a manifest states a require entry, and a
native emit where a .native sibling takes its sibling's name. The compiler
packages keep Babel as their own substrate; nothing else runs over the code.
Eighteen packages still carry type errors the previous tool never checked.
2026-09-03 17:14:57 -07:00
zooqueen f2bb913b52 An avatar is a circle because of style, not because of a class name
UserAvatar named its shape and its crop in `rounded-full object-cover`.
This package ships no stylesheet and its hosts are not all Tailwind, so on
hanzo.ai those two class names resolved to nothing: a photo rendered as a
square and squashed to the box instead of cropped to it. The values are
inline now, which every host honours, and `className` stays the caller's.

Hanzo Base returns to the estate with it. `stage` is what holds a product
back — every surface filters the list through `sees(stage)` — so clearing
the flag took a released product out of the mega-menu and the footer for
everybody, against what stage.test.mjs asserts.
2026-08-30 14:00:22 -07:00
zeekay 4f9f8693e1 Merge commit 'refs/tmp/a' into converge
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-29 20:51:40 -07:00
zeekay 0243d68060 State a version once
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.

Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
2026-08-29 18:13:47 -07:00
zeekay 56977efab8 Chat is a flagship, like every product beside it
Its entry carried no `flagship` flag, so it was never in HANZO_FLAGSHIP — and
the doors come from there. Every Hanzo surface's Try Hanzo menu and every
command palette offered App, Cloud and Dev and said nothing about the product
the estate leads with. Nothing errored; the door was simply absent.

An omission rather than a decision: the note above that list names Team, Bot and
Studio as the ones held back until they are ready, and Chat is neither
unfinished nor unannounced — it carries a `page` on the marketing site and is
the door most readers open the palette to find.
2026-08-29 00:28:49 -07:00
zooqueen 61081bf52a The chrome's ground can follow its ink
A light host flips this chrome's inks and could not flip what they sit on. The
inks are `var(--white-92, …)` — a name, with white only as the fallback — so a
host that defines those names inverts them. The plane under them was the bare
literal #0a0a0a, which no variable reaches, and the menus came out black on
black: measured 1.06:1 with the whole menu present and invisible.

`panel` is now `var(--chrome-panel, #0a0a0a)`, written the way every ink beside
it already was. Undefined still means #0a0a0a, so a host that themes nothing
gets today's chrome unchanged; a host that themes the inks can theme the ground.

The sibling-dimming rule had the same shape and the same fault: it stated
rgba(255,255,255,0.46) flat, with `!important`, so on a light plane the whole
menu went white-on-white the moment a pointer entered and nothing could reach
it. It takes `--white-45`, which is that value to within a rounding step and is
already a name a light host redefines.
2026-08-28 23:20:15 -07:00
zeekay 56fc65d9ce v5 names what it re-exports, so the names survive
@hanzogui/config/v5 starred both @hanzogui/themes/v5 and ./v5-base, and
v5-base re-exports a dozen names it takes from themes/v5 — createThemes,
tokens, the palette helpers, the theme types. ESM calls a doubly-starred name
ambiguous and omits it rather than picking one, so every shared name silently
left the module: `import { tokens } from '@hanzogui/config/v5'` compiled and
resolved to undefined.

It ships as a patch in at least one consumer, which is the wrong home for it —
a fix in a patch file is a fix exactly one app gets, and only until its
overrides drift. So v5 now names the nine things themes/v5 carries that
v5-base does not, and everything they share arrives through v5-base, which is
the module that already curates it.

8.3.1.
2026-08-28 14:23:46 -07:00
zeekay 09144c6131 Name five flagship products, and one mark in the footer
Chat, Base and Studio were flagships, so the footer PRODUCTS column and
the mega-menu listed eight. The five that are sold are App, Bot, Cloud,
Dev and Team; the others keep their pages and their registry entries.

The footer wore the lockup next to the copyright line, which already
sets the name in type, so the row read Hanzo twice.
2026-08-28 13:38:23 -07:00
zeekay 9d44744080 feat(shell): OrgHeader can decline the app launcher (hideLauncher) 2026-08-27 20:03:15 -07:00