/{owner}/{slug}?name=&email=¬es= starts the details step filled in,
as a Cal.com link does: hanzo.ai's sales page sends its visitors here
with the answers they gave. The page reads them once and takes them off
the address before anything reports it.
That needs @hanzo/booker 8.3.6's prefill, so the app moves to the 8.x
line: @hanzo/gui 8.3.5 and React 19. The committed lockfile no longer
matched package.json and is regenerated.
cal.hanzo.ai is served from the Sites plane slug cal-web, and nothing
published there: the image lane pinned a values file universe deleted,
and the forge copy runs no workflows. hanzo.yml gains the site lane and
.github/workflows calls hanzoai/ci; the Dockerfile and the dead lanes go.
Claude-Session: https://claude.ai/code/session_01HuMDfgFssPUptYUzgZ6Cp8
hanzo-build-linux-amd64, lux-build-linux-amd64, zoo-build-linux-amd64 and
every other org-prefixed spelling all meant the same machine. Which org a
job belongs to does not change which host can build it, so the org bought
one pool name per org per arch and each could go stale on its own -- the
evo host alone answered to fourteen names for one label.
One vocabulary now: linux-amd64, linux-arm64, macos-arm64, win-amd64. The
generic labels every plain workflow uses (ubuntu-latest, self-hosted) are
untouched, so naive CI keeps working.
Co-authored-by: Hanzo Dev <[email protected]>
hanzoai/ci keeps the reusable at .github/workflows/build.yml — the one path
both planes resolve, since github.com reads a reusable only from there and the
forge reads it too. The v1 tag moved with it, so a caller still naming
.hanzo/workflows/build.yml asks for a blob that is not in the tree:
InsertRun: read hanzoai/ci@v1:.hanzo/workflows/build.yml: object does not exist
The caller itself stays at .hanzo/workflows/cicd.yml on purpose: github.com has
no runner for these labels, so a caller placed there could never be scheduled.
Co-authored-by: Hanzo Dev <[email protected]>
main.tsx imported @fontsource-variable/geist and geist-mono and styles.css
named them, so this surface shipped two npm packages of somebody else's face.
One import of @hanzo/font/css covers both roles.
This repo is written on git.hanzo.ai and mirrored to github.com, and the two had drifted apart — 8 commits here the mirror lacked, 1 there this host lacked. Merging rather than overwriting so neither side's work is lost.
This repository was public with no LICENSE file. It is a fork, so the grant is
the upstream's: MIT, with the upstream copyright retained as MIT requires.
Work landed on GitHub while CI reads the forge, so each remote carried commits
the other did not. Merging keeps both; a force-push either way would have
dropped one side silently.
Co-authored-by: Hanzo Dev <[email protected]>
Actions are disabled on this repository, so these files have not run in a long
time and cannot run: they are build definitions no forge executes. Builds go
through the native path -- POST /v1/runner, which schedules a BuildKit job --
and CI lives under .hanzo/workflows. A dead workflow that still looks like a
pipeline is worse than none, because it reads as coverage nobody has.
github.com has no runner for hanzo-build-linux-amd64, so a caller under
.github/workflows is a gate that can never be scheduled. This is the ~7-line
caller on the plane that can (git.hanzo.ai git-runner fleet), pinned @v1.
Co-authored-by: Hanzo Dev <[email protected]>
github.com has no runner for hanzo-build-linux-amd64, so a caller under
.github/workflows is a gate that can never be scheduled. This is the ~7-line
caller on the plane that can (git.hanzo.ai git-runner fleet), pinned @v1.
Co-authored-by: Hanzo Dev <[email protected]>
This pipeline could not work on this fleet and had not produced an image in
weeks, while looking idle rather than broken.
buildctl-daemonless.sh: command not found (exit 127). Jobs run in
catthehacker/ubuntu:act-24.04 per GIT_RUNNER_LABELS; there is no buildctl
in it. It also read secrets.GIT_CLONE_TOKEN, which exists on neither the
repo nor the hanzoai org on git.hanzo.ai.
The kubectl patch step failed the same way (kubectl: command not found) and
was futile anyway: cd.hanzo.ai selfHeal restores the App CR from the pin in
hanzoai/universe on its next poll. Rollout is a reviewed pin there, never a
CI side effect — so the deploy step is removed, not repaired.
Replaced with the shape proven on hanzoai/playground, the only one of these
whose build job has ever gone green here: setup-buildx + login-action +
build-push-action, using GHCR_USER/GHCR_TOKEN/GH_PAT which DO exist as org
secrets. Keeps playground's imagetools verification, because build-push-action
can exit 0 before the manifest resolves.
runs-on named a label no runner on git.hanzo.ai advertises. The four online
git-runners offer hanzo-build-linux-amd64 (plus ubuntu-latest/22.04/24.04);
hanzo-linux-amd64 and hanzo-deploy-linux-amd64 are offered by NOTHING there
(the latter is a GitHub ARC pool, not a forge runner).
A job asking for an unavailable label does not fail — it queues forever and
cancels at the 24h timeout, which reads as 'CI is slow', not 'CI is broken'.
This was latent while the forge repo had actions disabled and the pipeline
could not fire at all. Enabling it made the bug reachable, so it is fixed in
the same pass.
The build workflow no longer calls platform.hanzo.ai/v1/build-callback (that TS
control plane is retired; the edge is the cloud Go binary). The runner just builds
and pushes to GHCR; the operator rolls it out via the App CR. Ship images by
semver tag (v0.2.0), not raw sha.
The landing hero is now the product itself — the live <Booker> embedded (no
StrictMode loop; renders stably). Drop the 'Try a booking' button. Nav gets
'Sign in' and 'Create your calendar', both entering through hanzo.id (IAM).
Add the Hanzo H mark to the nav + favicon (from ~/work/hanzo/logo). Fix the font
family to the real @fontsource name (Geist Variable) and force it across the
Tamagui booker with !important (Tamagui sets font-family inline).
The cross-origin POST /bookings to api.hanzo.ai failed (cal-api-version header not
in the preflight allow-list). cal.hanzo.ai/v1/calendar already routes to the same
backend, so a relative same-origin path avoids CORS entirely. GET slots worked
cross-origin; the POST didn't.
The nested Tamagui embed in the plain-HTML marketing hero intermittently blanked
the landing. Landing is now pure HTML (always renders); 'Try a booking' links to
the live Booker at /{host}/{event}. Dark monochrome + Geist intact.
The Cal atoms never rendered (4 blank-page failures: dayjs, zustand, infinite-loop).
Replace with the native universal @hanzo/booker on hanzogui/@hanzo/gui, pointed at
/v1/calendar. react-native->react-native-web + GuiProvider is the whole recipe.
Booker at /{owner}/{slug}, CalendarEmbed live-demo in the hero. Render-verified
headless (full calendar renders; atoms bundle 1.7MB -> 410KB). No atoms, no patches.
The Booker crashed 'aue is not a function' because zustand/traditional imports the
named export useSyncExternalStoreWithSelector from use-sync-external-store's CJS
barrel, whose conditional dev/prod require defeats Rollup's named-export analysis
(namespace resolved to {}). Install use-sync-external-store + alias the shim to its
concrete production file so the named export is synthesized. Reverts the incomplete
@hanzo/cal-atoms fork (empty barrel/broken exports) back to the buildable @hanzo/cal
wrapper. Artifact-verified: dayjs .extend=16, empty-namespace crash pattern=0.
The atoms declare sideEffects:false, so the bundler dropped their
'import ./vendor/dayjs' that runs dayjs.extend(utc,timezone) — dayjs.tz was
undefined and the Booker crashed at bootstrap (blank page). pnpm-patch the atoms
sideEffects to preserve those extends (verified: bundle extend-count 3→16).
Renames @hanzo/calendar → @hanzo/cal (owned/publishable pkg, tsup dist); root
build is topological (pkg then app); Dockerfile + app rewired.
Booker crashed with 'dayjs.tz is undefined' on tz.guess() because @calcom/atoms
declares sideEffects:false, so the bundler dropped its vendored dayjs.extend(tz).
Extend the shared singleton in @hanzo/calendar and dedupe dayjs to one instance.
- Dockerfile builds the Vite bundle (pinned pnpm) in stage 1, serves it via
hanzoai/spa in stage 2 — a fresh docker build no longer needs a pre-built
app/dist (gitignored), so CI and local builds match.
- .dockerignore keeps the build context lean (deps/bundle rebuilt in-image).
- .github/workflows/cicd.yml builds+pushes ghcr.io/hanzoai/cal:sha-<short> on
the self-hosted hanzo-build-linux-amd64 pool — zero GitHub-hosted minutes.
- deploy/mirror-to-forge.sh mirrors any repo to git.hanzo.ai/hanzo/<name>.
- deploy/base-native/cicd.yml: paired base image workflow (prepared, not applied).
The public booking SPA: Cal.com's real <Booker> UI powered entirely by the
native Hanzo Base backend at /v1/calendar (no Cal Prisma/Postgres/Node API).
- packages/calendar: @hanzo/calendar, the debranded fork surface — a thin
Hanzo-namespaced wrapper over published @calcom/atoms (MIT, see NOTICE) that
re-exports Provider/Booker under Hanzo names for public, no-OAuth booking.
- app: Vite + React SPA. /{owner}/{slug} renders the Booker against Base;
/booking/{uid} is the confirmation + cancel view.
- Dockerfile: FROM ghcr.io/hanzoai/spa, COPY app/dist /public.
Free-booking Stripe peers are stubbed so the bundle is self-contained/CSP-clean.
Only MIT @calcom code; Cal copyright preserved in NOTICE.