27 Commits
Author SHA1 Message Date
zeekayandHanzo Dev ba0e321b66 work-board: roll lux/hanzo mainnet to work-board:*-23a5a89 (UI-fix build)
Pin the lux-mainnet and hanzo-mainnet deployments to the CI images built from
23a5a89 (FIXTURE gate + title wrap + per-brand favicon). Applied + rolled out
to do-sfo3-lux-k8s / do-sfo3-hanzo-k8s; verified live 4/4 breakpoints.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-19 01:19:55 -07:00
zeekayandHanzo Dev 23a5a89070 work-board: gate FIXTURE/RPC-error chrome out of prod, wrap bounty titles, per-brand favicon
Three prod UI fixes from the 4-res audit (work.lux.network + work.hanzo.network):

1. FIXTURE debug bar in prod. The LIVE/FIXTURE data-source pill (and the raw
   RPC error string it surfaces, e.g. "Missing or invalid parameters") was
   pinned bottom-left for every visitor and clipped past the mobile viewport.
   Gate it to `vite dev` (import.meta.env.DEV) or an explicit VITE_SHOW_STATUS
   flag, and cap the pill at calc(100vw-1.5rem) + overflow-hidden so it can
   never overflow even in dev.

2. Bounty-card title truncation. Space-card names ("Ecosystem &
   Partnerships", "Community & Social", "Content Creation") were ellipsis-
   clipped at tablet/laptop. Drop `truncate`; let the title wrap.

3. Favicon. Replace the generic emerald green-check placeholder with each
   brand's own square mark, injected per-build by the brand-html Vite plugin
   as an inline data: URI (CSP-safe, no extra request). New purpose-built
   16px-legible favicon.svg per brand (lux/hanzo/zoo/pars).

Board still reads $0 / 0 tasks because the work-market contracts are not yet
deployed on 96369/36963 (owner-gated) — untouched here.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-19 01:13:58 -07:00
zeekayandHanzo Dev 7fcb5c5ac9 work-board: resolve deps lock-free in the image (fix Rolldown musl native-binding, npm #4828)
Vite 8's Rolldown bundler needs @rolldown/binding-linux-x64-musl, but a committed
darwin-generated lock omits it and npm bug #4828 won't add it on install → 'Cannot find
native binding'. Copy only package.json and npm install fresh on the linux-musl build host so
the correct platform bindings resolve. Repo lock stays for local-dev reproducibility.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-19 00:08:58 -07:00
zeekayandHanzo Dev 4b533d3aa3 work-board: build image via vite directly + npm install (fix TS7-native/rollup platform-binary break on alpine)
The @luxfi/ui migration bumped to TypeScript 7 (native) + Vite 8 (Rollup 4), both of which
ship platform-specific PREBUILT binaries as optionalDependencies. Two failures resulted in the
alpine CI build: (1) npm ci against a darwin-generated lock lacked the linux-musl variants, and
(2) the TS7 native compiler has no alpine/musl binary at all, so 'tsc --noEmit' can't run there.
Fix both the ecosystem-standard way (same as the dao-vote image): npm install resolves the
platform-correct optional deps on the linux build host, and the image builds the bundle with
vite directly (esbuild transpiles TS; the typecheck is a dev/CI-lint concern, verified locally).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-19 00:05:03 -07:00
zeekayandHanzo Dev 21b323de7a work-board: regenerate package-lock with npm 10 to match node:22 CI (fix npm ci drift)
The @luxfi/ui@7.4.0 migration regenerated the lock with npm 11, which dedupes the
typescript@6.0.3 that @luxfi/ui's @expo/* deps require — but the Dockerfile builds on
node:22-alpine (npm 10) via 'npm ci', which demands those nested entries and failed
EUSAGE 'Missing: typescript@6.0.3 from lock file'. Regenerate the lock with npm 10 so it
matches the build tool; no bypass of npm ci.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 23:48:58 -07:00
zeekayandHanzo Dev c846a068ea work-board: generic injected-wallet Connect (any EIP-1193, not Phantom-only)
The Connect sheet's wallet method was Phantom-specific — window.phantom.ethereum only —
so eth_requestAccounts never fired for MetaMask/Rabby/Coinbase users (Zoo/Pars Connect
read as a no-op). Replace the narrow 'phantom' WalletKind with a generic 'injected' one
that resolves window.ethereum (any injected EIP-1193 wallet, Phantom included) and opens
the wallet's own connect prompt, so claim->sign is reachable on every brand.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 23:42:11 -07:00
zeekayandHanzo Dev a6efa84d86 work-board: consume @luxfi/ui@7.4.0 from npm + drop local line-height pin
Phase-1 built @luxfi/ui locally and consumed it via `file:`, which blocked the
merge. 7.4.0 is now published to npm WITH dist/ (real tarball, 192 dist entries)
via the KMS-gated release path, so switch the dep `file:` -> `@luxfi/ui@7.4.0`
(exact, matching the sibling @hanzogui pins). package-lock now resolves the
registry tarball (integrity sha512-LfUYgZFP…).

Drop the local `body .font_body { line-height: 1.5 }` pin from src/index.css:
7.4.0's AppProvider now ships that Tailwind-Preflight reset itself (injected once
via useInsertionEffect), so every consumer — not just the work-board — inherits
it. One place, one way.

Verified against the npm package: build green (tsc + vite 8.1.5, 1622 modules);
visual-regression 25/25 goldens within 2% (21 zoo + 4 pars white-label), incl.
the task-detail sheet + ⌘K palette overlays that the pin originally fixed.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 16:13:31 -07:00
zeekayandHanzo Dev 8ef4d5dc82 work-board: drop dead weld-probe helper (weldcheck scaffold removed)
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 11:23:12 -07:00
zeekayandHanzo Dev c4101e4094 work-board: fix task-detail sheet reflow — pin app text line-height to 1.5
@hanzo/gui's GuiProvider wraps the app in a Tamagui `font_body` context that
pins an absolute line-height (23px). That cascaded into the work-board's
arbitrary-size text (text-[11px] field labels etc., which carry no line-height
utility), making each ~6.5px too tall and reflowing the bottom-anchored
task-detail sheet by ~33px on mobile. Restore the Tailwind-Preflight baseline
(html line-height:1.5) the work-board was authored against.

Visual-regression now 25/25 work-board goldens within 2% (21 zoo + 4 pars
white-label). task-detail modal panel height matches the pre-migration build
exactly (576px == 576px).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 11:22:18 -07:00
zeekayandHanzo Dev 1bda286d36 work-board: migrate onto @luxfi/ui@7.4.0 (@hanzo/gui Tamagui engine) — Phase 1
Run the live 4-org Dework hub on the @luxfi/ui / @hanzo/gui (Tamagui) engine
without regressing the owner-approved look/feel.

- Vite+Tamagui weld (proven exchange recipe): react-native->react-native-web
  alias, dedupe + single-copy of @hanzo/gui/@hanzogui/core/@hanzogui/web,
  optimizeDeps pre-bundle, __DEV__/EXPO_OS/IS_WEB defines, commonjsOptions so
  the engine stays in React's chunk. guiPlugin extraction deferred (its 7.3.0
  peer pins vite@8.0.3); app renders on the runtime style-injection path.
