Topolo UI Kit
Canonical handbook for the shared browser UI package, including launcher/auth surfaces, browser icon assets, build fingerprinting, consumer graph generation, and rollout verification behavior.
What It Is
PlatformApplications/packages/topolo-ui-kit is the shared browser UI package for first-party Topolo products.
It owns:
- the shared browser app launcher
- shared auth/login/landing/callback/loading shells
- the first-party app icon registry and icon renderer
- shared launcher command behavior and handoff helpers
- the checked-in build fingerprint used to verify deployed consumer bundles
- the checked-in consumer graph and fanout/report workflows used to keep launcher hosts from drifting when the package changes
How It Works
@topolo/ui-kit is not a deployable product surface.
It is a shared package repo with:
- a repo-local
topolo.cloudcontrol.jsonmanifest - package CI for build validation
- a checked-in
build-meta.jsonfingerprint for the current package source - a checked-in
consumer-graph.jsondescribing current workspace consumers - repo-local fanout automation in
.github/workflows/fanout-consumers.yml - repo-local live rollout reporting in
.github/workflows/report-consumers.yml
Shared-package repos should not pretend to be deployable applications just to appear in the deployment registry. The package exists so multiple application repos can consume one canonical browser UI contract.
Interfaces
PlatformApplications/packages/topolo-ui-kit/src/AppLauncher.tsxPlatformApplications/packages/topolo-ui-kit/src/firstPartyApps.tsPlatformApplications/packages/topolo-ui-kit/src/TopoloAppIcon.tsxPlatformApplications/packages/topolo-ui-kit/src/renderTopoloAppIconSvg.tsPlatformApplications/packages/topolo-ui-kit/src/buildMeta.tsPlatformApplications/packages/topolo-ui-kit/build-meta.jsonPlatformApplications/packages/topolo-ui-kit/scripts/update-build-meta.mjsPlatformApplications/packages/topolo-ui-kit/scripts/update-consumer-graph.mjsPlatformApplications/packages/topolo-ui-kit/scripts/fanout-consumers.mjsPlatformApplications/packages/topolo-ui-kit/scripts/rollout-consumers.mjsPlatformApplications/packages/topolo-ui-kit/scripts/report-consumers.mjsPlatformApplications/packages/topolo-ui-kit/consumer-graph.jsonPlatformApplications/packages/topolo-ui-kit/topolo.cloudcontrol.jsonPlatformApplications/packages/topolo-ui-kit/.github/workflows/ci.ymlPlatformApplications/packages/topolo-ui-kit/.github/workflows/fanout-consumers.ymlPlatformApplications/packages/topolo-ui-kit/.github/workflows/report-consumers.yml
Build Fingerprint
The checked-in build fingerprint lives at:
PlatformApplications/packages/topolo-ui-kit/build-meta.jsonPlatformApplications/packages/topolo-ui-kit/src/buildMeta.ts
It is regenerated from package source by:
node PlatformApplications/packages/topolo-ui-kit/scripts/update-build-meta.mjs
Contract:
- hash all tracked
src/**/*.tsandsrc/**/*.tsxfiles except the generated build-meta file - produce a stable
build_idsuch asui-kit-a40d59315824 - expose that build id in
AppLauncherasdata-topolo-ui-kit-build - also stamp
globalThis.__TOPOLO_UI_KIT_BUILD__from the package entrypoint so any consumer bundle importing@topolo/ui-kitcarries a stable build marker even when the launcher is code-split or not rendered on the probed route - treat the checked-in fingerprint as the package-side proof target for live rollout verification
Consumer Graph
The checked-in consumer graph lives at:
PlatformApplications/packages/topolo-ui-kit/consumer-graph.json
It is regenerated from the current workspace by:
node PlatformApplications/packages/topolo-ui-kit/scripts/update-consumer-graph.mjs
Discovery rules:
- scan canonical repo roots under
PlatformApplications/*/topolo.cloudcontrol.json - exclude
.worktrees,node_modules,dist, and other generated directories - treat code/build references to
@topolo/ui-kit,packages/topolo-ui-kit, ortopolo-ui-kit/dist/index.jsas a consumer signal - capture repo identity, default branch, declared CI workflow, deploy workflow, deploy targets, and matched files
The consumer graph is intentionally checked in rather than discovered remotely inside GitHub Actions because the package repo is standalone. The fanout workflow needs a stable, reviewable list of downstream repos without depending on a live multi-repo workspace on the runner.
Fanout Workflow
The package fanout entrypoints are:
npm run fanout:plannpm run fanout:dispatch-cinpm run rollout:plannpm run rollout:packagenpm run rollout:deploy.github/workflows/fanout-consumers.ymlnpm run report:consumers.github/workflows/report-consumers.yml
Current behavior:
- package CI builds
@topolo/ui-kit - successful
mainbuilds can dispatch downstreamci.ymlworkflows for each checked-in consumer repo - manual
workflow_dispatchsupports dry-run planning and repo filters - local workspace rollout can package or deploy stale consumers from clean git worktrees while still resolving local
file:dependencies againstPlatformApplications/packages - rollout packaging now normalizes packaged artifacts after both standard and fallback packaging so Pages and asset-backed Worker artifacts always carry the same deployed marker files, entry-document meta marker, and deploy support files before publish
- asset-backed worker deploys now restore the source asset directory after publish so local rollout does not leave marker files or packaged assets behind in consumer repos
Current limitation:
- this is a CI fanout contract, not a production auto-promotion contract
- consumer repos still own their own deploy and promotion rules
- until every consumer repo supports versioned shared-package materialization in CI, GitHub fanout should be treated as the suite-wide rebuild trigger and the local rollout script remains the authoritative operator path for package-led cross-suite deploys
- the live consumer report prefers production URLs declared in consumer manifests and falls back to a checked-in first-party host map for known Topolo apps; manifest coverage remains the long-term target
- the live consumer report now crawls HTML-discovered JS entrypoints plus first-hop imported chunks so Astro island boot files, code-split launcher chunks, and other non-trivial browser shells still resolve to one package build verdict before a host is marked stale
Required secret:
TOPOLO_GH_FANOUT_TOKENin thetopolo-ui-kitrepo, with permission to dispatch Actions workflows across dependent repos
Local Rollout
The local rollout path exists because several consumer repos still depend on sibling workspace packages such as @topolo/ui-kit, @topolo/auth-client, or @topolo/design-tokens through file: specifiers.
Package-side operator entrypoints:
npm run rollout:plan -- --stale-onlynpm run rollout:package -- --only Topolo-io/TopoloAdmin,Topolo-io/TopoloLearnnpm run rollout:deploy -- --stale-only --environment production
Contract:
- create or refresh clean consumer worktrees under
PlatformApplications/.worktrees - ensure
PlatformApplications/.worktrees/packagesresolves to the currentPlatformApplications/packagestree so sharedfile:dependencies do not drift to an old mirror - prefer each consumer repo’s own
.github/scripts/standard_ci.pyand.github/scripts/standard_deploy.pywhen they exist and the repo manifest is fully standardized - fall back to manifest-driven local packaging and direct Wrangler deploys for legacy consumers that still lack committed
ci_targetsor repo-local standard CI scripts - allow package-only fanout as the safe default and keep live deploy as an explicit operator action
- use the checked-in consumer graph plus live consumer report to target stale hosts first rather than rebuilding the whole suite blindly
- for local deploys, prefer the machine’s authenticated Wrangler OAuth session and only require
CLOUDFLARE_API_TOKEN[_ENV]when no local Wrangler session is available
CloudControl Contract
The package repo now carries a canonical topolo.cloudcontrol.json manifest even though it has no deploy targets.
Shared-package manifest rules:
- keep
deploy_targetsempty - declare package CI workflows explicitly
- use
ci_targetsto describe the package build surface - declare the repo-local
shared_packageblock so operators can find the checked-in build fingerprint, consumer graph, CI fanout workflow, local rollout script, and live-report workflow quickly
CloudControl should treat that shared_package block as preserved repo metadata. It is useful for operators and repo-local tooling even before the desktop application surfaces it directly.
Data Flow
- A shared browser UI change lands in
PlatformApplications/packages/topolo-ui-kit. - Package CI validates the TypeScript build in the package repo.
- The checked-in
consumer-graph.jsondefines which downstream repos currently consume the package. - The package fanout workflow reads that graph and dispatches downstream
ci.ymlentrypoints. - When a consumer still depends on local workspace packages, operators use
scripts/rollout-consumers.mjsto package or deploy it from a clean local worktree instead of relying on remote CI to materialize missing sibling packages. - Direct rollout deploys keep probing declared health checks for longer before failing, so a successful Cloudflare publish is not misclassified during short propagation windows.
- Direct Pages deploys now honor each target’s declared Cloudflare
production_branchinstead of assuming the git source branch should receive the live custom-domain publish. - Rollout packaging writes deployed marker files at
/topolo-ui-kit.jsonand/_topolo/ui-kit.jsonfor Pages outputs and asset-backed Workers, and also injects atopolo-ui-kit-buildmeta tag into HTML entry documents so verification does not depend entirely on bundle tree-shaking behavior or SPA rewrite rules. - Each consumer repo still owns its own build artifact, deploy workflow, and production promotion semantics even when the shared-package rollout is orchestrated locally.
- The live consumer report checks declared consumer URLs for the current
build_id, first through the entry document and injected build meta, then through the deployed marker, then through discovered JavaScript assets. - Operators confirm the downstream host actually promoted the new artifact before treating the shared fix as fully live.
Failure Modes
- a launcher/auth fix lands in the package repo but
consumer-graph.jsonis stale and misses a dependent repo - a consumer repo still vendors or aliases an old launcher path and therefore is not discoverable as a real package consumer
- package fanout dispatch succeeds but the downstream repo fails CI or never promotes production
- package fanout dispatch fails because
TOPOLO_GH_FANOUT_TOKENis missing or under-scoped - the local rollout path is pointed at a stale
.worktrees/packagessymlink and therefore packages consumers against the wrong shared source tree - consumer manifests omit production URLs, so the live report has to rely on the first-party host fallback instead of manifest-declared URLs
- operators assume a single healthy host proves all consumer hosts are current
- a Pages target declares a non-default Cloudflare production branch but local rollout deploys to the source git branch instead of the live Pages branch
Debugging
When a shared launcher or auth-surface fix is live in some apps but missing in others:
- confirm the package repo
maincommit actually contains the shared change - inspect
consumer-graph.jsonand make sure the stale host repo is listed as a consumer - inspect
build-meta.jsonand note the currentbuild_idexpected to be present in live consumer bundles - confirm the consumer repo still uses the shared launcher/auth surface rather than a vendored copy
- confirm whether the package fanout workflow dispatched that consumer repo’s
ci.yml - if the repo still depends on workspace
file:packages, runnpm run rollout:plan -- --stale-onlybefore assuming remote CI can rebuild it - run
npm run report:consumersand check whether the host iscurrent,stale, orno_url - if the consumer is a Pages app, compare the target’s declared
production_branchwith the branch used for the live publish before treating a successful deploy as production - confirm whether the consumer repo completed its own promotion to the affected environment
- do not treat one correct host as proof that every consumer host has already rebuilt
Change Log / Verification
- Added TopoloCommerce to the shared first-party app registry and consumer graph contract on 2026-04-10 so the signed-in ops surface resolves through the same launcher, icon, and callback metadata as the rest of the suite
- Added canonical
@topolo/ui-kitcoverage, a checked-in consumer graph contract, and package-level fanout workflow guidance on 2026-04-09 - Added the checked-in build fingerprint plus live consumer-report contract on 2026-04-09
- Added the local workspace rollout contract for consumers that still rely on sibling
file:packages on 2026-04-09 - Standardized rollout artifact normalization and Pages production-branch deploy behavior on 2026-04-09