Files
zeekayandHanzo Dev c3674879b7 Serve hanzo.market as one static storefront over api.hanzo.ai
hanzo.market is now the one two-sided Hanzo marketplace: a static SPA the
sites plane serves, with every read and write an api.hanzo.ai /v1 operation
and sign-in through hanzo.id (@hanzo/iam, authorization code + PKCE).

Deleted: the Hono API server (api/: its own session auth, tokens, skills,
personas, search, upload, users, integrations), the Nitro OG-image server
(server/), the Base migrations it ran (base/), the Dockerfile and entrypoint
that started all three, k8s/ manifests, the market CLI and its schema
package (packages/) whose only backend was that server, the bothub
discovery documents, the brand/federation presets, and the Convex-era docs.
No Hono remains anywhere in the tree or the lockfile.

Buyers browse one catalog of agents, apps, skills and MCP servers faceted
by type; a listing page carries reputation and the same action as a docs
link, a hanzo CLI line and a hanzo-mcp call; checkout runs clearance first
and says what it needs in plain words, including backup withholding, then
installs for per-call payment over x402 or funds an escrow job whose
lifecycle is open, accepted, delivered, released or disputed. Sellers set
up the org as principal (identity, W-9 or W-8, payout wallet), publish and
edit listings of each type from the org's own inventory, work the jobs
inbox, and see earnings and the 1099s they received.

Operations cloud does not serve yet are called by their specified path and
shown as pending on a 404 rather than faked. The UI is @hanzo/ui on
@hanzo/gui with @hanzo/design tokens and the shared @hanzogui/shell header
and footer, on the Hanzo Vite toolchain (@hanzo/vite).

CI moves to .github/workflows (hanzoai/ci build.yml@v2); hanzo.yml drops
the image lane and publishes dist/ through the site lane as hanzo-market.
The gate is oxlint (type-aware) plus hanzo-design-lint, tsc, vitest under
an 80% coverage threshold on src/lib, and the build. Playwright specs run
both sides against the dev server with the platform mocked at the network
layer, and a read-only @live subset runs against a deployed host.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-24 15:29:40 -07:00

49 lines
2.1 KiB
HTML

<!doctype html>
<html lang="en" class="t_dark" data-theme="dark">
<head>
<meta charset="utf-8" />
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="dark light" />
<title>Hanzo Market</title>
<meta name="description" content="Agents, apps, skills and MCP servers — install them, hire them, or sell your own." />
<meta property="og:site_name" content="Hanzo Market" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Hanzo Market" />
<meta property="og:description" content="Agents, apps, skills and MCP servers — install them, hire them, or sell your own." />
<meta property="og:image" content="https://hanzo.market/og.png" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="manifest" href="/manifest.json" />
<style>
/* The two things only the host document can answer: the page ground before
any module runs, and that the app fills the window. */
html { background: #0a0a0a; }
html.light { background: #f7f7f7; }
#root { display: flex; flex-direction: column; min-height: 100dvh; }
</style>
<script>
/* Keep gui's theme class in step with next-themes': next-themes writes
`light` on <html>, gui reads `t_light` / `t_dark`. Inline, because the
first paint happens before any module runs. */
;(function () {
var e = document.documentElement, was
function s() {
var l = e.classList.contains('light')
if (l === was) return
was = l
e.classList.toggle('t_light', l)
e.classList.toggle('t_dark', !l)
}
s()
new MutationObserver(s).observe(e, { attributes: true, attributeFilter: ['class'] })
})()
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>