Skip to content

Commit 037fe10

Browse files
montycheeseclaude
andcommitted
Initial commit
omni-ui: the Base upgrades, changelog, snapshots, and Vibenet demos site (Next.js 15 App Router). Commit history squashed ahead of the public release. Co-Authored-By: Claude <noreply@anthropic.com>
0 parents  commit 037fe10

232 files changed

Lines changed: 62149 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/commands/agents.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: Regenerate the public AGENTS.md routing document, or check whether it is stale
3+
---
4+
5+
Manage the generated `public/AGENTS.md` — the **public** agent routing document
6+
served at `<origin>/AGENTS.md`.
7+
8+
Argument: `$ARGUMENTS` — one of `check`, `status`, `force`, or empty.
9+
10+
## Two different files
11+
12+
Get this right before doing anything:
13+
14+
- **`/AGENTS.md`** at the repo root is hand-written, follows the
15+
[agents.md](https://agents.md/) spec, and describes how to work *in* this
16+
repo. It is in no generator's `outputs`. Never regenerate it.
17+
- **`public/AGENTS.md`** is generated by `scripts/agents.mjs` and tells external
18+
developers' agents how to use the site: routing rules, freshness, network
19+
reference, route list.
20+
21+
This command only concerns the second one.
22+
23+
## Normally you do not need this
24+
25+
`githooks/post-commit` runs it automatically when a commit message contains
26+
`agents.md`, and on any added, deleted, or renamed route file:
27+
28+
```sh
29+
git commit -m "docs: refresh agents.md"
30+
```
31+
32+
## What to do
33+
34+
**No argument** — regenerate only if the route tree or config changed:
35+
36+
```sh
37+
git diff --name-only HEAD -- src/app app llms.config.mjs
38+
node scripts/agents.mjs
39+
git diff --stat public/AGENTS.md
40+
```
41+
42+
**`force`** — regenerate regardless.
43+
44+
**`check`** — report staleness and validation failures without writing; exit 1
45+
if stale:
46+
47+
```sh
48+
node scripts/agents.mjs --check
49+
```
50+
51+
**`status`** — size, mtime, route count, config. Never fails.
52+
53+
## When reviewing the diff
54+
55+
Check these specifically, because they are the parts that would be damaging
56+
rather than merely wrong:
57+
58+
- Each chain ID sits in the same `### ` block as its own RPC URL. A transposed
59+
`8453` / `84532` reads perfectly fine and would have an agent signing against
60+
the wrong network. There is a test for this; if it is failing, do not
61+
work around it.
62+
- Ephemeral networks publish a note about where to read live values, not a
63+
fabricated chain ID.
64+
- The routing rules still say which source wins on a conflict.
65+
66+
To change content, edit `llms.config.mjs` — not the generated file.

.claude/commands/llms.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
description: Regenerate llms.txt and llms-full.txt, or check whether they are stale
3+
---
4+
5+
Manage the generated `public/llms.txt` and `public/llms-full.txt`.
6+
7+
Argument: `$ARGUMENTS` — one of `check`, `status`, `install`, or empty.
8+
9+
## Normally you do not need this
10+
11+
`githooks/post-commit` runs `scripts/llms.mjs` automatically when a commit
12+
message contains `llms.txt` (case-insensitive), and when a route file is added,
13+
deleted, or renamed. So the day-to-day flow is just:
14+
15+
```sh
16+
git commit -m "feat: add a snapshots page; updates llms.txt"
17+
```
18+
19+
Use `/llms` when you want to preview output before committing, regenerate
20+
without committing, or set the hook up on a fresh clone.
21+
22+
## What to do
23+
24+
**No argument** — regenerate and show what changed:
25+
26+
```sh
27+
node scripts/llms.mjs
28+
git diff --stat public/llms.txt public/llms-full.txt
29+
```
30+
31+
Report which files changed and summarise the diff. If nothing changed, say so
32+
plainly rather than implying work happened.
33+
34+
**`check`** — report staleness without writing. Exit 1 means stale, invalid, or
35+
sitemap drift:
36+
37+
```sh
38+
node scripts/llms.mjs --check
39+
```
40+
41+
Relay the metadata-source breakdown. Any count under `metadata fallback` means
42+
those routes have no usable `export const metadata` and are being listed with a
43+
humanized slug — name them and suggest either adding metadata to the page or a
44+
`routes` override in `llms.config.mjs`.
45+
46+
**`status`** — sizes, mtimes, config, route count, drift. Never fails:
47+
48+
```sh
49+
node scripts/llms.mjs --status
50+
```
51+
52+
**`install`** — set up the hook on this clone:
53+
54+
```sh
55+
./githooks/install.sh
56+
```
57+
58+
Then confirm it is repo-scoped: `git config --global --get core.hooksPath`
59+
should print nothing.
60+
61+
## Do not
62+
63+
- Edit `public/llms.txt` or the autogen region of `public/llms-full.txt` by
64+
hand. Change the page's `export const metadata` or `llms.config.mjs` instead.
65+
- Touch the `<!-- LLMS_EXTRAS_START -->``<!-- LLMS_EXTRAS_END -->` region
66+
unless the user asked for a prose change. That region is hand-written and
67+
preserved verbatim across regenerations.
68+
- Confuse `public/AGENTS.md` (generated) with `/AGENTS.md` at the repo root
69+
(hand-written, never generated).

.env.example

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Vibenet dataplane API and RPC (public URLs, safe to expose to the client).
2+
NEXT_PUBLIC_VIBENET_API_BASE_URL=https://api.vibes.base.org
3+
NEXT_PUBLIC_VIBENET_RPC_URL=https://rpc.vibes.base.org
4+
5+
# Snapshots: Cloudflare R2 credentials, read server-side by /api/snapshots.
6+
# These are secrets — set them in the Vercel project settings, not in git.
7+
# Provide per network (BASE_MAINNET_, BASE_SEPOLIA_, BASE_ZERONET_).
8+
# BASE_MAINNET_R2_ACCOUNT_ID=
9+
# BASE_MAINNET_R2_ACCESS_KEY_ID=
10+
# BASE_MAINNET_R2_SECRET_ACCESS_KEY=
11+
12+
# Build/deploy target — selects which surfaces ship (see deploy.config.mjs).
13+
# external (default) = public Vercel site; internal = Coinbase EKS (cb/ui),
14+
# which includes internal-only sections like TIPS.
15+
#
16+
# Normally you don't set this by hand — the scripts do it:
17+
# npm run dev / npm run build -> external (default)
18+
# npm run dev:internal / npm run build:internal -> internal (TIPS visible)
19+
#
20+
# Set it here to change your local default (either value works), e.g. pin
21+
# `internal` so a plain `npm run dev` includes TIPS. The *:internal scripts still
22+
# win over this: a variable set in the shell by the npm script takes precedence
23+
# over .env.local, so you can always get either variant without editing this file.
24+
# Only affects local runs — Vercel sets no value, so the public build is external.
25+
# NEXT_PUBLIC_DEPLOY_TARGET=internal
26+
27+
# TIPS: per-chain S3 + RPC, read server-side by /api/tips (chain via ?chain=).
28+
# One deployment serves all chains; provide a set per chain
29+
# (TIPS_MAINNET_, TIPS_SEPOLIA_, TIPS_ZERONET_). Secrets → Vercel env, not git.
30+
# TIPS_MAINNET_S3_BUCKET=
31+
# TIPS_MAINNET_S3_REGION=us-east-1
32+
# TIPS_MAINNET_S3_ENDPOINT= # optional (e.g. MinIO); omit for AWS
33+
# TIPS_MAINNET_S3_ACCESS_KEY_ID=
34+
# TIPS_MAINNET_S3_SECRET_ACCESS_KEY=
35+
# TIPS_MAINNET_RPC_URL=
36+
# Per-chain block explorer for TIPS links (client-visible). Defaults:
37+
# mainnet=https://base.blockscout.com, sepolia=https://base-sepolia.blockscout.com.
38+
# NEXT_PUBLIC_TIPS_ZERONET_EXPLORER_URL=

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.github/workflows/ci.yml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
# Cancel superseded runs on the same PR/branch.
10+
concurrency:
11+
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
12+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
typecheck:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Harden the runner (Audit all outbound calls)
22+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
23+
with:
24+
egress-policy: audit
25+
26+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
27+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
28+
with:
29+
node-version: 24
30+
cache: npm
31+
- run: npm ci
32+
- run: npm run typecheck
33+
34+
lint:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Harden the runner (Audit all outbound calls)
38+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
39+
with:
40+
egress-policy: audit
41+
42+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
43+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
44+
with:
45+
node-version: 24
46+
cache: npm
47+
- run: npm ci
48+
- run: npm run lint
49+
50+
test:
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Harden the runner (Audit all outbound calls)
54+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
55+
with:
56+
egress-policy: audit
57+
58+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
59+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
60+
with:
61+
node-version: 24
62+
cache: npm
63+
- run: npm ci
64+
- run: npm test
65+
66+
# public/llms.txt, llms-full.txt, and AGENTS.md are generated from the route
67+
# tree and committed. They go stale whenever a route is added, renamed, or
68+
# removed, so this fails if they differ from a fresh generation (it also
69+
# reports sitemap drift). Fix with: npm run llms && npm run agents
70+
docs:
71+
name: docs (generated agent index)
72+
runs-on: ubuntu-latest
73+
steps:
74+
- name: Harden the runner (Audit all outbound calls)
75+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
76+
with:
77+
egress-policy: audit
78+
79+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
80+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
81+
with:
82+
node-version: 24
83+
cache: npm
84+
- run: npm ci
85+
- run: npm run docs:check
86+
87+
public-build-excludes-internal:
88+
name: public build excludes internal-only surfaces
89+
runs-on: ubuntu-latest
90+
steps:
91+
- name: Harden the runner (Audit all outbound calls)
92+
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
93+
with:
94+
egress-policy: audit
95+
96+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
97+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
98+
with:
99+
node-version: 24
100+
cache: npm
101+
- run: npm ci
102+
103+
# The default (external) build is what ships to Vercel. Deliberately no
104+
# NEXT_PUBLIC_DEPLOY_TARGET here, so this reproduces the public build.
105+
- run: npm run build
106+
107+
# Guards the deployment matrix in deploy.config.mjs: a surface that is not
108+
# shipped to the external target must be unreachable on the public site.
109+
# Without this, dropping the middleware rule — or adding an internal-only
110+
# page and forgetting its SURFACES entry — would silently publish it.
111+
- name: Assert internal-only surfaces are absent
112+
run: |
113+
set -euo pipefail
114+
115+
npx next start -p 3000 &
116+
SERVER_PID=$!
117+
trap 'kill $SERVER_PID 2>/dev/null || true' EXIT
118+
119+
for i in $(seq 1 60); do
120+
if curl -fsS -o /dev/null http://localhost:3000/; then break; fi
121+
if [ "$i" -eq 60 ]; then echo "server never became ready"; exit 1; fi
122+
sleep 1
123+
done
124+
125+
fail=0
126+
127+
# Internal-only routes must 404 on the public build.
128+
for route in /tips /tips/block/0x1 /tips/bundles/0x1 /api/tips/blocks; do
129+
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}")
130+
if [ "${code}" != "404" ]; then
131+
echo "FAIL: ${route} returned ${code}, expected 404"
132+
fail=1
133+
fi
134+
done
135+
136+
# Pages that must stay public.
137+
for route in / /snapshots; do
138+
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}")
139+
if [ "${code}" != "200" ]; then
140+
echo "FAIL: ${route} returned ${code}, expected 200"
141+
fail=1
142+
fi
143+
done
144+
145+
# No nav link to, or sitemap entry for, an internal-only section.
146+
if curl -s http://localhost:3000/ | grep -q 'href="/tips"'; then
147+
echo "FAIL: public homepage links to /tips"
148+
fail=1
149+
fi
150+
if curl -s http://localhost:3000/sitemap.xml | grep -q '/tips'; then
151+
echo "FAIL: public sitemap lists /tips"
152+
fail=1
153+
fi
154+
155+
if [ "${fail}" -ne 0 ]; then exit 1; fi
156+
echo "OK: internal-only surfaces are absent from the public build"

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# dependencies
2+
/node_modules
3+
4+
# next.js
5+
/.next/
6+
/out/
7+
8+
# production
9+
/build
10+
11+
# misc
12+
.DS_Store
13+
*.pem
14+
15+
# debug
16+
npm-debug.log*
17+
yarn-debug.log*
18+
yarn-error.log*
19+
.pnpm-debug.log*
20+
21+
# env files (keep .env.example)
22+
.env*
23+
!.env.example
24+
25+
# vercel
26+
.vercel
27+
28+
# typescript
29+
*.tsbuildinfo
30+
next-env.d.ts
31+
.claude/worktrees/
32+
.agents/skills/
33+
.claude/skills/
34+
skills-lock.json
35+
plans/

.npmrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# @vercel/analytics declares optional peers for other frameworks (e.g.
2+
# @sveltejs/kit) that npm's strict resolver conflicts against our vite/vitest
3+
# tree. We only use the Next.js path, so relax peer resolution for a clean,
4+
# reproducible install here and on Vercel's build.
5+
legacy-peer-deps=true

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
24

0 commit comments

Comments
 (0)