- Wrap in AppProvider (GuiProvider + TanStack Query); brand = VALUE: root theme
  row dark_${BRAND_KEY} + --brand sourced from @luxfi/ui LUX_BRAND (hex identical
  to brands.ts, zero cross-brand leak).
- tokens.css remap layer maps the @luxfi/ui --color-* contract onto the Dework
  palette + brand (no wholesale exchange-palette import).
- Text fields -> @luxfi/ui Input/Textarea (native inputs, onChangeText<->onChange
  bridge): CommandPalette ⌘K, Suggestions editor, TaskDetail comment, chrome
  Toolbar, Leaderboards search. Keystroke round-trip verified.
- Fix Leaderboards mobile clip: page container was a flex item whose mx-auto
  disabled cross-axis stretch, so min-w-[460px] tables forced cards to 460px and
  bled past 390px. w-full + min-w-0 chain + overflow-hidden cards -> tables now
  scroll inside rounded cards, no horizontal page scroll.

Build green (tsc + vite). Visual-regression: 19/21 golden views pixel-match
(<=2%); 2 mobile bottom-sheet overlays (task-detail, palette) diverge ~3% (under
review). Preview branch — do NOT merge to main until owner review.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 11:08:50 -07:00
zeekayandHanzo Dev 54540233a9 brands: point Zoo + Pars work-board at the GO-LIVE contracts
Set the Zoo (200200) and Pars (494949) addresses (bounty/escrow/reputation + karma,
+ Pars governor) to the newly deployed DAO-Safe-owned work-market, superseding the
smoke set the boards read today. Owner/governor unchanged. Lux + Hanzo untouched.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 09:06:17 -07:00
zeekayandHanzo Dev 57604fd8f7 work-board: multi-auth Connect flow (Discord/GitHub/Phantom/WalletConnect via Hanzo IAM)
Per-brand IAM tenant (lux.id/zoo.id/pars.id) + <org>-work OIDC client (PKCE, no secret);
SIWE wallet-link. Build green (tsc + vite).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-18 02:16:54 -07:00
zeekayandHanzo Dev 9e0073528c deploy: roll all 4 work-board surfaces to 6fcf7a2 + stand up lux & hanzo
All four white-labels pinned to the single green sha 6fcf7a2 (identical source to
477a05f — only the CI matrix changed):
  zoo   sha-6fcf7a2    work.zoo.network    (zoo-mainnet / zoo-k8s, @file)
  pars  pars-6fcf7a2   work.pars.network   (pars / pars-k8s, @file)
  lux   lux-6fcf7a2    work.lux.network    (lux-mainnet / lux-k8s, IngressRoute)
  hanzo hanzo-6fcf7a2  work.hanzo.network  (hanzo-mainnet / hanzo-k8s, @file)

