One label per runner, spelled <os>-<arch>. The aliases these jobs named
were removed, and a job naming a label no runner carries waits instead of
failing.
Co-authored-by: Hanzo Dev <[email protected]>
Two thousand and twenty-one packages carried more than one spec across this
estate — eslint alone in a hundred and four forms — and a package resolved twice
is two copies at run time, which is how react-hook-form came to report "two
different types with this name" from files nobody had edited. None do now.
The number lives in the catalog: a manifest names the package, the workspace
names the version. Where a manifest cannot reach a catalog it still carries the
one version, because the table is the source either way.
Co-authored-by: Hanzo Dev <[email protected]>
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.
Co-authored-by: Hanzo Dev <[email protected]>
Every dependency on a @hanzo/@luxfi/@zooai package names the same version across
the repo: a catalog entry where pnpm supports one, an exact pin where it does
not, and a range only where a peer genuinely means one.
pnpm itself is pinned too — the estate ran eighteen different versions, five of
them too old to read a catalog.
Co-authored-by: Hanzo Dev <[email protected]>
Tailwind 4 out — the engine import, the `@custom-variant`, and the `@theme
inline` wrapper. The tokens inside it were always plain custom properties and
are untouched; what goes is the thing that was reading them.
Every class attribute now reaches a converter rather than the document: Box for
an element, css for an icon, the component itself for anything from @hanzo/ui.
The body's ground moves into the sheet, since <body> sits outside the provider
and reads no classes.
The library's sheets are imported from the LAYOUT rather than @import-ed from
the app's CSS: a bare package specifier does not resolve in this pipeline and
the failure is silent — the whole file is dropped, so every token goes missing
and the page renders on browser defaults.
Also on the current toolchain: React 19.2.8, Next 16.3.3, TypeScript 7.
Measured at 390px and 1280px: 4/4 page-widths clean, nothing unread.
Co-authored-by: Hanzo Dev <[email protected]>
One family. Font stacks name Zen and fall back to the native faces, tokens
name the role rather than a face, and the packages that used to supply a
face now point at @hanzo/font.
Self-hosted @font-face blocks are removed rather than renamed: rewriting the
family in one would leave a src pointing at a file this repo no longer ships.
@hanzo/font carries the binaries and declares the faces, so the local copies
go with the declaration that used them.
Comments naming a face we no longer use are deleted, not reworded.
Lux Partners Limited is not the entity behind this work. Every place the
old name stood — copyright lines, site footers, brand config, legal and
compliance text — now names the company that actually holds it.
lux.fund is the exception and is not renamed to match: that site belongs
to Lux Assets Management LLC, a different company, and it says so.
Two kinds of line were left for a person rather than rewritten. A dated
news item recording that Lux Partners Limited was established in the Isle
of Man is a historical fact, and renaming it would falsify the record. And
a sentence asserting that the company is domiciled in the Isle of Man is a
claim about a jurisdiction, not a name — an Inc or an LLC is not an Isle
of Man company, so swapping the name there would assert something untrue.
Co-authored-by: Hanzo Dev <[email protected]>
github.com held commits this host lacked, which refuses the mirror push
("fetch first") and stops github receiving anything at all. Merging rather
than overwriting, so the mirror is a fast-forward again and neither side's
work is dropped.
Adds .hanzo/workflows/cicd.yml calling the canonical pipeline and drops the
GitHub-hosted workflows it replaces. Lands here because this is where the repo
is written — git.hanzo.ai is upstream and github.com is its push mirror, so the
same change made on github.com never reaches the runner fleet.
LLM.md is the source and stays the source; CLAUDE.md is a symlink to it, so there is
one file and it cannot drift from itself. What changes is that the link is committed
rather than left for each checkout to recreate.
Left untracked, the doc was conditional on a step outside the repo: a fresh clone had
no CLAUDE.md, nothing loaded LLM.md, and an agent worked here having never read what
this repo already explains. Most of the estate already tracks theirs; this is the rest
agreeing with them.
A Next.js app served at /forum emits /forum/_next/... into index.html while the
image holds /_next/... — the prefix is added by the router, not by the layer. The
check resolved only the literal path, so it failed forum and help on assets that
were in the image all along, and it also asserted that a bare href="/forum" — a
navigation link, not a file — existed on disk.
Now: only references naming a file are checked, and each resolves either
directly or with the leading basePath segment stripped. A genuinely absent
chunk still fails, which was the point of the check.
Co-authored-by: Hanzo Dev <[email protected]>
publish.yml asked for `runs-on: ubuntu-latest`. The git-runner behind
git.hanzo.ai advertises ~28 labels and that is not one of them, so the job was
never picked up here — it is one of 44 jobs sitting in `waiting` for exactly
that label. On GitHub it was equally stuck, because the luxfi org has zero
registered runners. Addressed to a runner that exists in neither place, it was
not a build; it was a queue entry.
Also removed, both GitHub-only assumptions:
- ghcr login via github.actor + secrets.GITHUB_TOKEN. On this forge
GITHUB_TOKEN is minted by git.hanzo.ai and ghcr.io answers `denied: denied`.
GHCR_USER/GHCR_TOKEN are luxfi org-level secrets here.
- cache-from/to: type=gha, which addresses the GitHub Actions cache service.
The v1.x.x bump is untouched: feat/BREAKING/type! to minor, else patch, never
a major. What changes is that the tag push now goes to github.com rather than
to the forge — this repo is a pull-mirror here and refuses receive-pack, so the
old `|| echo "tag push skipped"` had been silently tagging nothing.
Adds the checks node's release.yml learned the hard way: smoke the image before
it is allowed to exist at the registry, prove the pushed manifest resolves, and
stamp revision/ref/source labels. The smoke checks what a static-server image
cannot check itself — index.html exists and every asset it references is really
in the layer — so a hollow build cannot serve a white page with a 200.
Co-authored-by: Hanzo Dev <[email protected]>
point the registry at our verdaccio, which proxies and caches all of npm
alongside our own scoped packages. lockfiles are untouched: npm and pnpm
both honor .npmrc at fetch time, so no re-resolution is needed.
Co-authored-by: Hanzo Dev <[email protected]>
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.
`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).
`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.
The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.
Co-authored-by: Hanzo Dev <[email protected]>
- Dark theme (#0a0a0f) with purple/cyan accents
- Hero section with search bar
- 6 category cards: Getting Started, Wallet, Transactions, Staking, Developers, Security
- Popular articles list
- Contact section with Discord, Email, Twitter buttons
- Responsive mobile-first design
- CNAME set to lux.help