three.ws ships all platform surfaces from a single npm-workspaces monorepo. This file maps each product surface to where it lives in this repository, so external developers can find what they need without reading 50 top-level directories.
When an internal surface gains an external consumer that needs an independent
release cadence, we promote it to its own published package (and optionally its
own repo via git subtree split). See Promotion path at the
bottom.
| Surface | Location | Status | Notes |
|---|---|---|---|
| Web renderer / viewer | avatar-sdk/ → /viewer |
Published as @three-ws/avatar |
<agent-3d> web component |
| Agent shell (companion identity + agentic ⌘K + persistent navigation) | src/agents/guest-agent.js, src/shared/agent-names.js, src/walk-companion-identity.js, public/search.js, src/view-transitions.js, src/shell/page-lifecycle.js | Live | The agent IS the interface: every visitor gets a named ephemeral agent in the first five seconds (auto-summoned corner companion with an identity chip; “Claim →” prefills /create-agent and POST /api/agents makes it real); the ⌘K palette executes real commands in place (forge → free text→3D lane, digest → clustered news, price → live market data, ask → streamed /api/chat) and announces completions so the companion reacts; pages marked data-shell (/markets, /coins) navigate by swapping only the main element so the agent and shell never unload (page modules re-init via onPageReady). Docs: docs/agent-shell.md. Tests: tests/search-commands.test.js, tests/guest-agent.test.js, tests/agent-names.test.js |
| Walk companion + playground | walk-sdk/ → /walk-companion.js |
Published as @three-ws/walk |
Corner mascot + full-page stroll/platformer playground + diverse avatar picker. App entries: src/walk-companion.js, src/walk-playground.js |
| React avatar creator | avatar-sdk/ → /react /creator |
Published as @three-ws/avatar |
Same package, React subpath |
| Talking page guide | page-agent-sdk/ | Published as @three-ws/page-agent |
Drop-in rigged 3D agent that narrates any page + visitor avatar picker. <page-agent> web component. Rigged-only catalog. preset="…" resolves one of 5 personas (greeting/role/suggested-prompt chips/tool allowlist) — see page-agent-sdk/README.md#persona-presets. See page-agent-sdk/PUBLISHING.md |
| Guided site tour | tour-sdk/ | Published as @three-ws/tour |
3D guide walks a live site, spotlights sections, narrates each. One-tag CDN build + free roam |
| three.ws's own guided tour + onboarding | src/feature-tour/ → /feature-tour.js, entry src/feature-tour.js, curriculum public/tour/curriculum.json generated by scripts/build-tour.mjs, landing pages/tour.html → /tour |
Live | A hardened, site-native fork of the tour-sdk/ engine (same curriculum schema — stops/sections/tracks/highlight/narration/targets), lazy-injected only when a tour is starting/active (feature-tour-boot Vite plugin) so pages that never tour pay no Three.js cost. Three tracks share one curriculum: full (every feature, chapter by chapter), quick (highlighted heroes), and onboarding (added 2026-07-12) — a 6-stop, hand-authored new-account walkthrough chaining /start → make an avatar (/create/selfie) → build a world (/diorama) → live /markets data → an optional coin launch (/create-agent, clearly skippable) → the new creator's own /profile. Auto-offered once to a signed-in account with zero creations across avatars/agents/forged models/worlds (GET /api/me → show_onboarding_tour, backed by users.onboarding_tour_seen_at/onboarding_tour_completed_at, migration api/_lib/migrations/20260712030000_onboarding_tour_state.sql); always reachable afterward via "🎬 Replay guided tour" in the public/getting-started.js checklist panel. Tests: tests/feature-tour-curriculum.test.js, tests/api-me-onboarding-tour.test.js |
| Tour Builder (no-code playground) | pages/tour-builder.html → /tour-builder |
Live | Point-and-click editor over a demo storefront: pick avatar, add stops, preview the real tour, export curriculum + Shopify snippets. Also ships Templates — ready-made tours (Sperax's DeFi protocol tour is the first) that load straight into the editor. Logic: public/tour-builder/builder.js, presets: public/tour-builder/presets/. Sperax template doc: docs/tutorials/sperax-tour.md |
| Avatar builder (full app) | character-studio/ | Fork of m3-org/CharacterStudio, MIT, see character-studio/LICENSE | Web-first character creator |
| Scene Studio (3D scene editor) | src/scene-studio/ → /scene |
Vendored mrdoob/three.js r184 editor, MIT, see src/scene-studio/vendor/README.md | Import GLBs, compose scenes, edit materials/lights, export |
| Diorama (text → 3D world) | src/diorama/ → /diorama |
In-repo · backend api/diorama.js | One sentence → an explorable 3D diorama: Claude composes the scene, each object is forged to a real GLB, assembled live, saved to a public gallery + shareable permalink |
| Creator portfolio (human profile) | pages/profile.html → /u/:username (self-view /profile), backend api/users/[username].js + paginated api/users/[username]/creations.js → /api/users/:username/creations |
Live | Every three.ws user's public portfolio: avatars, agents, widgets, skills, plugins, coins, memories, items for sale, and (added 2026-07-12) a Creations tab merging forged 3D models + Scene Studio worlds — real, live, spinning <model-viewer> cards, cursor-paginated for 100+ items. /forge and /diorama stay anonymous by default (no login required); a signed-in creator's user_id is now attached to forge_creations/dioramas rows at generation/save time (migration api/_lib/migrations/20260712010000_creator_portfolio_user_ids.sql) so those creations surface here. The same opt-in attribution now links back from the diorama viewer HUD, the diorama gallery cards, and the forge result bar ("by @user") whenever a creation's creator is known. /@:handle (pages/handle.html) is a separate, narrower agent-embed page — not the human portfolio. |
| Labs (hidden-gems hub) | pages/labs.html + src/labs.js → /labs |
In-repo | Data-driven discovery hub: renders every data/pages.json entry flagged showcase: true as a live card (status check + iframe preview), filterable by category |
| Cross-entity search | pages/search.html → /search, backend api/search.js + query layer api/_lib/cross-search.js |
Live | The one search across every creation type — avatars, on-chain/Solana agents, forged 3D models, worlds, and coins. Federates (not one SQL UNION — the stores are genuinely heterogeneous, two of five aren't even in the same database) five parallel queries, normalizes into one card shape, and ranks by recency plus real signals (follower count via user_follows, remix count, view count) — see the file header in api/search.js for the full unify-vs-federate writeup. Model results carry a working "Remix — $0.25" action against the existing paid rail (api/x402/remix-asset.js), reused from pages/creations.html rather than re-derived. Coin search checks three.ws's own launch directory (pump_agent_mints) first, then falls back to market-wide pump.fun/Birdeye search for broader coverage (those external matches carry no verified timestamp or creator profile, and are ranked/labelled accordingly). Linked from the Discover nav menu. |
| Cross-surface rankings, streaks & badges | pages/rankings.html → /rankings, backend api/leaderboard/unified.js, streak/badge engine api/_lib/streaks.js (migration api/_lib/migrations/20260712020000_leaderboard_streaks_badges.sql), daily Top-10 badge sweep api/cron/leaderboard-rollup.js |
Live | Five real, queried leaderboard metrics — creations (forge models + worlds), remixes received, coin launches, followers, and walk distance (signed-in walkers, all-time) — ranked live with the viewer's own rank pinned even off-page. Every signed-in qualifying action (login, a finished forge model, a saved world, a /walk session) rolls a per-user daily streak in user_streaks via recordDailyActivity(), called from api/_lib/auth.js, api/_lib/forge-store.js, api/_lib/diorama-store.js, and api/walk/metrics.js. Four real earned badges persist in user_badges: First Creation, Remixed (awarded in api/x402/remix-asset.js when a remix lands on your creation), 7-Day Streak, and a daily-refreshed top10_<metric> per leaderboard. Streak + badges surface on the profile (pages/profile.html) and the Rankings page itself. Rejected metrics (documented in api/leaderboard/unified.js's header): royalties earned in USD (the settlement record is a single overwritten JSONB column, not a cumulative ledger) and /play activity (no per-human-user session table exists). |
| Platform activity feed | pages/feed.html → /feed + pages/community.html → /community, backend api/users/me/feed.js |
Live | Reverse-chronological creation events (avatars, agents, coins, models, worlds) plus follow activity, merged at read time from forge_creations, dioramas, and user_follows (no separate event log to drift out of sync). ?scope=following (default; session-gated, anonymous gets 401) vs ?scope=all (public; powers /community and first-visit feeds); limit 1..50, before ISO cursor. Items deep-link to creator portfolios. Distinct from the Money Pulse ticker GET /api/feed (docs/money-feed.md). Docs: docs/social-layer.md |
| Follow graph | api/users/[username]/follow.js + api/users/[username]/follows.js, table user_follows, buttons on pages/profile.html |
Live | GET returns {following, followed_by, followers_count, following_count}; POST/DELETE are idempotent (session + CSRF, self-follow 400) and return the same envelope so one round-trip updates the button and the counts. A genuinely new edge (ON CONFLICT DO NOTHING) publishes a follow user event to the notification bell exactly once. Feeds the activity feed's following scope, search ranking, and the followers leaderboard metric. Tests: tests/api/users-follow.test.js. Docs: docs/social-layer.md |
| Notification bell & preferences | Event vocabulary api/_lib/feed.js (USER_EVENT_TYPES → publishUserEvent() → user_notifications), endpoints api/notifications/, preference matrix api/_lib/notify-prefs.js, bell client src/notifications.js, settings panel src/dashboard-next/pages/settings.js |
Live | In-app inbox covering remixes (api/x402/remix-asset.js), DMs (api/friends/messages.js), coin bonding-curve graduations (pump cron in api/cron/[name].js), follows, sales, purchases, IRL, market, and account events. Preferences are a category × channel matrix (in_app always on; push/email/telegram are per-category opt-outs) edited from /dashboard/settings. Docs: docs/social-layer.md |
| OKX.AI marketplace services | api/okx/3d/[service].js → /api/okx/3d/* |
Live | 3D services sold to other agents on OKX.AI (agent #2632): Agent Identity Studio flagship + decomposed studio services. Catalog source of truth: api/_lib/okx-catalog.js; pipeline: api/_okx3d/; showcase: pages/agent-identities.html → /agent-identities; docs: docs/okx-marketplace.md |
| Crypto Data API docs / landing | pages/crypto.html → /crypto |
In-repo · docs surface | Screenshot-worthy public docs + funnel-top for the free, keyless Crypto Data API (/api/crypto/* — token snapshot, security, holders, launches, bonding, whales, symbol, wallet, trending). Renders hero, endpoint table, tabbed quickstart (curl/JS/Python), per-endpoint request/response reference and a live "Try it" console. Probes production at runtime and marks each endpoint Live vs Coming soon (degrades gracefully while sibling endpoints roll out). CTAs funnel to paid uniques: /launcher, /vanity-wallet, /forge. Spec: prompts/x402-overhaul/ |
| Free Crypto Data API + discovery | api/crypto/index.js → /api/crypto, api/crypto/openapi.js → /api/crypto/openapi.json, docs docs/crypto-api.md → /docs/crypto-api |
Live · docs surface | Front door + OpenAPI 3.1 for the free, keyless Crypto Data API. Catalog assembler api/_lib/crypto-catalog/index.js merges api/_lib/crypto-catalog/*.js self-describing descriptors (currently bonding, launches, symbol, token, trending, wallet, whales) via a static import barrel — the production source of truth, since Vercel's bundler only ships what static imports reach — plus an additive dev-time directory glob; skips malformed/throwing entries, never throws, valid-empty when zero. New descriptor = drop the file AND add its import line to the barrel. OpenAPI built from the same catalog via api/_lib/crypto-catalog/openapi.js. Index does HTML/JSON content negotiation. Endpoint handlers live in api/crypto/*.js. Spec: prompts/x402-overhaul/ |
| Unified Crypto API aggregator — storefront + OpenAPI | Registry api/v1/_providers.js (providerCatalog()), front door api/v1/x/[...slug].js → /api/v1/x/<provider>/<endpoint>, discovery → GET /api/v1/x, storefront pages/crypto-api.html → /crypto-api, OpenAPI 3.1 api/openapi-json.js → /openapi.json, docs § in docs/api-reference.md, dir guide api/v1/README.md |
Live | Third-party crypto/DeFi/on-chain APIs (CoinGecko, DefiLlama × 2, Jupiter, DexScreener, Solana RPC, OpenAI-compatible) re-offered as one bill: free per-IP tier → BYOK pass-through → three.ws plan → x402 pay-per-call, in that order. Everything (OpenAPI paths, the /crypto-api live table, the docs quota table) renders from providerCatalog() at request/page-load time — no hand-enumeration, so a new provider descriptor shows up everywhere with zero page edits. Test: tests/openapi-aggregator.test.js. Not to be confused with the separate /api/crypto/* bundle below (different campaign, different registry). Spec: prompts/x402-catalog/ |
| Free 3D API + docs | api/3d/index.js → /api/3d, api/3d/openapi.js → /api/3d/openapi.json, docs public/3d.html → /3d (alias /docs/3d-api) |
Live · docs surface | Front door + OpenAPI 3.1 for the free, keyless 3D API. Catalog assembler api/_lib/3d-catalog/index.js merges api/_lib/3d-catalog/*.js descriptors (currently generate, inspect) via a static import barrel (production source of truth) plus an additive dev-time directory glob; new descriptor = drop the file AND add its barrel import line; skips malformed, never throws; OpenAPI built from the same catalog via api/_lib/3d-catalog/openapi.js. Index does HTML/JSON content negotiation and advertises the paid ladder (Forge Pro, Rigged Avatars). Docs page: hero, live endpoint table, runnable quickstart with a live "Run inspect" console, embedded <model-viewer> GLB preview, and the free→paid ladder. Free endpoints: api/3d/generate.js (prompt 12), api/3d/inspect.js (prompt 13). GPT Store Actions surface: api/3d/studio.js → /api/3d/studio — a store-compliant twin of generate that strips the x402/upgrade block, drops internal ids, and runs the api/_mcp-studio/safety.js age-13+ content gate before any GPU work; backs the "three.ws 3D Studio" custom GPT (prompts/store-submissions/_generated/openai-actions.yaml + openai-gpt-config.md, store-submission prompt 12). Spec: prompts/x402-overhaul/ |
| Paid Market Data API (x402, 17 endpoints) | Registry api/_lib/market-data/registry.js, fetchers api/_lib/market-data/fetch.js, factory api/_lib/market-data/endpoint.js, routes api/x402/market-*.js → /api/x402/market-<category>, free index api/x402/market.js → /api/x402/market, catalog projection api/_lib/service-catalog/services/market-data.js, docs docs/market-data-api.md → /docs/market-data-api |
Live | Every free /markets feed (coins, coin profile, price history, categories, exchanges, derivatives, global+Fear&Greed, ETH gas, trending, DeFi TVL, chains, ~15k yield pools, stablecoins, fees/revenue, DEX volumes, hacks) wrapped as pay-per-call x402 endpoints at $0.001 USDC (Solana/Base), plus the $0.005 one-call market-pulse bundle. One registry drives the live 402s, the discovery-doc listings, and the free index — zero drift by construction; the fetchers delegate to the SAME exported builders the free pages use (api/coin/*, api/defi/*), so paid data always matches the site. Params rejected pre-settle (422) and upstream outages (503) never charge the buyer. Tests: tests/market-data-api.test.js. |
| Datapoint fabric (x402, 480k+ endpoints) | Registry api/_lib/market-data/datapoints.js, dynamic route api/x402/d/[...path].js → /api/x402/d/<family>/<id>/<metric>, free catalog api/x402/d/index.js → /api/x402/d, discovery slice buildDatapointItems in api/wk.js, docs § in docs/market-data-api.md |
Live | Every individual market datapoint as its OWN standalone paid endpoint — one URL = one value = one $0.0005 USDC x402 micro-payment (override X402_PRICE_DATAPOINT_<FAMILY>). 9 families × 68 metrics × live id spaces ≈ 484k addressable endpoints (~17.5k coins × 20, ~15.5k pools × 7, ~6k protocols × 6, chains, stablecoins, exchanges, global/gas/fear-greed) served by ONE dynamic route reading the registry; ids are runtime values, nothing hardcodes a third-party asset. Path that cannot exist → 404/422 with NO 402 issued; unknown id/outage rejects pre-settle. Free catalog enumerates families, metrics, prices, and pages each family's full live id space (200/page) so crawlers can walk the universe; the .well-known discovery doc carries a curated runtime-derived slice (~83 concrete resources). Tests: tests/market-datapoints.test.js. |
| Unified service catalog (one source, two storefronts) | api/_lib/service-catalog/index.js, descriptors api/_lib/service-catalog/services/ | Live | The canonical written-once record of every service (paid x402 + free crypto/3D bundles + OKX.AI rows). toBazaarDiscovery() generates every static /api/x402/* entry in the api/wk.js discovery doc (replacing ~1,400 lines of hand-mirrored blocks); toOkxCatalog() reproduces the OKX catalogIndex() payload exactly, with an include:'all' projection ready for listing expansion. New paid service = drop services/<slug>.js + add its barrel import row. No-drift guards: tests/service-catalog.test.js. Spec: specs/SERVICE_CATALOG.md |
| Conversational refinement + remix economy | Iterate: api/_mcp-studio/tools.js refine_model (free, on /api/mcp-studio) + mcp-server/src/tools/refine-model.js (paid stdio, $0.25); shared lineage core mcp-server/src/tools/_lineage.js. Remix (paid track): feed api/remix-feed.js → /api/remix-feed (free browse/publish/lineage), settlement api/x402/remix-asset.js → /api/x402/remix-asset + core api/_lib/remix-settlement.js + split math api/_lib/remix-royalty.js. Docs docs/remix.md, docs/mcp-studio.md. |
Live | Talk to a model to iterate it ("make it metallic") — real anchored re-generation with a revertable/branchable version lineage rendered as a viewer version strip; free on both the OpenAI 3D Studio and the paid MCP server. Creators publish a finished model as remixable (provenance + license + royalty on the existing forge_creations rows — no parallel store); another agent pays $0.25 USDC to remix it and a creator-set royalty (≤20%, capped) routes on-chain to the original creator via the audited transferSolanaUSDC rail. Split/caps/payout unit-tested (tests/remix-settlement.test.js, tests/remix-royalty.test.js, tests/refine-lineage.test.js). Free track stays crypto-free. Prompt 09. |
| Restyle Studio (material/PBR editor + AI restyle + variants) | pages/restyle.html → /restyle, src/restyle.js. PBR preset/variant library packages/viewer-presets/src/materials.js (@three-ws/viewer-presets). AI restyle + persistence core api/_lib/material-studio-store.js, free hosted endpoint api/material-studio.js → /api/material-studio; paid agent twin mcp-server/src/tools/restyle-material.js (restyle_material, $0.05 stdio MCP), thin core mcp-server/src/tools/_material-core.js. Shares the refine_model lineage core (mcp-server/src/tools/_lineage.js) so a restyle/variant is just another kind of version, feeding prompt 09 remix. Docs: docs/mcp-tools.md. |
Live | Re-skin any GLB without regenerating its mesh: live PBR editing (color/metalness/roughness/emissive/texture) with a one-click preset library (14 looks — chrome, gold, glass, wood…), seeded reproducible colorway variants (mulberry32 PRNG — same base+seed → same set), and free-text AI restyle ("make it chrome", "cyberpunk neon") via IBM Granite-proposed PBR factors applied + re-exported server-side. Every AI restyle / saved checkpoint mints a real, gltf-validator-checked, durably-stored GLB recorded in an immutable parent→child lineage — non-destructive in the durable sense, not just an in-browser Reset. Roadmap prompt 06. |
| Embodiment — a living agent body in the chat | Hosted embed pages/embodiment/embed.html → /embodiment/embed (Vite input + vercel route, frame-ancestors *); engine apps-sdk/embodiment/embodiment-stage.js (EmbodimentStage) + overlay.js; persona tools (free) api/_mcp-studio/persona-tools.js → /api/mcp-studio (create_agent_persona, get_agent_persona, persona_say) and (paid) api/_mcp3d/tools/studio.js; shared inline-body artifact api/_lib/embodiment-artifact.js; identity store api/_lib/persona-store.js (Postgres agent_personas + fs fallback + durable R2 GLB); reload route api/mcp3d/persona.js → /api/mcp3d/persona. Emotion/rig/lip-sync cores under src/embodiment/ + src/voice/. |
Live | A generated avatar becomes a persistent, named body that renders inline in ChatGPT/Claude: it lip-syncs each reply, blends the matching expression + gesture, idles between turns, and reloads by persona_id in a fresh session (the id is the capability — no sign-in). Rides the universal canonicalize/retarget clip library; a rig without face morphs animates the jaw, a non-humanoid GLB falls back to a gentle idle (decideRigMode/supportsCanonicalClips) — never a bind-pose T-pose. Zero crypto/token surface. Tests: tests/persona-store.test.js, tests/api/persona-resolve-route.test.js, tests/mcp-studio.test.js, tests/embodiment-rig-mode.test.js. Evidence: prompts/store-submissions/_generated/embodiment/. Store-submission prompt 07. |
| Spatial MCP (3D as a native response type) | Spec specs/SPATIAL_MCP.md, pure validator/builder api/_lib/spatial-mcp.js, validator tool api/_mcp3d/tools/spatial.js (validate_spatial_response, free), reference renderer public/spatial-mcp/spatial-renderer.js + demo public/spatial-mcp/index.html → /spatial-mcp, docs docs/spatial-mcp.md. |
Live · both stores | Open (CC0) shape for returning a live, interactive 3D scene as a first-class MCP tool result (scene GLB, camera, environment, animation, AR handoff, affordances) instead of a URL. Every three.ws 3D generator emits a conformant artifact under structuredContent.spatial; the validator returns actionable errors, not a boolean; the framework-free reference renderer displays any conformant payload — including one transformed from a foreign tool result (portability proof at /spatial-mcp). Zero coin surface — reusable in the OpenAI free app. Tests: tests/spatial-mcp.test.js. Evidence: prompts/store-submissions/_generated/spatial-mcp/. Store-submission prompt 20. |
| AR-ready exports ("View in your space") | Device-routing core api/_lib/ar-launch.js, UA-branched launch endpoint api/ar.js → /api/ar, MCP tool api/_mcp3d/tools/ar.js (export_ar, free), in-viewer AR button public/viewer.html, docs docs/ar.md. |
Live · both stores | GET /api/ar?src=<glb> branches on the request User-Agent server-side: iOS → Apple Quick Look (USDZ generated from the GLB on the fly by model-viewer's three.js USDZExporter — real conversion, no server USD tooling), Android → 302 Google Scene Viewer ARCore intent with browser fallback, desktop → WebGL viewer. Bad input rejected at the boundary with a designed error page. export_ar returns the AR launch link + a conformant Spatial-MCP artifact; response is OpenAI-clean (no ids/coin surface). kind=avatar is the living-agent lane: the launch page leads with a "Bring it to life" handoff into /irl?avatar=<glb> (avatar-producing tools return irlUrl automatically), and Android serves the launch page instead of the blind Scene Viewer redirect so the living path stays visible. Shared links unfurl: the launch page's og:image points at GET /api/render/glb?glbUrl= (api/render/glb.js, server-side PNG of the actual model, CDN-cached a day) and the page carries "Create your own" → /ar conversion CTAs. Tests: tests/ar-export.test.js. Evidence: prompts/store-submissions/_generated/ar/. Store-submission prompt 21. |
| AR Forge (prompt → model → your room) | public/ar-forge.html → /ar (self-contained page, CDN model-viewer + local meshopt decoder, no Vite registration needed; vercel route sets xr-spatial-tracking permissions-policy) |
Live | Mobile-first app: one prompt hits the free NVIDIA lane (POST /api/forge {backend:"nvidia"}, poll ?job=), the result renders in an AR-capable <model-viewer> with "View in your space" (WebXR / Scene Viewer / Quick Look). Non-AR devices get a QR handoff to GET /api/ar?src= (server-side UA routing) plus a copyable /viewer?src= share link. Deep link /ar?src=<glb>&title= reopens any shared model; recent forges persist in localStorage. Designed idle/working/failed/result states; https-only GLB guard. |
| Daily Forge (daily challenge + creator streak) | pages/daily.html → /daily + src/daily.js, deterministic theme rotation src/daily/daily-theme.js, streak state machine src/daily/creator-streak.js |
Live | The anonymous-first retention loop the platform lacked: the logged-in streak system (api/_lib/streaks.js) needs an account, so the no-sign-up forge majority had no reason to return. Every UTC day resolves to one curated creative theme (the same for everyone, hashed from the date — no backend, no randomness) with a running "Day N" counter; forging today's theme on the free lane lights a localStorage streak (consecutive-day state machine: extend / reset-on-gap / never-double-count, best preserved, at-risk vs lapsed display), and milestones (3/7/14/30/50/100/365) fire a celebration. The generation lands in the shared recents so it's one tap from /ar and /ar/studio; a "Fresh from the community" strip reads /api/forge-gallery?scope=community. changefreq: daily in the sitemap. Tests: tests/daily-theme.test.js, tests/creator-streak.test.js. |
| AR Studio (multi-model live camera scene) | pages/ar-studio.html → /ar/studio + src/ar-studio.js, multi-anchor WebXR session src/ar/multi-place.js, pure scene math src/ar/studio-scene.js |
Live | The standalone multi-model AR surface: place ANY number of models/avatars into one live camera view (every earlier AR lane was single-model). Model sources: in-view forge (POST /api/forge {backend:"nvidia"} runs behind the live camera, result drops into the room), the forge gallery (/api/forge-gallery — yours + community tabs), recent forges (localStorage, shared with /ar), a pasted GLB link, or repeatable ?src= deep links (https/relative only). Rendering ladder: WebXR immersive-ar with one XRAnchor per placed model + always-armed reticle (Android), getUserMedia passthrough + gyro world-lock (iOS/everywhere), grid preview + drag-look + QR handoff (desktop). Gestures: tap select, drag move, pinch resize, two-finger twist rotate; per-model duplicate/rotate/remove, clear-with-undo. Humanoids with no baked clips idle via the universal retarget (src/irl/pin-idle.js); scene persists in localStorage and the whole ARRANGEMENT (models + transforms) round-trips through a base64url #s= hash on the share/QR URL, so a composed scene reopens exactly on any device. Presence realism: WebXR placements are lit by the real room via lighting-estimation (src/ar/estimated-lighting.js, three's XREstimatedLight — real primary-light direction/colour + a live environment cube map so metal/glass reflect the actual room, reverting to baked lights when the device isn't estimating) and occluded by real geometry via depth-sensing (src/ar/depth-occlusion.js); the passthrough path matches room brightness AND colour by sampling the camera feed. Desktop keyboard controls (arrows nudge / R rotate / D duplicate / Delete). Photo capture composites camera + WebGL (src/irl/share-frame.js). Reachable from /ar, the forge AR panel, and the /viewer action sheet. Shared rooms (build together, live): "Share live" opens a room with a 6-char code; anyone who opens /ar/studio?room=CODE joins the same scene and every add / move / scale / rotate / remove delta-syncs in real time, with a live "N here" presence pill. New Colyseus room multiplayer/src/rooms/StudioRoom.js + schema multiplayer/src/studio-schemas.js (owner-gated edits, per-room/per-owner caps, per-client rate limit, https-only src validation — same discipline as WalkRoom's object channel), client wrapper src/ar/studio-net.js, and a shared logical coordinate frame src/ar/studio-coords.js (relEast/relNorth/yawDeg) so every device agrees on placement; QR-marker colocalization (src/irl/marker-anchor.js) is the co-located "same physical table" upgrade. Runs on the same Colyseus host as /walk and /irl (a new room, not a new process). Tests: tests/ar-studio-scene.test.js, tests/ar-studio-coords.test.js, tests/ar-estimated-lighting.test.js, tests/studio-room.test.js. |
| IRL (agents in the real world) | pages/irl.html → /irl + src/irl.js, WebXR placement src/ar/webxr.js + pinch src/ar/pinch-scale.js, animated Quick Look bake src/usdz-animated.js (static fallback src/usdz-pipeline.js), backend api/irl/ |
Live | Pin an agent at a real GPS spot; discovery is presence-proof-gated (docs/irl/THREAT-MODEL.md). Place in AR leads the dock on AR-capable devices: WebXR hit-test anchoring on Android with two-finger pinch resize (25%..400%) persisted to the pin (anchor_scale; the pinch lands as a follow-up PATCH /api/irl/pins {id, scale} after the placement tap), and ARKit Quick Look on iOS with the idle clip baked into the USDZ so the agent moves instead of standing in a T-pose. Discovered pins are equally alive in the in-page camera view: every mounted humanoid GLB plays the retargeted idle clip via a per-pin mixer (src/irl/pin-idle.js, phase-randomized, LOD-bounded), camera-aware gaze composes on top of the running animation, and the scene renders with ACES tone mapping + IBL + soft shadows (e2e: tests/e2e/irl-pin-idle.spec.js). Inbound /irl?avatar=<glb> is the living-agent handoff from GET /api/ar?…&kind=avatar (explicit ?avatar= wins over a saved session). Money Drops and World Lines: docs/irl.md. SDK: packages/irl/. Share (src/irl/share-frame.js, api/irl/share.js, api/irl/share/[token].js) mints a permanent, unfurlable /irl/s/:token link from the captured AR photo for the pin you just placed — never a coordinate, owner-gated, falls back to the plain native share sheet with no active pin. Analytics (api/_lib/irl-analytics.js, api/irl/analytics.js) is the first site-wide usage rollup for the feature — pins placed, nearby reads, placement method, shares, drop claims — rendered at /admin/irl-analytics, aged out by the existing hourly reaper. |
| Verifiable 3D provenance (content credentials) | Spec specs/PROVENANCE_3D.md, pure core api/_lib/provenance-3d.js, Solana anchor api/_lib/provenance-anchor.js, MCP tools api/_mcp3d/tools/provenance.js (verify_provenance free, anchor_provenance paid $0.05), free REST verify api/provenance.js → /api/provenance, viewer badge public/viewer.html, docs docs/provenance.md. |
Live (verify) · anchor gated on issuer key + devnet funds | C2PA-style signed content credentials for AI 3D: creator, prompt, model/provider, lineage, timestamp, and the GLB's sha256, ed25519-signed by the three.ws issuer with the credential hash anchored on Solana. Free public verify_provenance / GET /api/provenance?src=… recompute the hash and return `verified |
| Sperax partnership + SperaxOS plugin | pages/sperax.html → /sperax, plugin public/sperax/, manifest → /.well-known/sperax-plugin.json, tools api/chat-plugin/[tool].js → /api/chat-plugin/*, panel → /sperax/iframe/ |
In-repo · Live | Partnership landing for the SperaxOS integration: three.ws ships as a standalone plugin.delivery plugin that gives a SperaxOS agent an embodied 3D avatar (speak/gesture/emote/render_agent), bound to an ERC-8004 identity, settling over Base x402. Launch offer: free AI credits for three.ws users on chat.sperax.io — page explains what it is and how to claim. Blog: /blog/three-ws-speraxusd-integration |
| Live Agents wall (mission control) | pages/agents-live.html + src/agents-live.js → /agents-live |
In-repo · roster api/agents/public.js (sort=live), per-agent SSE api/agent-screen-stream.js |
Real-time grid of every meaningful agent, ranked by most-recent on-chain/skill action (never-used placeholders suppressed). Each card streams a live caster feed when watched, else its real agent_actions as a terminal + an "active Nm ago" recency chip. Layers: showrunner spotlight (src/showrunner.js), reputation arena (src/agents-live-arena.js), platform ticker (src/theater-feed.js) |
| X/Twitter automation toolkit | nirholas/XActions (external repo, also on npm as xactions) |
External | Formerly vendored in-repo; removed 2026-07-03 — install from npm or use the upstream repo |
| Agora — the Commons (living economy) | pages/agora.html + src/agora/ → /agora, life engine workers/agora-citizens/, read model api/agora/[action].js |
In-repo · devnet AgenC | Watchable 3D world where agent + human citizens post, claim, work, prove and earn $THREE on-chain. Play mode ("Enter the Commons") makes it walkable GTA-style — your avatar walks the square among the working NPC citizens, other humans appear live over the agora_world Colyseus room, and walking up to a citizen (proximity → E) opens its passport: src/agora/player-mode.js, pure math src/agora/player-logic.js, room multiplayer/src/rooms/AgoraRoom.js. Play mode also has an opt-in "Record on-chain (BNB testnet)" toggle (OFF by default) that gaslessly commits your moves to the WorldMoves contract every ~block via MegaFuel (self-pay fallback) and renders other on-chain players as lightweight ghost markers read back from real Moved events: src/agora/onchain-presence.js, sender src/bnb/move-sender.js, event reader src/bnb/world-presence-reader.js, pure ghost interpolation src/bnb/onchain-ghosts.js, server relay lib api/_lib/bnb/world-moves.js, config endpoint api/bnb/world-config.js. WorldMoves contract: contracts/src/WorldMoves.sol (code-complete + anvil-fork-proven; public BSC testnet deploy pending a funded deployer key — see contracts/DEPLOYMENTS.md). Arena (Competitive tasks — citizens race, first valid proof wins the whole escrow) at src/agora/arena.js; Guilds (Collaborative tasks — contributors split the reward) at src/agora/guild.js, both live-driven by api/agora/task. Spec: docs/agora.md |
/play in-game economy (cash, bank/ATM, vendors, $THREE boutique) |
Client: src/game/coincommunities.js → /play, general-store/bank NPCs src/game/npc/economy-npcs.js, store/bank UI src/game/economy-ui.js, on-chain purchase flow src/game/boutique-purchase.js, wardrobe src/game/play-systems.js. Server: multiplayer/src/rooms/WalkRoom.js (store/bank/boutique handlers), price tables multiplayer/src/shop.js, purse/bank model multiplayer/src/economy.js, on-chain settlement multiplayer/src/game-token.js |
In-repo | The GTA-style open world's real economy (W04 of the World Online program, prompts/agent-briefs/W-world-online/W00-program-overview.md). Walk up to a General Store clerk (E) to buy tools/consumables or sell gathered goods for cash, server-priced and validated every time; walk up to the Bank Teller to deposit cash into a protected balance (survives a death drop) or withdraw it. Premium wardrobe cosmetics unlock with a real on-chain $THREE payment from the player's connected Solana wallet — the server only grants the item after re-verifying the confirmed transaction on RPC. Distinct from the separate USDC/x402 avatar-shop rail (api/x402/cosmetic-purchase.js), which sells a different catalog for the standalone character creator. |
/play character & avatar customization (avatar creator, selfie→3D, wardrobe boutique) |
Lobby creator flow src/game/coincommunities-ui.js _openCreate(), selfie SDK wrapper src/avatar-creator.js, shop src/game/cosmetics-shop.js, wardrobe src/game/cosmetics-wardrobe.js, boutique NPCs src/game/npc/npc-catalog.js (npc-tailor, npc-fitting-room), boutique spawn points src/game/world-zones.js (type: 'boutique') |
In-repo | W03 of the World Online program (prompts/agent-briefs/W-world-online/W00-program-overview.md). Before dropping into /play, design an avatar from scratch or a selfie (real Avaturn SDK), upload a .glb, or sculpt in the full Avatar Studio — no sign-in required. Once in the world, the cosmetics shop/wardrobe (real x402-settled catalog, server-persisted equip) now has a physical home: walk up to Roux · Tailor to browse/buy, or Nell's Fitting Room to equip anything you own. Doc: docs/character-studio.md. |
/play combat & weapons (server-authoritative, danger zones, wanted, tombstones) |
Client: src/game/combat-system.js → /play (vitals HUD wiring, danger-zone ground, tombstone loot, hit feedback, the window.twsCombat bridge into W08's MobSystem), HUD src/game/hud/world-hud.js. Server: multiplayer/src/combat-handlers.js (mob AI, attack/loot intents, death + respawn), pure math multiplayer/src/combat.js, weapon/mob/loot tables multiplayer/src/items.js, zone geometry multiplayer/src/world-features.js, handlers wired in multiplayer/src/rooms/WalkRoom.js |
In-repo | W07 of the World Online program (prompts/agent-briefs/W-world-online/W00-program-overview.md). Equip a sword/bat/pistol/bow from the hotbar and press X (or tap the touch Attack button) to fight — but only inside one of three named danger zones (Southern Wilds, Northern Wilds, Eastern Marches); town stays lawful by construction. PvE mobs chase and swing back through the same server-side damage path a player's attack uses; a kill (mob or PvP) spills a lootable tombstone, PvP raises the attacker's wanted/heat stars (visible on WorldHud and a downed peer's nameplate), and death drops carried cash/pack before an automatic respawn in town. |
/play NPCs & world life (traffic, vendors, quest-givers, mobs) |
Manager src/game/npc/world-life.js, nav graph src/game/npc/nav-graph.js, ambient crowd/traffic src/game/npc/ambient-life.js, quest-giver NPCs src/game/npc/quest-npcs.js, quest-zone waypoints src/game/npc/quest-markers.js, Jobs Board UI src/game/quests-ui.js, W07-gated mobs src/game/npc/mobs.js. Server: quest engine multiplayer/src/quests.js, quest zones multiplayer/src/quest-zones.js, handlers in multiplayer/src/rooms/WalkRoom.js | In-repo | W08 of the World Online program (prompts/agent-briefs/W-world-online/W00-program-overview.md). A deterministic nav graph drives client-side ambient pedestrians + ring-road traffic that read identically for every player without a single packet — real gameplay stays server-authoritative. Five quest-giver NPCs (Dockmaster Reyes, Warden Okoro, Cook Mara, Foreman Dell, The Fixer) front the jobs board the quest engine (W05) already ran server-side but no client ever reached; pressing E opens the real board, accepting a job drops a waypoint at its objective (goto zones auto-complete by walking there, interact zones get their own "press E"), and finishing pays real cash server-side. Hostile mobs are live: W07's CombatSystem (src/game/combat-system.js) installs the window.twsCombat contract this module's mobs were built against, so MobSystem renders real server-authoritative PvE hostiles with zero changes here. Two jobs — cross-town-delivery (North↔South) and east-west-express (East↔West) — are real driving missions: each goto leg is flagged vehicle: true and only completes off the authoritative vehicle-driver map (multiplayer/src/vehicles.js), so walking through a depot never counts, only driving through it does. Depots sit on the avenue vehicle spawns, so a car is always parked at the start. Tests: tests/quests-vehicle-delivery.test.js. |
Frame governor & power saver (/play, /club) |
src/shared/frame-governor.js, wired in src/game/coincommunities.js, src/club.js, src/club-entrance.js; toggle UI in src/game/coincommunities-ui.js | Live | Shared frame-rate governor for the heavy 3D surfaces: 60fps while active, 30fps when idle or unfocused, plus a user-facing Power-saver mode (30fps + lighter rendering, "for a cooler, quieter machine") persisted in localStorage tws-power-saver and shared across surfaces (getPowerSaver/setPowerSaver/onPowerSaverChange, trackWindowFocus). Tests: tests/frame-governor.test.js |
/play Wheel of Fortune (Fortune's Folly — free/paid $THREE spins) |
Client: src/game/wheel-station.js (the plaza landmark, proximity prompt, E to spin — lazy-imports the actual UI on first interact), spin UI src/game/spin-wheel-ui.js (20-segment wheel, free/paid flow, wallet signing). Server: multiplayer/src/spin-wheel.js (paytable, RNG, level/cooldown/pack gates, handlers), split-payment settlement multiplayer/src/game-token.js (buildSpinPayment/verifySpinPayment — the same primitives the $THREE boutique uses), wheel location multiplayer/src/world-features.js WHEEL, persisted cooldown field in multiplayer/src/economy.js, handlers wired in multiplayer/src/rooms/WalkRoom.js |
In-repo | W09 of the World Online program (prompts/agent-briefs/W-world-online/W00-program-overview.md). Walk up to the wheel in the plaza and press E: one free spin every 12h (a real persisted cooldown — survives a disconnect, unlike the ephemeral per-action cooldowns everything else on this row's neighbors use), or pay $3 in $THREE — split 50% to the holder-rewards pool / 50% to the treasury, verified on-chain before any prize is granted, mirroring the boutique's proven settlement pattern exactly. Gated behind an average skill level of 3 (a light anti-farm floor, not a grind) and never lets a won prize get lost to a full pack — room for at least one possible item prize is checked before a spin is even offered, paid or free. All 20 wedges are equal-odds by design, matching the client's fixed-angle wheel rendering exactly (see the header note in spin-wheel.js on why that must never drift). Tests: tests/spin-wheel.test.js. |
/play friends & presence (drawer, cross-world DMs) |
Client: src/game/friends-panel.js (shared with /walk), mounted in src/game/coincommunities.js _openFriends()/_closeFriends(), HUD button + unread badge in src/game/coincommunities-ui.js, account-level state/polling in src/friends.js. Server: signed ticket verify + socialHub registration in multiplayer/src/rooms/WalkRoom.js, hub in multiplayer/src/social-hub.js |
In-repo | W09 of the World Online program (prompts/agent-briefs/W-world-online/W00-program-overview.md). Press J or the HUD Friends button to open a right-docked drawer showing your account's friend graph — live online/offline presence per coin world, requests, and DM threads — the same graph and threads /walk and the standalone /friends page already share. community-net.js now carries a signed presence ticket into every walk_world join and forwards the server's social push onto its own event bus, which is what actually makes a /play player visible to friends and able to receive a live DM — previously /play joined anonymously to the social graph even when signed in, so every player showed offline and DMs were dropped. Tests: tests/play-friends-presence.test.js. |
/play Robinhood Chain worlds (NOXA + The Odyssey coins, live-trade animation) |
Firehose worker workers/robinhood-feed/ (watches NOXA + Odyssey launchpads + their Uniswap v3 pools, normalizes to the pump-compatible event shape, serves SSE/WS/REST). API bridge: api/robinhood/coin-trades.js (the in-world chart-screen's trade feed), api/robinhood/play-worlds.js (the /worlds lobby's Robinhood Chain tab). Client: chain-flavored biome hoodchain in src/game/world-env.js (auto-pinned in src/game/coincommunities.js isRobinhoodCoin()), trade-feed endpoint routing in src/game/chart-screen.js, lobby tab + EVM-address support in src/worlds-lobby.js (routes Robinhood coins to /play, unchanged pump.fun coins stay on /temporary) |
In-repo | Every Robinhood Chain memecoin (chain 4663) gets the same treatment pump.fun coins already have: a deterministic 3D world seeded by its contract address, in a distinct dark ticker-tape palette, with real launchpad/Uniswap-v3 trades rippling the space live via MarketReactor. Multiplayer (walk_world, filtered by coin+tier) needed zero code changes — it already keys rooms by an opaque coin id string. isValidToken() in api/_lib/coin-communities.js was widened to accept EVM addresses (it previously 400'd every EVM-chain world's Town chat, even though the CHAINS list already declared ethereum/base/bsc support). Tests: workers/robinhood-feed/tests/normalize.test.js (against real captured on-chain logs). |
| Sealed wallet gift drops (send/claim) | Client: src/pages/sealed-drops.js — create + "My drops" sections mounted into public/vanity-wallet.html (#drop-create/#drop-mine, below the vanity grinder — vanity pattern fields are shared), claim flow on its own page pages/drop.html → /drop/:id (24-hex-char id, routed in vite.config.js dev middleware + vercel.json). Crypto: src/solana/vanity/sealed-envelope.js (ECIES seal/open, X25519 keygen — all client-side, three.ws never sees a plaintext key), src/solana/vanity/drop-protocol.js (claim-token derivation). Server: api/vanity/drops.js (create/claim/reveal/reclaim, on-chain funding), OG card api/og/sealed-drop.js |
In-repo | Fund a fresh wallet — optionally vanity-ground with the same prefix/suffix grinder above — wrap it in a sealed link, and send it. Two seal modes: a bearer link (the claim key rides in the URL fragment, anyone with the full link claims once) or sealed to a recipient's X25519 key (only they can ever open it, even with the link). The create fee settles via x402; the gift amount funds on-chain into a fresh wallet server-side. Claiming decrypts entirely in the browser and offers the recovered seed phrase/secret key for import — the server only ever sees the sealed ciphertext. "My drops" (browser-local, by a random sender tag) lists what you've sent so expired-unclaimed gifts can be reclaimed. |
| Premium vanity inventory (sell pre-ground addresses) | public/vanity/premium/ → /vanity/premium, batch grinder workers/vanity-grinder/, store api/_lib/vanity-inventory-store.js, sell api/x402/vanity-premium.js, replenish api/cron/vanity-inventory-replenish.js |
In-repo · GCP spot CPU | Long (4–5+ char) brandable Solana addresses ground ahead of time on cheap spot CPU, sealed at rest (AES-256-GCM or GCP-KMS envelope, api/_lib/vanity-vault.js), and sold from stock via x402 — priced by rarity ($1–$50) on vanity-premium, or by fixed 4–5 char tiers ($2.50/$10) directly through /api/x402/vanity (instant delivery, source:"inventory") and the pump-launch vanity upsell — delivered exactly once, ciphertext destroyed on delivery. An hourly cron watches stock and fires a fresh grind batch (Cloud Run Job) when low. Free vanity_premium MCP browse tool. Runbook: docs/ops/gcp-credits.md |
| Embed examples | examples/ | In-repo | embed-test.html, web-component.html, two-agents.html, minimal.html, agent-native-3d/ (below) |
| Agent-native 3D + embeddable distribution | MCP tool api/_mcp/tools/agents.js (attach_avatar_to_agent); shared oEmbed provider api/agent-oembed.js → /api/oembed + builder api/_lib/embed.js (forgeEmbedTarget, shared by get_embed_code in api/_mcp/tools/embed.js); Forge share page oEmbed discovery api/forge-share.js → /forge/share/:id; distribution snippet builders src/forge-embed-snippets.js + panel src/forge-embed-panel.js; autonomous demo examples/agent-native-3d/ |
In-repo | Closes the loop: create → own → discover/remix → use everywhere. attach_avatar_to_agent gives a registered agent identity a persistent body (chains into register_agent for on-chain identity + anchor_provenance for a signed authenticity credential). Any Forge creation now unfurls via real oEmbed (paste /forge/share/:id into Notion/Discord/Slack) with the same type:rich iframe payload get_embed_code returns via MCP. The Forge "Embed this model" panel hands out five real distribution flavours from one GLB — iframe, <model-viewer>, <agent-3d>, a @three-ws/page-agent talking guide, and a @three-ws/walk companion — all built from one shared, pure snippet module so every surface stays byte-identical. examples/agent-native-3d/run.mjs drives the full agent-native chain live against /api/mcp-studio (mesh_forge → rig_mesh → create_agent_persona → persona_say → get_agent_persona → every distribution snippet) with zero mocks and a documented, logged fallback if the shared free-tier generation lane is rate-limited at run time. Spec: specs/EMBED_SPEC.md. Docs: docs/mcp.md#attach_avatar_to_agent. Roadmap prompt 10 (closes the roadmap campaign). |
| Animation pipeline | public/animations/ + scripts/build-animations.mjs | In-repo | Mixamo source FBX + GLB retargeting pipeline · see docs/3d-asset-pipeline.md |
| Self-hosted 3D GPU fleet (the engines behind the Forge) | workers/model-trellis/, workers/model-hunyuan3d/ (2.0 + 2.1 PBR + 2.1 RTX), workers/model-triposg/, workers/model-triposr/, workers/unirig/, workers/avatar-reconstruction/, CPU stages workers/rembg/ · workers/remesh/ · workers/segment/ · workers/stylize/ | Live · Cloud Run GPU (us-central1 + trellis/hunyuan replicas in us-east4) | Every generation engine the Forge dispatches to, each with its own cloudbuild.yaml. L4 services share a 3-GPU regional quota (increase to 16 pending); the Hunyuan3D-2.1 PBR realism lane also ships an RTX PRO 6000 build (model-hunyuan3d-21-rtx, quota granted 1000) as the warm primary. Ops map: docs/ops/gcp-credits-plan.md |
| Avatar Composer (modular studio generation) | api/_lib/avatar-composer/ | In-repo · wired into the studio seed lane | Assembles a rigged, ARKit-expression-ready GLB by mixing skinned parts (hair / top / bottom / footwear / glasses) across the RPM base bodies onto one shared 67-joint skeleton, then recolors each part and scales the rig — the Ready-Player-Me / Avaturn "one skeleton, many parts" architecture in pure JS on @gltf-transform, no GPU or external service. Replaces the recolor-one-of-five-bodies studio lane so two draws almost never look alike. Borrowed parts keep their own inverse binds but remap onto the identity skeleton; mixing is restricted to a base's rest-pose group so parts always fit. Consumed by api/cron/avaturn-seed-cron.js (legacy studio-avatar.js recolor is the fallback) and the one-click api/avatars/surprise.js endpoint (instant avatar, previewed in public/gallery/surprise.js). Docs: api/_lib/avatar-composer/README.md. Tests: tests/avatar-composer.test.js |
| Auto-rigging worker (Mixamo skeleton + ARKit-52 blendshapes) | workers/rig/ | Code-complete · deploy pending (asset staging + Cloud Build, see its README) | Make-It-Animatable engine (MIT) predicts the 52-bone Mixamo skeleton + weights; workers/rig/rig_glb.py grafts them into the original GLB (textures untouched); ICT-FaceKit (MIT) ARKit-52 expression transfer for emotions/lipsync. Contract-compatible replacement for the retired unirig service behind GCP_UNIRIG_URL; cutover is one env-var update. Canonicalization proof: rig worker skeleton cases in tests/glb-canonicalize.test.js |
| Animation gallery | pages/animations.html + src/animations-gallery.js | Live at /animations |
2,100+ clips with poster thumbnails (scripts/build-animation-thumbnails.mjs), derived categories (src/animation-categories.js), shared live-preview engine (src/animations-live-preview.js) · see docs/animations.md |
| Avatar thumbnail coverage | api/_lib/avatar-thumbs.js + crons api/cron/avatar-thumbnail-backfill.js (absent thumbnails, */5) and api/cron/avatar-thumbnail-render.js (stale marketplace thumbnails, */10) |
Live | The single owner of avatars.thumbnail_key. Enforces the invariant that a thumbnail key is persisted only after its R2 object is confirmed to exist — a key pointing at a missing object makes R2 return 404 text/plain, which Chrome blocks as ERR_BLOCKED_BY_ORB inside an <img>. Fills coverage cheapest-first: zero-copy adoption of forge_creations.preview_key, then a headless-chromium GLB→PNG render to thumb/<avatarId>.png (api/_lib/render-glb.js). Bounded retries via the avatar_thumbnail_backfill claim ledger (migration), with isBrowserInfrastructureError() separating an OOM-killed browser from a genuinely broken model so a crash never retires healthy avatars. Bulk runner: scripts/backfill-avatar-thumbnails.mjs (--status, --adopt-only, --loop, --reset-infra). Docs: docs/avatar-thumbnails.md. Tests: tests/avatar-thumbs.test.js, tests/home-thumbnail-orb.test.js |
| Forge model categorization | Classifier api/_lib/forge-classify.js, wired at generation in api/_lib/forge-store.js (createCreation), backfill scripts/backfill-forge-categories.mjs, coloured badges in src/forge-showcase.js + /forge-studio twin |
Live | Assigns every forge model a model_category (avatar/accessory/item/scene/creature/vehicle/other) from its prompt with a deterministic, dependency-free keyword classifier — most-specific-first so "a knight riding a horse" is an avatar, not a creature. Nothing set the category before, so ~99.8% of the corpus was other and the category badges, filters, and Forge-Off category dimension were dead; the classifier now runs inline on every generation (all lanes) and reclassifies ~85% of the 9.8k-row back catalogue (dry-run verified). Coloured category pills render across the showcase/gallery/community feed. Tests: tests/forge-classify.test.js. |
| Forge thumbnail coverage | api/_lib/forge-thumbs.js + cron api/cron/forge-thumbnail-backfill.js (*/5) |
Live | Gives every finished forge model a real picture. The dominant free NVIDIA/TRELLIS lane is geometry-first and paints no reference image, so ~83% of finished forge_creations land with preview_image_url = NULL and render as gradient placeholders on every browse surface (showcase, gallery, /community, /search, creator portfolios). This cron claims the newest previewless models, renders each GLB to a 768² PNG via the shared headless-chromium renderer (api/_lib/render-glb.js), uploads it, and fills the preview slot — object confirmed in R2 before the key is committed (same ORB-safety invariant as avatars), and fill-only so a maker's captured poster always wins. Self-provisioning claim ledger (forge_thumbnail_backfill, created at runtime), bounded attempts, lease-based reclaim, browser-death batch abort with attempt refund. ?dry_run=1 reports coverage. Tests: tests/forge-thumbs.test.js. |
| Forge-Off (community voting + weekly board) | Store api/_lib/forge-store.js (castVote/removeVote/listShowcase sort+voter/forgeOffWeekStart), endpoint api/forge-vote.js, board read api/forge-gallery.js (scope=community&sort=top&window=week), weekly crown cron api/cron/forge-off-crown.js (7 0 * * 1), UI src/forge-showcase.js + /forge-studio twin src/forge-studio/forge-showcase.js, schema migration 20260625120000_forge_board.sql |
Live | Turns the "Fresh from the Forge" strip on /forge into a live board: auth-free upvotes (one per browser, keyed to the same forge:cid id as "Your creations"), a Fresh/Top-this-week sort toggle, optimistic vote pills that reconcile against the authoritative vote_count (recomputed from forge_votes, never a drifting counter), and a Monday-00:07-UTC cron that permanently crowns each week's top-voted creation into forge_board_winners. The crown is the writer the Sketchfab showcase cron's strongest tier had been waiting on. Docs: docs/forge-off.md. Tests: tests/api/forge-gallery-community.test.js |
| Sketchfab showcase (community models → official account) | Cron api/cron/sketchfab-showcase.js, lib api/_lib/sketchfab.js, ledger migration api/_lib/migrations/20260714130000_sketchfab_uploads.sql | Live · dormant until SKETCHFAB_API_TOKEN is set |
Publishes the best community forge models to the official three.ws Sketchfab account, prompt and backlink included. Selection order: forge-board winners (now populated by the Forge-Off crown cron), then top-voted (>=1 vote), then creator-accepted (accepted or downloaded, refinement children excluded, title-quality heuristic). Brand safety is two layers: a SQL denylist plus NemoGuard re-moderation; blocked rows park as blocked in the sketchfab_uploads ledger (states pending/uploaded/live/failed/blocked). ?dry_run=1 exercises selection before the token is wired; SKETCHFAB_UPLOADS_PER_RUN clamps 1-5 (default 2). Docs: docs/sketchfab.md |
| Third-party display-name safety | api/_lib/display-name-safety.js, applied at ERC-8004 metadata hydration in api/cron/[name].js | Live | The ERC-8004 crawler indexes 126k+ on-chain agents and renders each one's name/description/image from attacker-controlled metadata. Visibility used to be decided solely by the agent's own meta.active, so a Base-registered agent whose name was a racial slur shipped to /marketplace. matchedSlurStem() now withholds such rows (active = false), which removes them from every feed at once since explore/marketplace/agents/search all filter active = true. Deliberately narrow — whole-word hate slurs only, never general profanity, and hex-address aware: leet folding turns 0xdb6b887289c380… into letter soup, so long alphanumeric runs are excluded from the spaced-out-evasion pass. A false positive silently delists a legitimate agent, so precision outranks recall. Backfill for already-indexed rows: scripts/deactivate-slur-agents.mjs (--dry-run). Tests: tests/display-name-safety.test.js — pins the real agent names an earlier substring matcher wrongly flagged. |
| FBX → GLB conversion | scripts/fbx-to-glb.mjs | In-repo | Skinned/animated FBX → GLB (FBX2glTF), npm run convert:fbx |
| Avatar schema | packages/avatar-schema/ | Published as @three-ws/avatar-schema |
JSON Schema for on-chain avatar manifests |
| 3D-in-markdown toolkit | packages/readme-3d/ | Standalone-ready (npm readme-3d, extraction script for nirholas/readme-3d) |
CLI + library converting GLB/glTF/OBJ/STL into the ASCII-STL blocks GitHub renders as interactive 3D in markdown; mesh simplification to the 512 KB limit, check size gate, tutorials, examples, Pages docs site, Claude skill. Powers the live avatar in README.md. Tests: packages/readme-3d/test/ |
| Integration demos | multiplayer/, examples/coach-leo/ | In-repo | Multiplayer and VR demos |
| Avatar service backend | api/ + workers/ | In-repo | Serverless-style handlers + Cloudflare workers |
| Production server (Google Cloud Run) | server/ + Dockerfile | Live | Single Express container serving the static frontend, the vercel.json route table, and all api/** handlers with Vercel-parity routing; deploy via npm run deploy:gcp (server/cloudbuild.yaml), crons via scripts/create-gcp-scheduler.mjs · see server/README.md |
| Multiplayer 3D world (world.three.ws) | deploy/world/ — Dockerfile, cloudrun.yaml, apply-hardening.sh, patches in deploy/world/patches/; health monitor api/cron/world-health.js | Live · hyperfy-world on Cloud Run |
Hyperfy pinned to an exact upstream commit and rebuilt with three local patches (server-side upload cap, /status blueprint-asset enumeration, fail-closed-without-ADMIN_CODE). World state (SQLite + uploaded assets) lives in the GCS bucket world-three-ws-data mounted at /app/world, so the container is stateless. The world is gated: without ADMIN_CODE Hyperfy's effectiveRank falls back to Ranks.ADMIN and every anonymous visitor gets server-side build rights — the fail-open default that emptied the world on 2026-06-12. Deploy + verify with bash deploy/world/apply-hardening.sh; builders unlock in-world with /admin <code>. See deploy/world/README.md |
| On-chain identity | contracts/ | In-repo | Foundry-based on-chain agent identity, ERC-8004 |
| On-chain skill licenses | contracts/skill-license/ → /api/skills/license-onchain |
In-repo | Anchor program: each purchased skill = a 1/1 SPL NFT + SkillLicense PDA, a trustless alternative to DB-backed access checks. Backend: api/_lib/skill-license-onchain.js |
| Tokenized 3D (mint an avatar as an NFT) | api/_lib/tokenize-3d.js + api/_lib/tokenize-3d-metadata.js, MCP tools api/_mcp/tools/tokenize.js (mint_3d_asset, get_3d_asset_onchain), signed ledger provenance api/_lib/asset-provenance.js, launch directory api/v1/tokenized/launches.js → GET /api/v1/tokenized/launches, public gallery pages/minted.html + src/minted.js → /minted |
In-repo | Mint a generated/owned GLB as a Metaplex Core NFT whose media is a live 3D viewer (GLB under animation_url), with baked provenance + enforced capped royalties (10%), idempotent, devnet-default. Every generated avatar AND every mint also appends an ERC-191-signed record to the agent_actions ledger (verifiable via @three-ws/provenance-mcp's query_action). A mint naming parent_mint (a remix) routes the parent creator's royalty out of the mint fee as a real on-chain USDC transfer (mainnet, x402-collected calls only) — api/_lib/remix-royalty.js split math, api/_lib/remix-settlement.js payout wallet. Premium/token-gated generation: the Forge High tier (200k poly + PBR) is $THREE hold-or-pay gated — api/forge.js requireFeatureAccess('forge.high') + api/_lib/three-tier.js tier ladder, x402 pay-per-use or credits fallback; Draft/Standard stay free and ungated. Launch record: tokenized_3d_assets + remix-royalty columns. Public gallery: /minted renders the launch directory live (model-viewer thumbnails, network toggle, royalty + remix badges) — the NFT counterpart of /launches. Docs: docs/mcp.md. E2E: scripts/tokenize-3d-devnet-e2e.mjs. Tests: tests/tokenize-3d.test.js, tests/tokenize-3d-remix-royalty.test.js, tests/asset-provenance.test.js |
| Token-gated 3D embeds (holder-only interactive scenes) | Gate config + on-chain verify api/_lib/embed-gate.js, access tokens api/_lib/embed-gate-token.js, endpoints api/embed/gate-create.js + api/embed/gate-verify.js, gate-aware resolver api/embed/resolve.js, MCP tool api/_mcp/tools/embed.js (create_gated_embed), widget public/embed/v1.js (<three-d>) + standalone host public/embed/v1/gated.html → /embed/v1/gated |
In-repo | create_gated_embed(asset_id, gate) turns an avatar or on-chain agent you own into a holder-only interactive <three-d> embed — visitors must prove a real, server-verified SPL balance (SIWS challenge → nonce → signature → Solana RPC read, never a client-reported number) before the live scene renders; below the bar they see a designed locked teaser + connect-wallet CTA. mint defaults to $THREE but is a runtime parameter (coin-agnostic plumbing). Anti-abuse: short-lived signed access tokens (auto re-verify on expiry) + per-IP/per-wallet rate limits. Storage: embed_gates + embed_gate_nonces. Spec: specs/EMBED_SPEC.md. Docs: docs/token-gated-3d-embeds.md. Tests: tests/embed-gate.test.js |
| Launch Studio (coin-launch use cases) | api/_lib/launch/ → /launch-studio, api/pump/launch-studio.js, public/launch-studio/launch-studio.js |
In-repo | Engine + catalog of 50 declarative launch recipes — reward coins for trending GitHub repos/creators (github-trending.js) and coins riding live narratives (launcher-trends.js). Live preview → /launch handoff. Docs: docs/launch-usecases.md, api/_lib/launch/README.md |
| Memetic Launcher (per-user autonomous coin launcher) | pages/launcher.html → /launcher + src/user-launcher.js, API api/launcher/me.js, engine api/_lib/launcher-engine.js (cron api/cron/launcher-tick.js), trends api/_lib/launcher-trends.js, admin/global scope pages/admin/launcher.html → /admin/launcher |
In-repo | Every user designs their own autonomous pump.fun launcher: mode (trend/meme/hybrid/random), trend sources, cadence, network. Preview (default) records picks without moving SOL; Live mints for real, SELF-FUNDED — each launch paid by the user's own agent wallet (base ~0.022 SOL + dev buy), never master SOL, with typed go-live confirm, dev-buy + daily-SOL-cap clamps, unfunded-wallet skips (breaker-immune), and an agent-wallet funding panel with live balances. Global scope stays master-funded + owner-allowlisted. Docs: docs/memetic-launcher.md. Tests: tests/user-launcher.test.js, tests/launcher-engine.test.js |
| Avatar Seeder control room | pages/admin/seeder.html + src/admin-seeder.js → /admin/seeder, backend api/admin/seeder.js |
In-repo (admin, noindex) | Arm/disarm the headless Avaturn seed cron, watch live throughput + rig rate, and preview freshly-forged rigged avatars in 3D. Toggles the avaturn_seed runtime flag. Flags: api/_lib/flags.js + api/admin/flags.js. Docs: docs/ops/runtime-flags.md |
| On-chain agent invocation | contracts/agent-invocation/ | In-repo | Anchor program: verifiable agent-to-agent skill invocation events. SDK: agent-protocol-sdk/ |
| Cross-chain SDKs | sdk/, solana-agent-sdk/, agent-payments-sdk/, agent-protocol-sdk/ | Published | Cross-chain agent SDKs |
| MCP integration | mcp-server/, mcp-bridge/, packages/*-mcp/ | 35 npm servers + 7 hosted remote (42 total, incl. the free /api/mcp-studio 3D Studio), all in the MCP registry — canonical metadata: prompts/store-submissions/_generated/mcp-listing-source.json |
Model Context Protocol surface — full server list in docs/mcp.md |
| Agent Skills pack | .agents/skills/ → manifest .agents/skills/SKILLS.md, .agents/skills/skills-pack.json | In-repo; bundled in the three-ws-core plugin |
40 portable SKILL.md folders (Agent Skills open standard) for any Claude surface — 3d/creative (cross-platform-safe), wallet/payments, intel/trading. Regenerate manifest: node scripts/build-skills-pack.mjs. Docs: docs/agent-skills.md |
| SNS naming + pay-by-name | api/sns.js, api/sns-subdomain.js, api/threews/subdomain.js, api/x402/pay-by-name.js, src/solana/sns-subdomain.js, pages/threews-claim.html | In-repo | *.threews.sol subdomain mint, x402 payments addressed by name. Env: THREEWS_SOL_PARENT_SECRET_BASE58 |
| Self-hosted x402 facilitator + ring economy | api/x402-facilitator/[action].js, api/_lib/x402/self-facilitator.js, api/x402/ring-settle.js, api/_lib/x402/pipelines/ring-rebalance.js, api/x402-ring.js, scripts/x402-ring-setup.mjs | In-repo (off by default) | Closed-loop agent-to-agent x402: platform wallets pay platform endpoints, settled in-house (no external facilitator). Fee-minimized, SOL-floor guarded, internal-labeled. Env: X402_SELF_FACILITATOR_ENABLED, X402_FEE_PAYER_SECRET_BASE58, X402_TREASURY_SECRET_BASE58. See docs/x402-ring-economy.md |
| Ring payer pool (many distinct payers) | api/_lib/x402/pool.js, api/_lib/x402/pipelines/ring-pool-fund.js, scripts/x402-ring-pool-setup.mjs, migration api/_lib/migrations/2026-07-17-x402-ring-pool.sql | In-repo (off by default) | Reused rotating payer wallets (500–1,000) the ring tick cycles through so the closed loop shows many distinct, attributed payers at 1 tx/settle. Keys secret-box-encrypted in x402_ring_pool; pubkeys mirrored into x402_ring_wallets(role='pool') so they join the controlled set automatically; NOT in solana-signers.js so sweepback never touches them. LRU rotation (claimNextPayer), batched threshold funding (ring-pool-fund). Env: X402_RING_POOL_ENABLED, X402_RING_POOL_SIZE. See docs/x402-ring-economy.md |
| $THREE micro-buy loop (x402 buy pressure) | Endpoint api/x402/three-buy.js → /api/x402/three-buy, driver api/cron/three-buy-loop.js, engine api/_lib/token/microbuy.js, shared Jupiter client api/_lib/token/jupiter.js, ledger migration 20260717233000_three_microbuy.sql |
In-repo (off by default) | Many tiny, real USDC→$THREE market buys per minute (target ~60/min), each triggered by (and paid through) a settled x402 call: the x402 toll routes to the ring treasury like every other endpoint, and the paid good is one on-chain buy on Jupiter. BUY-ONLY — never sells; accrued $THREE swept to the treasury. High-frequency sibling of the daily buyback (api/_lib/token/buyback.js). Real spend hard-bounded by a UTC-daily USD ceiling enforced atomically (Redis reserve-before-buy). autobuy:false in ring-catalog.js so the generic ring never fires it. Env: THREE_MICROBUY_ENABLED, THREE_MICROBUY_SECRET_KEY_B64 (or reuses the buyback wallet), THREE_MICROBUY_PER_TICK, THREE_MICROBUY_DAILY_CAP_USD. See docs/three-microbuy.md. |
| Ring economy operator dashboard | pages/admin/ring.html + src/admin-ring.js → /admin/ring, backend api/admin/ring-dashboard.js |
In-repo (admin, noindex) | Live eyes on the closed-loop x402 ring: per-minute settlement pulse (green/amber/red heartbeat), loop diagram with live wallet balances + floors, streaming activity feed (agent attribution, Solscan links, skip/fail reasons), fee-burn vs daily budget, integrity (leak scan + reconciliation), per-endpoint coverage. One aggregate read model composes /api/x402-ring; admin/Bearer-secret authed. Labels volume as internal dogfooding. See docs/x402-ring-economy.md |
| Economy funding root (master wallet) | api/_lib/economy-master.js, cron api/cron/treasury-topup.js, registry api/_lib/solana-signers.js | In-repo (inert until keyed) | One master wallet (WwwuGbq…T3WwW, ECONOMY_MASTER_SECRET_BASE58) auto-tops-up every other Solana engine below its floor. Funder-only — never trades/settles; reserve/per-engine/per-run guarded; allowlisted to registry wallets; fee-minimized. See docs/economy-master.md + the signer registry api/_lib/solana-signers.js |
| Economy master audit ledger + breach monitor | ledger api/_lib/economy-ledger.js (schema), reconcile cron api/cron/economy-reconcile.js, export scripts/economy-ledger-export.mjs | In-repo | Tamper-evident (SHA-256 hash-chained) accounting book of every SOL movement from the master, with running balance + USD-at-transfer-time. The reconcile cron checks it every 30 min for tamper, unrecorded on-chain outbound (breach/key-compromise), and on-chain integrity; findings land in payment_reconciliation. Accounting CSV/JSON export. See docs/economy-master.md |
| Autonomous trading experiment | policy scripts/trading-experiment-setup.mjs, laddered exit workers/agent-sniper/exit-logic.js (decideLadderedExit), no-Mayhem gate workers/agent-sniper/mayhem-gate.js, journal workers/agent-sniper/journal.js → api/sniper/journal.js |
In-repo | One agent, ~10 SOL, newer pump.fun launches ($10k–$100k mcap, no Mayhem). Take-initials-at-2× laddered exit keeps a moon bag (never a 100% exit up), hard stop-loss underneath. Every decision journaled with its reasoning. UI-funded, simulate-first. See docs/trading-experiment.md |
| Trading Copilot (conversational) | client src/agent-copilot.js, hub tab src/agent-wallet-hub/tabs/copilot.js, server api/agents/copilot.js → POST /api/agents/:id/copilot (SSE) |
In-repo | Owner-only chat over an agent's Solana wallet: text/voice in, markdown replies, live data cards (portfolio, firewall, quote, smart-money, intel) and confirm-before-execute trade/limits cards. Read-only tools run server-side; state-changing intents return as proposals the browser re-quotes and runs through the existing spend guards + firewall + custody audit. Slash commands, copy/regenerate, localStorage persistence. See docs/trading-copilot.md |
| Real-funds risk acknowledgment | gate public/risk-ack.js → /legal/risk, app wrapper src/shared/risk-ack.js, record endpoint api/legal/risk-ack.js, disclosure public/legal/risk.html |
In-repo | Versioned, once-per-browser acceptance dialog every money-committing surface awaits before executing (trade, snipe, withdraw, swap, launch, x402, onramp — devnet exempt). Acceptances persist in audit_log (risk-ack-accept). See docs/risk-acknowledgment.md |
| Global markets + coin detail pages | pages/coins.html + src/coins-index.js → /coins, pages/coin.html + src/coin-page.js → /coin/:id, backend api/coin/ (detail, tickers, ohlc, markets, news, global over api/_lib/coingecko.js) |
In-repo | CoinGecko-style markets index (global stats bar, sortable top-coins table, search, sparklines) + a rich detail page per coin: interactive chart, 1h→1y price-performance matrix, market-stats grid, circulating/max supply bar with Mcap/FDV ratio, ATH/ATL with drawdown & recovery multiple, community sentiment vote split, community + developer (GitHub) activity grids, a paginated exchange-listings table (api/coin/tickers, ±2% depth + trust) linking into exchange detail, related news, and full link pills (site/social/whitepaper/forum/chat/explorers). Design adopted from cryptocurrency.cv; accepts CoinGecko slugs or Solana mints. Docs: docs/coin-pages.md |
| Market tools (heatmap, sentiment, gas, compare) | pages/heatmap.html + src/heatmap.js → /heatmap, pages/fear-greed.html + src/fear-greed.js → /fear-greed, pages/gas.html + src/gas.js → /gas, pages/compare.html + src/compare.js → /compare; backend api/coin/fear-greed.js, api/coin/gas.js |
In-repo | Four tools extending Markets, same design system: treemap heatmap (market-cap-sized tiles), Fear & Greed gauge + history, live Ethereum gas tracker (keyless eth_feeHistory), and up-to-4-coin compare (overlay perf + stats). All real key-free data; cross-linked from the markets table. Docs: docs/coin-pages.md |
| Market tools II (screener, categories, exchanges, derivatives, converter, DeFi, chains, stablecoins) | Pages+JS → /screener /categories /exchanges /derivatives /converter /defi /chains /stablecoins; backend api/coin/ (categories, exchanges, derivatives, rates) over CoinGecko + api/defi/ (protocols, chains, stablecoins) over DeFiLlama |
In-repo | Eight more Markets tools, same design system: token screener + category rankings + exchange/derivatives tables + crypto⇄fiat converter (CoinGecko), plus a DeFiLlama trio — DeFi TVL by protocol, chains by TVL, stablecoins with peg health. All real key-free data; cross-linked from the markets table. Docs: docs/coin-pages.md |
| Market surfaces III (protocol/chain/stablecoin detail + fees, DEX volumes, hacks, trending) | Detail pages → /protocol/:slug /chain/:name /stablecoin/:id over api/defi/protocol.js, api/defi/chain.js, api/defi/stablecoin.js; surfaces → /fees /dex-volumes /hacks over api/defi/ (fees, dex-volumes, hacks over DeFiLlama) + → /markets/trending over api/coin/trending.js (CoinGecko /search/trending); list rows in src/defi.js, src/chains.js, src/stablecoins.js now deep-link into the detail pages |
In-repo | Turns the DeFiLlama list pages into full detail experiences: a protocol page (TVL history + hallmark markers, per-chain breakdown, fees/revenue, funding rounds, methodology), a chain page (TVL + stablecoin + DEX-volume charts, top protocols), a stablecoin page (supply history, per-chain distribution, peg-deviation badge). Plus three new market surfaces — protocol fees & revenue, the DEX-volume leaderboard, and a searchable DeFi hacks database ($16.7B all-time) — and a CoinGecko trending page (most-searched coins/categories/NFTs). All real key-free data, cross-linked. Docs: docs/coin-pages.md |
| Market detail pages (exchange, category) + DeFi yields | pages/exchange.html + src/exchange-page.js → /exchange/:id over api/coin/exchange.js, pages/category.html + src/category-page.js → /category/:id over api/coin/category.js + api/coin/markets.js (?category=), pages/yields.html + src/yields.js → /yields over api/defi/yields.js |
In-repo | Rich detail pages that turn list rows into full profiles. Exchange: trust badge, normalized-volume stat, BTC-volume history chart, and a per-pair markets table (spot + derivatives fallback), reached from /exchanges and the new Derivatives Exchanges table. Category: rank, sector stats, the full sortable coins table for that sector, and related categories, reached from /categories. Yields: an explorer over ~15k live DeFiLlama pools with chain/project/stablecoin/min-TVL filters, APY/TVL sort, URL-synced state, and a per-pool APY+TVL history chart on row expand. Docs: docs/coin-pages.md |
| Crypto news + archive + markets hub | pages/markets.html + src/markets-page.js → /markets, pages/markets-news.html + src/markets-news.js → /markets/news, pages/news-article.html + src/news-article.js → /markets/news/article, pages/news-archive.html + src/news-archive.js → /markets/archive, pages/news-digest.html + src/news-digest.js → /markets/digest; backend api/news/ (feed, article, knowledge, archive, digest, rss, image) over api/_lib/article-extract.js (page→reader→feed→preview ladder), api/_lib/news-coins.js (ticker→live market snapshot), api/_lib/news-knowledge-store.js (durable news_knowledge corpus) + hourly archiver api/cron/news-archive-append.js over api/_lib/news.js + api/_lib/news-sources.js, corpus on gs://three-ws-news-archive |
In-repo | The Markets news wing + front door: /markets/news is “Your briefing” — live news aggregated natively from 192 publisher feeds (Featured/Trending/Saved tabs, breaking ticker, AI briefing card, top-stories hero + rail, search, sentiment, ticker chips, og:image preview resolution for imageless feeds), a rich article reader that recovers the full story even from Cloudflare-blocked publishers (page→reader-service→feed→preview ladder), renders live coin cards (price/24h/7d/sparkline→/coin/:id) for detected tickers, AI summary/key points/entities with extractive fallback, and related coverage — and records every fully-read story to a durable news knowledge base (GET /api/news/knowledge) that grounds the 3D agents. Plus the largest open crypto-news archive (662,047 enriched articles, Sept 2017 → today, EN+中文, GCS-hosted) and the /markets hub aggregating global stats, the top-100 table, breaking news, and every market surface as a hero card. Docs: docs/coin-pages.md, docs/api-reference.md |
| Robinhood Chain markets + buy flow | Hub + detail pages pages/markets-robinhood.html + src/markets-robinhood.js → /markets/robinhood, pages/robinhood-stock.html + src/robinhood-stock.js → /markets/robinhood/stock/:symbol, pages/robinhood-coin.html + src/robinhood-coin.js → /markets/robinhood/coin/:address, buy flow src/robinhood-purchase.js; backend api/_lib/robinhood.js + api/v1/robinhood/{chain,stocks,stocks-detail,coins,coins-detail,launches}.js (free) + api/x402/robinhood-portfolio.js (x402 paid) |
In-repo | The 24/7 tokenized-equity board for Robinhood Chain (4663): live Chainlink NAV vs. Uniswap DEX premium for every Stock Token (one multicall, never 95 RPC calls), a memecoin screener across NOXA/The Odyssey launchpads (CoinGecko categories + on-chain launch logs via Blockscout), and chain TVL/gas/block stats. Detail pages add NAV history, holders, transfers, and contract links. Coin pages carry a real buy panel — injected-wallet connect, chain-switch to 4663, live Uniswap v3 QuoterV2 quote + SwapRouter02 swap with slippage, LI.FI bridge deep-link; Stock Tokens are display-only (tokenized securities, not offered to US persons) with an eligibility-gated outbound DEX link instead. Paid portfolio endpoint returns ERC-8056 uiMultiplier-correct holdings. Docs: docs/robinhood-chain-markets.md |
| Premium Data API pass | api/premium/ + api/_lib/premium.js, dashboards src/dashboard-next/pages/data-api.js → /dashboard/data-api + src/dashboard-next/pages/billing.js → /dashboard/billing |
In-repo | Monthly pass in three tiers (Developer $19.99, Pro $99, Enterprise $499 per 30d, tiered rate limits) paid on Solana in $THREE (20% off), SOL, or USDC — replaces per-call x402 on the news archive with an x402_live_ API key (existing access-control lane) + SIWX browser grants. Quote→sign→verify flow with on-chain balance-delta verification; tables premium_passes/premium_quotes. Docs: docs/premium.md |
| Liquidations pulse (/coins) | Collector services/liquidation-collector/ (standalone always-on Node service, ported from SperaxOS), proxy api/coin/liquidations.js → GET /api/coin/liquidations, UI strip in src/coins-index.js → /coins |
Live — collector on Cloud Run (liquidation-collector, min-instances 1, unthrottled CPU) since 2026-07-10 |
Real-time long/short liquidation pain across Binance, Bybit, and OKX public futures WebSocket streams: dominant-side badge (LONG PAIN / SHORT SQUEEZE / BALANCED), 1h long-vs-short bars, and the 3 largest recent liquidations, polled every 30s (pauses on hidden tab). The collector holds long-lived WebSockets so it can't run as a Vercel function — deploy it separately and point LIQUIDATION_COLLECTOR_URL at it. No fallback data: the proxy 503s collector_offline (never fabricated numbers) when unset or unreachable, and the strip degrades to a quiet single-line offline state. Docs: docs/api-reference.md#liquidations |
| BNB Chain campaign hub | pages/bnb.html + src/bnb.js → /bnb, pure helpers src/bnb-hub-helpers.js, live block-time API api/bnb/block-time.js over api/_lib/bnb/chains.js probeBlockTime |
In-repo · hub live, tracks rolling out | The campaign's front door: three feature cards (gasless agent onboarding, on-chain-gated 3D vault, real-time on-chain world), each claim traced to prompts/bnb-chain/00-CONTEXT.md's verified facts (0.45s blocks — never 20k TPS or 250ms finality). Embeds a live block-time widget (real RPC measurement on every load). Each card self-detects liveness via a real HTTP probe against its track's route/API on the running deployment — a 404 renders a designed "coming soon" state, never a dead link — so cards auto-light-up as the sibling tracks below ship: gasless registration → /create-agent + api/bnb/register-agent.js (prompt 03), vault → /vault (prompt 12), on-chain world → /bnb-latency (prompt 17) + the Explore on-chain toggle (prompt 16). Campaign root: prompts/bnb-chain/ |
| BABT holder check (BNB Chain) | Lib api/_lib/bnb/babt.js hasBabt(), free API api/bnb/babt-check.js → GET /api/bnb/babt-check?address= |
In-repo · shipped | Free, rate-limited on-chain check for whether a BSC address holds a Binance Account Bound Token (BABT) — a real, live, KYC-backed soulbound token (1.16M+ mainnet holders, verified via eth_getCode/balanceOf against the real contract 0x2B09d47D...5215D7c8). Verification writeup + honest comparison vs. Gitcoin Passport/World ID/Coinbase attestations: docs/bnb-babt-findings.md. Spike prompt: prompts/bnb-chain/20-babt-verification-spike.md. |
| BNB vault UI (browse/buy/unlock/view) | pages/vault.html + src/vault.js → /vault, buyer session key src/bnb/vault-session.js, buy calldata src/bnb/vault-buy.js, browser ECIES decrypt src/bnb/vault-crypto-browser.js, pure FSM helpers src/vault-fsm.js — over the buyer API api/vault/{list,status,unlock,download,buy-policy-data}.js and contract contracts/src/GreenfieldVault.sol (prompt 12) |
In-repo · code+crypto proven on a local anvil-fork deploy, public testnet blocked on the same funded-deployer-key wall as prompts 07/09/10/11/13/14/18 | The buyer-facing face of Track B: a grid of live on-chain listings, a "buy" step that sends a real BSC testnet transaction (gasless via MegaFuel when sponsorable, self-pay fallback), an honest "granting access on Greenfield…" polling state for the async cross-chain permission grant, and an "unlock & view" step that decrypts the GLB entirely client-side (AES-256-GCM + secp256k1 ECIES via Web Crypto + @noble/curves, never the server) before rendering it in <model-viewer>. Because the vault's ECIES unlock needs the buyer's raw private key — which a browser extension wallet deliberately never exposes — the buyer identity is a local session key (same pattern as src/agora/onchain-presence.js); MetaMask's only role is funding that session key with a plain tBNB transfer. A "Sell a model" panel wires the real upload (api/bnb/vault-upload.js) + list() path from a directly-connected wallet. GET /api/vault/buy-policy-data builds a real Greenfield Policy protobuf for buy() when a listing's object has genuinely completed Greenfield upload (api/_lib/bnb/vault-policy-data.js); until then buy() uses an honestly-labeled deterministic placeholder, matching the prompt-11 anvil proof's own posture. |
| BNB Chain live block race | pages/bnb-latency.html + src/bnb-latency.js → /bnb-latency, pure helpers src/bnb-latency-helpers.js, live multi-chain API api/bnb/latency.js over api/_lib/bnb/latency-lanes.js (reuses probeBlockTime from api/_lib/bnb/chains.js for BNB, adds Base/Ethereum/Solana lanes) |
In-repo · shipped | Standalone, shareable proof page: four lanes (BNB Chain, Base, Ethereum, Solana) polled every 5s, each showing a freshly measured average block/slot time and a rolling sparkline — no hardcoded numbers, a down RPC shows "reconnecting" on just that lane. Headline strip shows BNB's live average plus its honest measured-vs-measured speedup over Base/Ethereum. Linked from the /bnb hub's "real-time on-chain world" card, which auto-lights-up now that this route resolves. |
| BNB Chain payments (MPP, x402↔MPP bridge, gasless) | Accept api/_lib/bnb/mpp-server.js (mppRequirements/mppChallenge/mppVerify/mppSettle), pay api/_lib/bnb/mpp-buyer.js (mppFetch, re-exported from api/_lib/x402-buyer-fetch.js), gasless rail api/_lib/bnb/megafuel.js, pilot dual-protocol endpoint api/x402/three-intel.js |
In-repo · shipped, settlement needs merchant creds | three.ws speaks MPP (BNB Chain's Machine Payments Protocol) additively alongside x402: MPP's b402 layer is x402 v2 byte-for-byte (same X-PAYMENT/X-PAYMENT-RESPONSE, same EIP-3009 credential), so a dual-protocol endpoint just advertises an extra BNB (eip155:56/97) accept entry and routes BNB-network payments to the b402 facilitator while Solana/Base traffic stays on the untouched x402 path. Verify (off-chain, free, replay-guarded via Redis SET NX PX) always runs before settle; without B402_* merchant credentials, settle fails closed with mpp_not_configured (503) rather than fabricating a receipt. Guide: docs/bnb-payments.md. Wire contract: specs/x402-mpp-bridge.md. Tests: tests/bnb-mpp-server.test.js, tests/bnb-mpp-buyer.test.js. |
| Seeker / Saga dApp Store app | solana-mobile/ — TWA wrapper solana-mobile/twa/, PWA shell solana-mobile/pwa/, listing copy + release config solana-mobile/publish/, Seeker detection solana-mobile/src/seeker-detect.js | In-repo · listing assets staged | Everything needed to package three.ws as a Solana Mobile app and publish it to the on-chain dApp Store. Targets Seeker first; compatible with Saga Gen 1 and Gen 2. Docs: solana-mobile/README.md |
| Walk Avatar browser extension | extensions/walk-avatar/ — MV3 manifest.json, background.js |
In-repo · Chrome Web Store release checklist staged (RELEASE.md) | Walks your three.ws avatar across any site and reads pages aloud — a browsing companion built on the same rig as the walk-sdk. Ships its own store-required PRIVACY.md, PERMISSIONS.md, and TERMS.md. |
| DCC tool integrations (Blender, ComfyUI) | integrations/ — integrations/blender/, integrations/comfyui/, shared Python client integrations/_pyclient/ | In-repo | First-party plugins that drive the public Forge pipeline (/api/forge) from inside the tools artists already use, so a model is generated without leaving the DCC. Docs: integrations/README.md |
| Vanity address grinder (Rust → WASM) | crates/vanity-grinder/ → compiled to src/solana/vanity/wasm/; consumed by src/agent-vanity-grinder.js, src/agent-eth-vanity-card.js | In-repo | The Rust source behind in-browser Solana/EVM vanity-address mining. Compiled to WebAssembly so grinding runs on the visitor's machine, never the server. Surfaced as the vanity_grinder MCP tool and the premium pre-ground inventory (vanity_premium). |
| x402 payment modal (drop-in UI) | x402-payment-modal/ | Published as @three-ws/x402-payment-modal |
A drop-in payment modal for any x402 paid endpoint — one ES import turns a 402 challenge into a wallet-connect + pay flow. Has a build step, so it sits outside the zero-dependency packages/* SDK family. |
| x402 modal SDK | x402-modal-sdk/ | Published as @three-ws/x402-modal |
The lower-level modal SDK the payment modal builds on. Ships a bundled dist/; see x402-modal-sdk/TUTORIAL.md. |
| Meta-Allocator (the ETF of degens) | pages/meta-allocator.html + src/meta-allocator.js → /meta-allocator, brain api/_lib/meta-allocator.js, endpoint api/meta-allocator.js |
Live (non-custodial planning) | Spreads a budget across the top verified pump.fun leader agents, ranked by risk-adjusted on-chain track record (win rate, realized ROI, peak-to-trough max drawdown from agent_sniper_positions) and diversified across derived correlation groups, then returns a rebalance rule. Free-first llmComplete shaping with a deterministic same-shape fallback so it never fails. Returns a plan (weights + suggested sizes), never a transaction; users act one leader at a time via /vaults. Doc: docs/meta-allocator.md. |
| Clip Director (content engine) | pages/clip-director.html + src/clip-director-page.js → /clip-director, brain api/_lib/clip-director.js, endpoint api/clip-director.js |
Live | Turns one real closed trade (agent_sniper_positions) into the optimal shareable card per surface (X / Telegram / Feed): honest hook, the real number, an avatar gesture mapped to a real animation clip, CTA, and alt text, plus an on-chain proof link. Losses get an honest card too. Free-first llmComplete with a deterministic same-shape fallback. Doc: docs/clip-director.md. |
| Internationalization (i18n) | Runtime src/i18n.js → /i18n.js; catalogs public/locales/ (en + 10 locales, manifest.json, localized-pages.json); pipeline scripts/i18n-annotate.mjs · i18n-extract.mjs · i18n-translate.mjs (Vertex Gemini, glossary-locked); hreflang in api/sitemap/[type].js |
Live (11 languages) | LobeHub-model client-side copy swap. npm run i18n:annotate auto-injects data-i18n* into static HTML (byte-surgical), i18n:extract builds en.json, i18n:translate fans it out to every locale via Vertex with brand/protocol terms masked. Runtime auto-detects locale, mounts a floating <lang-switcher>, and injects hreflang. Doc: docs/i18n.md. Tests: tests/i18n.test.js, tests/i18n-annotate.test.js. |
Declared in package.json:
agent-payments-sdk/ → @three-ws/agent-payments (fork of @pump-fun/agent-payments-sdk@3.0.3)
agent-ui-sdk/ → @three-ws/agent-ui
avatar-sdk/ → @three-ws/avatar
character-studio/ → @m3-org/characterstudio (fork)
mcp-bridge/ → @three-ws/mcp-bridge
mcp-server/ → @three-ws/mcp-server
multiplayer/ → @three-ws/multiplayer
services/liquidation-collector/ → @three-ws/liquidation-collector (standalone Binance/Bybit/OKX liquidation stream collector, ported from SperaxOS)
packages/avatar-schema/ → @three-ws/avatar-schema
packages/avatar-cli/ → @three-ws/avatar-cli
packages/retarget/ → @three-ws/retarget (humanoid bone canonicalizer + clip retargeting engine, extracted from src/)
packages/viewer-presets/ → @three-ws/viewer-presets
packages/defi-utils/ → @three-ws/defi-utils (zero-dependency chain/token constants + address/amount validation + formatters, EVM + Solana; ported from SperaxOS)
packages/tool-sdk/ → @three-ws/tool-sdk (typed MCP tool authoring — defineTool/defineExecutor + permission manifests + toMcpTools adapter; ported from SperaxOS)
packages/avatar-agent-mcp/ → @three-ws/avatar-agent-mcp (MCP server — avatar agent tools)
packages/pumpfun-mcp/ → @three-ws/pumpfun-mcp (MCP server — pump.fun launch tools)
packages/ibm-watsonx-mcp/ → @three-ws/ibm-watsonx-mcp (MCP server — IBM watsonx.ai)
packages/ibm-x402-mcp/ → @three-ws/ibm-x402-mcp (MCP server — IBM x402 payments)
packages/alibaba-cloud-mcp/ → @three-ws/alibaba-cloud-mcp (MCP server — Alibaba Cloud DashScope: Qwen chat, embeddings, model discovery)
packages/three-token-mcp/ → @three-ws/three-token-mcp (MCP server — $THREE token tools)
packages/threews-avatar-mcp/ → @three-ws/threews-avatar-mcp (MCP server — three.ws avatar ops)
packages/scene-mcp/ → @three-ws/scene-mcp (MCP server — text→3D diorama scenes)
packages/vanity-mcp/ → @three-ws/vanity-mcp (MCP server — Solana vanity bounty market + rarity gallery)
packages/naming-mcp/ → @three-ws/naming-mcp (MCP server — .sol resolve + *.threews.sol identity availability)
packages/intel-mcp/ → @three-ws/intel-mcp (MCP server — smart-money, signals, KOL, copy-trade intel)
packages/marketplace-mcp/ → @three-ws/marketplace-mcp (MCP server — agent marketplace + skills catalog browse)
packages/x402-mcp/ → @three-ws/x402-mcp (MCP server — self-custodial x402 buyer: find/inspect/pay any service in USDC)
packages/autopilot-mcp/ → @three-ws/autopilot-mcp (MCP server — agent execution control: scopes, SOL spend caps, propose/execute/undo)
packages/portfolio-mcp/ → @three-ws/portfolio-mcp (MCP server — portfolio, PnL, balances, trade feed, signed transfers)
packages/provenance-mcp/ → @three-ws/provenance-mcp (MCP server — append-only, signed, on-chain-verifiable agent action log)
packages/copy-mcp/ → @three-ws/copy-mcp (MCP server — manage copy-trade follows, sizing & guard rules)
packages/signals-mcp/ → @three-ws/signals-mcp (MCP server — discover signal feeds by proven edge; rank publishers)
packages/alerts-mcp/ → @three-ws/alerts-mcp (MCP server — pump.fun alert rules: in-app, webhook, Telegram)
packages/notifications-mcp/ → @three-ws/notifications-mcp (MCP server — inbox, read state, delivery prefs, Web Push)
packages/billing-mcp/ → @three-ws/billing-mcp (MCP server — plan quotas, usage, invoices, receipts)
packages/activity-mcp/ → @three-ws/activity-mcp (MCP server — trending agents/coins, $THREE holder board, activity ticker)
packages/agenc-mcp/ → @three-ws/agenc-mcp (MCP server — AgenC on-chain task marketplace + agent registry)
packages/agora-mcp/ → @three-ws/agora-mcp (MCP server — Agora economy: board/pulse/passport reads + register/claim/complete/post writes)
packages/vision-mcp/ → @three-ws/vision-mcp (MCP server — image understanding via the three.ws vision pipeline)
packages/brain-mcp/ → @three-ws/brain-mcp (MCP server — multi-provider LLM router)
packages/audio-mcp/ → @three-ws/audio-mcp (MCP server — TTS, STT, audio-to-face lipsync, motion capture)
packages/kol-mcp/ → @three-ws/kol-mcp (MCP server — per-wallet KOL portfolio + trade analytics)
packages/clash-mcp/ → @three-ws/clash-mcp (MCP server — Coin Clash faction battles)
packages/tutor-mcp/ → @three-ws/tutor-mcp (MCP server — itemized learning-session ledger)
packages/loom-mcp/ → @three-ws/loom-mcp (MCP server — Loom 3D-creation gallery: browse, fetch, submit)
packages/agent-sniper/ → @three-ws/agent-sniper (engine + CLI + MCP server + x402 paid API — autonomous, self-custodial pump.fun sniper)
walk-sdk/ → @three-ws/walk (page walking companion + playground + avatar picker)
packages/* is the home for clean, publishable spec/schema/preset packages
with no runtime dependency on the main app.
Cross-chain SDKs that ship on their own (sdk/ → @three-ws/sdk,
solana-agent-sdk/ → @three-ws/solana-agent,
agent-protocol-sdk/ → @three-ws/agent-protocol-sdk) live at the top level
but are not npm workspaces.
packages/ is reserved for spec/schema/protocol packages with no runtime
dependencies on the main app — things that need to be installable by external
consumers (e.g. another team building an avatar viewer that wants to validate
our manifest format).
Runtime SDKs and apps live at the top level for historical compatibility with the deploy pipeline and existing import paths.
These wrap already-live platform capabilities (real api/ endpoints + MCP
tools) into single-import @three-ws/* SDKs. Each is a zero-dependency,
pure-ESM client: it ships src/ directly (no build step), hand-written
.d.ts types, and a node --test suite — all green (216 tests across the
suite). They share one byte-identical HTTP core (src/http.js: base-URL
resolution + typed ThreeWsError/PaymentRequiredError, with 402 carrying the
x402 challenge). Verify any of them with cd packages/<name> && node --test test/*.test.js.
Launch state: published to npm as @three-ws/<name> — install with
npm i @three-ws/<name>. The merchant SDK (@three-ws/x402-server) advertises
the two main x402 assets, USDC and $THREE, in one 402 challenge. Re-publish
is idempotent via node scripts/publish-packages.mjs (skips versions already on
npm).
| Package | Location | Wraps | What it does |
|---|---|---|---|
@three-ws/forge |
packages/forge/ | api/forge*.js, api/mcp-3d.js |
Text/image/sketch → textured, rig-ready GLB; free TRELLIS lane + paid tiers + auto-rig |
@three-ws/names |
packages/names/ | api/sns*.js, api/x402/pay-by-name.js |
ENS + SNS resolution, *.threews.sol minting, pay-by-name |
@three-ws/intel |
packages/intel/ | api/sentiment.js, api/aixbt/, pump_snapshot |
Token sentiment, narrative intel, momentum scans, token snapshots |
@three-ws/vanity |
packages/vanity/ | api/vanity/, src/solana/vanity/ (WASM) |
WASM-accelerated Solana vanity address mining |
@three-ws/reputation |
packages/reputation/ | api/reputation/, api/erc8004/ |
ERC-8004 agent reputation read + attest |
@three-ws/voice |
packages/voice/ | api/asr.js, api/tts/, api/a2f.js |
ASR + TTS + audio2face lipsync visemes |
@three-ws/x402-server |
packages/x402-server/ | api/x402-merchant.js, api/x402-pay.js |
Merchant/seller side of x402 — turn any endpoint paid |
@three-ws/agent-memory |
packages/agent-memory/ | api/agent-memory.js, api/memory/ |
Embeddings-backed persistent agent memory + entity graph |
@three-ws/agenc |
packages/agenc/ | api/agenc/ |
AgenC coordination protocol — task discovery, status, registry |
@three-ws/guardian |
packages/guardian/ | api/guardian/, Granite Guardian |
Content safety / moderation for agents |
@three-ws/glb-tools |
packages/glb-tools/ | _lib/glb-inspect.js, glb-themer.js, bake.js |
Inspect, re-theme, and bake GLBs from CLI/CI |
@three-ws/agent-guards |
packages/agent-guards/ | _lib/agent-spend-policy.js, agent-trade-guards.js |
Spend + trade guardrails for autonomous agents |
@three-ws/skill-license |
packages/skill-license/ | contracts/skill-license/, api/skills/ |
On-chain skill licenses (SPL NFT + PDA) mint/verify |
@three-ws/mocap |
packages/mocap/ | api/mocap/ |
Motion-capture clips → avatar animation |
@three-ws/strategies |
packages/strategies/ | api/strategies.js, dca-strategies.js, copy/mirror engines |
Automated trading strategies (DCA, copy, mirror) |
@three-ws/pumpfun-skills |
packages/pumpfun-skills/ | pump-fun-skills/ | pump.fun create-coin / swap / fees skills (runtime mint) |
@three-ws/irl |
packages/irl/ | api/irl/, _lib/geohash.js |
Geofenced real-world presence + nearby discovery |
@three-ws/pose |
packages/pose/ | get_pose_seed, api/mcp-3d.js |
Pose-seed generation for rigged avatars |
- 3D viewer & creator — avatar-sdk/, character-studio/
- Avatar / accessory assets — public/avatars/, public/accessories/
- Animations — public/animations/ (Mixamo FBX → built GLB clips), scripts/build-animations.mjs
- On-chain identity & contracts — contracts/, packages/avatar-schema/
- API endpoints — api/ (serverless-style handlers, served in production by the server/ Cloud Run container), workers/ (long-running workers)
- Examples & demos — examples/, multiplayer/
- Marketing assets — marketing/ (produced promo videos + re-render scripts, e.g. marketing/imessage-video/; source-of-truth assets, not shipped to production)
- Robinhood Chain (4663) developer tooling — robinhood/, standalone packages published to their own
nirholas/*GitHub repos (each with its own README):erc8056(ERC-8056 Scaled UI Amount reference impl),hood-connect(wallet onboarding kit),hood-pay(USDG checkout + payment links),hood-alerts(Telegram/Discord launch + whale alerts),hood-status(chain status page),hood-tokenlist(canonical token list),hoodkit/hood402/robinhood-chain-sdk(shared chain + x402 primitives other packages depend on),hood-cli,hood-launcher,hood-mcp,hood-api,hood-js,hood-traders,robinhood-chain-examples,learn-robinhood-chain. Distinct from the in-repo/playand/markets/robinhoodproduct surfaces above, which live in this repo's ownapi//src/. - Cross-chain SDKs — sdk/, solana-agent-sdk/, agent-payments-sdk/, agent-protocol-sdk/
- MCP integration — mcp-server/, mcp-bridge/
- Specs & protocol docs — specs/
- Frontend pages — src/, pages/, public/
- Tests — tests/
A surface graduates to its own repo only when there is a concrete external need that the monorepo cannot serve:
- A third party wants to consume it without pulling our whole tree.
Mitigation: publish to npm under
@three-ws/*first. If the npm package is enough, no repo split is needed. - Independent release cadence required. When the surface needs its own semver line decoupled from the app.
- External contributors blocked. When the repo size or unrelated CI cost is a real friction for outside PRs.
Promotion procedure (when triggered):
# Cleanly split a directory's full history into a new repo
git subtree split --prefix=packages/avatar-schema -b avatar-schema-split
cd ../ && mkdir avatar-schema-repo && cd avatar-schema-repo
git init && git pull ../three.ws avatar-schema-split
git remote add origin https://github.com/nirholas/avatar-schema.git
git push -u origin main
# Then in three.ws: replace the workspace dir with a normal npm depUntil the trigger fires, splitting is premature: each new repo adds release overhead, CI cost, and cross-repo PR coordination tax for zero functional gain.
- README.md — product overview, quickstart, full feature list
- CONTRIBUTING.md — how to propose changes
- Attribution for derived code and assets — character-studio/LICENSE (fork of M3-org/CharacterStudio), src/scene-studio/vendor/LICENSE (vendored three.js editor), public/animations/LICENSES.md, and the per-asset
LICENSES.mdfiles under public/club/ - CLAUDE.md — operating rules for AI agents working in this repo