lux-k8s's public ingress reads the kubernetescrd provider (Traefik IngressRoute,
group hanzo.ai/v1alpha1), not @file, so work.lux.network mirrors api.lux.network
(certResolver letsencrypt, Cloudflare-proxied). hanzo mirrors api.hanzo.network
(@file router, certResolver letsencrypt via DNS-01, grey). One brand per image;
zero cross-brand leak.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 22:41:41 -07:00
zeekayandHanzo Dev 6fcf7a22b6 ci: add lux + hanzo white-label legs to work-board build matrix
Mirrors the zoo/pars legs — VITE_BRAND selects the src/brands.ts profile and
VITE_RPC_URL bakes the brand's live CORS-enabled RPC into the bundle. Two more
immutable per-commit images from identical source:
  lux   -> ghcr.io/luxfi/work-board:lux-<sha>    (work.lux.network,   #7000FF)
  hanzo -> ghcr.io/luxfi/work-board:hanzo-<sha>  (work.hanzo.network, #ea580c)
One brand per build; zero cross-brand leak. amd64-only static SPA, luxfi ARC pool.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 22:32:12 -07:00
zeekayandHanzo Dev 477a05f1ab fix: green the work-board build — decouple logo assets from brands.ts
- brands.ts was importing .svg logos at top level; vite.config.ts imports
  brands.ts (for build-time title/CSP), and the config bundler parses SVG
  markup as JSX → 'Unexpected JSX expression'. Split the .svg imports into a
  runtime-only src/brand-logos.ts (BRAND_LOGOS keyed by BrandKey); brands.ts
  is now pure, bundler-safe config data. ui.tsx BrandMark/BrandLogo read
  BRAND_LOGOS[BRAND_KEY].
- fixture.ts: add lux+hanzo empty fixtures (no live bounty yet) to satisfy
  Record<BrandKey,...> after brands.ts grew to 4 brands.

Full build green (tsc + vite). Lands the in-flight ⌘K palette, 6-category
symmetrical grid, real brand logos, and proper accents (Zoo #6c5efb indigo,
Pars #1C3879 Persian blue, Lux #7000FF, Hanzo #ea580c — placeholder green gone).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 21:54:22 -07:00
zeekayandHanzo Dev cf881fc763 WIP: ⌘K palette + 6-cat grid + brand logo rendering (build red)
Builder + brand agents paused on the weekly usage cap (resets Jul 21 6am PT).
Preserving in-flight work-board work so nothing is lost; next resume greens + finishes.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 21:23:58 -07:00
zeekayandHanzo Dev 6b1e1d16e2 Overview bounties: symmetrical category grid + peaq cards
Render brand.spaces as a 1→2→3 column grid (1-col phone, 2×N tablet,
3×2 desktop for six categories) — driven by whatever spaces the brand
supplies, no hardcoded count, so it stays symmetrical as ae530aa6
expands Zoo/Pars to six. Cards are peaq-style: emoji tile + name +
"N open tasks · N contributors" (singular/plural aware), uniform
structure so the grid reads as one clean block.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 21:07:31 -07:00
zeekayandHanzo Dev d717c5f826 ⌘K command palette: global fuzzy search + quick-nav + actions
One palette over bounties / spaces / views / quick actions (new
suggestion, connect). ⌘K / Ctrl-K toggles it on desktop (discoverable
via a Search pill in the topbar); a ≥44px search icon in the mobile top
bar opens the SAME palette as a full-screen bottom-sheet. Keyboard-nav
↑/↓ + Enter, Esc/⌘K to close; the rendered order and the selection
index share ONE grouped list so the highlighted row is always the row
Enter runs. Dependency-light (no kbar) — a subsequence fuzzy scorer.

App also composes the prior 64px icon-rail split into the shell.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 21:06:35 -07:00
zeekayandHanzo Dev 223d9a745b Mobile: prevent horizontal overflow on board & leaderboards
min-w-0 on the leaderboard grid cells lets long addresses/amounts
truncate instead of forcing page-level horizontal scroll at 390px;
narrower snap widths keep board columns fully on-screen on phones.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 21:04:45 -07:00
zeekayandHanzo Dev 3bb90ee58e Mobile-first + Dework design tokens + Karma-as-points across all 9 views
Mobile-first (390px up, enhance to desktop):
- Sidebar → off-canvas drawer behind a hamburger (overlay + tap-close + safe-area);
  static 256px sidebar only at md+. Mobile top bar carries hamburger + workspace + Connect.
- Kanban → horizontal scroll-snap columns (~86vw, peek next) on mobile; 4-col grid at xl.
- Leaderboard / All-Contributors tables wrapped in overflow-x scroll regions (min-w),
  body never scrolls sideways. Tab row is horizontally scrollable.
- Task-detail + suggestion modals are full-bleed / bottom-sheet on mobile, centered cards at sm+.
- Overview stacks main + right rail on mobile; all view paddings responsive.
- index.css: overflow-x hidden, env(safe-area-inset-*), clamp() fluid type, thin scroll-x utility.

Design tokens: consolidated every surface hex to the Dework palette as CSS vars
(--bg #0e0e10 / --rail #141416 / --surface #17171b / --border #232328 / --hover #1e1e24),
set per-brand --brand accent at runtime. Deleted the now-unused theme.ts (dead code).

Leaderboards: Task Points = global Karma (formatAmount(karma)) with a transparent
tasks×100 proxy until Karma is canonical on-chain; dropped the separate Karma column.

Contract naming: ABI imports stay indirected via abi.ts (one-line swap for the
finished non-versioned Bounty/Escrow/Reputation/Karma set); scrubbed V1/V2 from
comments + README; README now documents the full platform.

Every view still renders from the fixture with no wallet/chain (screenshot-able).
Verified live at work.zoo.network (real Zoo data) + local at 390px and 1440px.

package: 0.2.0 -> 0.3.0

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 17:37:56 -07:00
zeekayandHanzo Dev 2f470101a3 Dework-clone community work platform: Overview / Board / Open Tasks / Leaderboards / Suggestions / Combined Board / task-detail + Explore
Extends the on-chain work-board into a full Dework-style community surface,
white-labeled per domain, on our own primitives. Every view derives from ONE
on-chain read (loadWorkspace) so header/board/leaderboard numbers can't drift.

Views (all reading live Bounty/Reputation over JSON-RPC):
- Overview: org header + Time-to-payment / Total-paid stats (from PaymentReleased
  + BountyProposed event timestamps), Discord role-gate banner, Bounties category
  grid (Spaces), Projects, right rail (About/Contributors/Admins).
- Board: 4-lane kanban (To Do/In Progress/In Review/Done) with Dework empty-state
  framing; task cards show title + skill tags + reward + open-to badge + assignee.
- Open Tasks: rows grouped by status with skill tags + reward + assignee.
- Leaderboards: Top Contributors + Top Reviewers (7d/30d/all-time; windows from the
  event stream, all-time from Reputation) + All Contributors; global-Karma column.
- Community Suggestions: create modal + upvotes (local-first, IAM/on-chain-swappable).
- Combined Board (all Spaces) + Space tabs (Overview/Board/Open Tasks/Suggestions).
- Task detail: on-chain description + real activity log (created→funded→claimed→
  submitted→accepted→paid) + apply/comment flow + status/assignee/reviewers.
- Explore: cross-space skill-filtered index + sibling-DAO links.

Data layer:
- chain.loadWorkspace assembles bounties + activity + stats + contributors (workers
  ∪ reviewers) in one pass; block timestamps batched.
- Reward model is a native/ERC-20/ERC-721/ERC-1155 union — parseReward reads
  rewardType+tokenId when the finished Bounty struct carries them (NFT rewards
  render with tokenURI metadata), defaults to native/ERC-20 today.
- Karma optional per brand (global soul-bound rep); degrades cleanly when absent.

Config-driven white-label: Spaces/skills/tagline/accent/socials/Karma/IAM added to
the existing VITE_BRAND brand map (zoo, pars); one canonical config, one image/brand.
Hash router (no dep); Dework dark palette; per-brand accent via --brand.

package: 0.1.0 -> 0.2.0

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 17:22:22 -07:00
zeekayandHanzo Dev 2d06b73a03 deploy: pin pars work-board to ghcr.io/luxfi/work-board:pars-d10c9cb
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 16:54:18 -07:00
zeekayandHanzo Dev d10c9cbc49 pars: white-label the work board via a VITE_BRAND brand map
One repo, one Dockerfile. Brand-varying values (chain, addresses, owner
label, header/title, CSP RPC host) move into src/brands.ts, selected at
build time by VITE_BRAND (default zoo). The zoo profile reproduces the
prior hardcoded values exactly, so work.zoo.network is unchanged.

Adds the pars profile (chain 494949, BountyV1 0x316B..cf1F) plus CI and
k8s to stand up work.pars.network:
- docker.yml: a brand matrix builds zoo :sha-<sha> and pars :pars-<sha>
  from the same Dockerfile on the luxfi ARC pool.
- k8s/pars/: Deployment + Service (ns pars) + Traefik route fragment.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-17 16:52:23 -07:00
zeekayandHanzo Dev 4b00b51a85 route: serve work.zoo.network via Traefik @file (hanzoai/ingress), drop k8s Ingress
This cluster's hanzoai/ingress (Traefik v3) routes every public zoo host through
the zoo-dynamic ConfigMap (@file provider) with TLS auto-issued by its built-in
ACME resolver over Cloudflare DNS-01 — exactly how api.zoo.network is served.
Kubernetes Ingress objects don't produce the :443 router here (the api-zoo-network
Ingress is vestigial too), so replace k8s/ingress.yaml with k8s/route.yaml, the
router+service fragment merged into zoo-system/zoo-dynamic. One ACME client
(Traefik), no cert-manager. Verified: https://work.zoo.network serves 200 with a
valid LE cert (CN=work.zoo.network).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-16 21:03:16 -07:00
zeekayandHanzo Dev 2e533c0d5a deploy: pin work-board Deployment to ghcr.io/luxfi/work-board:sha-5331a19
The immutable image built by CI for commit 5331a19, verified present in GHCR
and rolled out 2/2 on zoo-k8s (namespace zoo-mainnet).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-16 20:40:43 -07:00
zeekayandHanzo Dev 5331a1917f ci: build on luxfi in-org ARC pool (cross-org hanzoai reusable is unreachable)
The hanzoai/.github reusable is a private cross-org repo and both orgs are on
the free plan (no shared enterprise), so GitHub blocks the `uses:` at parse
time — every luxfi caller of it fails at 0s. Switch to the in-org self-hosted
build pattern proven green by luxfi/node/dex/genesis: runs-on lux-build-amd64,
GHCR login via GITHUB_TOKEN, metadata-action → immutable ghcr.io/luxfi/work-board:sha-<sha7>,
build-arg VITE_RPC_URL baked to the live Zoo RPC. amd64-only (deploy target is amd64).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-16 20:37:15 -07:00
zeekayandHanzo Dev e88c60cb4e Zoo DAO work board: standalone repo + CI + k8s manifests
On-chain bounty kanban (Vite+React+viem static SPA) that reads the live
BountyV1/EscrowV1/ReputationV1 work-market on Zoo (chain 200200) directly
over the CORS-enabled JSON-RPC. Split out of luxfi/dao into its own repo so
CI builds a clean image.

- .github/workflows/docker.yml: canonical hanzoai/.github reusable build,
  bakes VITE_RPC_URL=https://api.zoo.network/v1/bc/C/rpc, pushes
  ghcr.io/luxfi/work-board:sha-<commit> on self-hosted arcd runners.
- k8s/: Deployment (2 replicas) + Service (80->3000) + Ingress
  (hanzoai/ingress class, host work.zoo.network, letsencrypt-prod).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-16 20:31:29 -07:00