feat(tips): consolidated TIPS page with per-chain toggle - #38
Merged
Conversation
Ports the standalone TIPS UI into omni as a sidebar page, replacing the three separately-deployed per-chain sites with one view. Chain (Base Mainnet / Base Sepolia / Zeronet) is a runtime parameter driven by a `?chain=` query and a toggle on every route. - API ported under /api/tips: thin S3 + JSON-RPC wrappers, chain-selected by env prefix (TIPS_MAINNET_/TIPS_SEPOLIA_/TIPS_ZERONET_), read-through block cache with write-through PutObject preserved. Secrets via Vercel env only. - Full route set restyled to the omni design system: dashboard (Blocks + Rejected tabs, tx search) plus block / bundle / txn detail pages, all chain-aware (links and explorer URLs carry the selected chain). - Chain model contract in app/tips/chains.ts; per-chain explorer overrides via NEXT_PUBLIC_TIPS_<CHAIN>_EXPLORER_URL. - Analytics: trackTipsChainSelect fires on toggle; wiring documented in AGENTS.md. Sitemap and .env.example updated; updates llms.txt.
Collaborator
🟡 Heimdall Review Status
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
TIPS is internal-only. The public (Vercel) build leaves the flag unset, so the section is entirely absent; the internal build (cb/ui) sets it to 1 at `next build` time. Same public source, two deployables. When the flag is off: - the sidebar entry is dropped from NAV_ITEMS (not just shown as "Soon") - middleware returns a real 404 for /tips and /tips/* at the edge. The route is statically prerendered, so the layout's notFound() alone serves 404 content with a 200 status; the edge check enforces the correct status. - app/tips/layout.tsx also calls notFound() as a content-level backstop - every /api/tips/* route returns 404 via a shared guard, so its existence isn't leaked by 500s from missing credentials - /tips is excluded from the generated llms/agents artifacts via a new llms.config.mjs; it is deliberately not in the public sitemap either next.config: emit output: 'standalone' so the internal Docker image can run server.js without node_modules (no-op on Vercel).
Contributor
Author
|
Added: TIPS is now gated behind a build-time flag
Same public source, two deployables. This pairs with the internal Verified both states on a production build: flag-off → 404 across all TIPS routes + link absent; flag-on → 200 + link present. |
Replace the single NEXT_PUBLIC_ENABLE_TIPS flag with a declarative deployment
matrix. deploy.config.mjs maps each environment-specific surface to the build
targets that include it; NEXT_PUBLIC_DEPLOY_TARGET (set by the build script)
selects the target. Adding an internal- or external-only page is now a one-line
config edit that nav, middleware, and the llms generator all read.
- deploy.config.mjs: SURFACES matrix + surfaceEnabled / disabledRoutePrefixes /
disabledRouteGlobs helpers. Authored as .mjs so both the app and the node
llms scripts import it; NEXT_PUBLIC_DEPLOY_TARGET is inlined at build, so a
disabled surface is still dead-code-eliminated (route + API 404).
- app/tips/flag.ts: TIPS_ENABLED now derives from surfaceEnabled('tips').
- middleware.ts: 404 any disabledRoutePrefixes() at the edge (generic; no
per-page edit).
- llms.config.mjs: exclude = disabledRouteGlobs() (auto).
- package.json: add build:internal (sets NEXT_PUBLIC_DEPLOY_TARGET=internal).
- deploy.config.test.mjs: surfaceEnabled / disabledRoutePrefixes / disabledApiPrefixes / disabledRouteGlobs under external + internal targets, default-external, and unknown-surface-enabled-everywhere. - add dev:internal script (NEXT_PUBLIC_DEPLOY_TARGET=internal next dev) so the internal variant (with TIPS) can be run locally, mirroring build:internal. - README + AGENTS.md: document the external/internal targets, how to run both locally, and the deploy.config.mjs workflow for adding env-specific pages. - .env.example: explain the target is set by the *:internal scripts, and the caveat of pinning it in .env.local.
The repo had no CI of its own — every check on a PR came from org-level
tooling (CodeQL, StepSecurity, Heimdall, Vercel), so tests, typecheck, lint,
and docs:check never ran on a pull request.
- .github/workflows/ci.yml, two jobs:
- verify: typecheck, lint, test, docs:check.
- public-build-excludes-internal: builds the default (external) target and
asserts internal-only routes 404 and never appear in the nav or sitemap.
Verified both ways — it passes on an external build and fails on an
internal one, so the deployment matrix can't silently regress.
Docs corrections found while wiring this up:
- README claimed docs:check was a "CI gate" when nothing ran it; now it is,
and the CI setup is documented.
- Drop the "dead-code-eliminated" claim (deploy.config.mjs, app/tips/flag.ts,
AGENTS.md). A disabled surface is unreachable — routes and API 404, dropped
from nav/sitemap/llms — but its client chunks may still be emitted, so the
guarantee is reachability, not omission from the bundle.
- Document that the *:internal scripts take precedence over a value pinned in
.env.local, so pinning a local default never locks you out of either variant.
- AGENTS.md: call out that SURFACES is an exception list, so an internal-only
page with no entry fails open, and point at the CI job to extend.
Co-Authored-By: Claude <noreply@anthropic.com>
…jobs Each runs as its own check so a failure names the thing that broke and can be required individually in branch protection, rather than one combined job. Also give the docs job a self-describing name: it verifies the generated agent index (public/llms.txt, llms-full.txt, AGENTS.md), which is committed and goes stale when routes change. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Ports the standalone TIPS UI into omni as a TIPS sidebar page, replacing the three separately-deployed per-chain sites (Base Mainnet, Base Sepolia, Zeronet) with a single consolidated view. Chain becomes a runtime parameter: a toggle at the top of every TIPS route drives a
?chain=query that selects the data source server-side and threads through all links.Completion criteria (all met)
/tipsrenders the dashboard (Blocks + Rejected Transactions tabs, tx-hash search)?chain=and refetches the correct chain's datatypecheck/lint/buildgreen; mobile layout cleanArchitecture
/api/tips— thin S3 + JSON-RPC wrappers (one read-through block cache with write-throughPutObjectpreserved). Chain selected by env prefix:TIPS_MAINNET_*,TIPS_SEPOLIA_*,TIPS_ZERONET_*(S3 bucket/region/endpoint/creds + RPC URL). Mirrors the snapshots per-network env pattern.app/tips/chains.ts— single source of truth for chain ids, labels, and explorer URLs (overridable viaNEXT_PUBLIC_TIPS_<CHAIN>_EXPLORER_URL).@aws-sdkcode reaches the client bundle.trackTipsChainSelectfires on toggle; wiring row added toAGENTS.md.Config
Secrets go in Vercel project env only (never in git).
.env.exampledocuments the per-chain variables. Set the threeTIPS_*credential sets before this reads live data.Verification
Verified locally with Playwright: nav item present; dashboard renders; toggling to Sepolia switches polling from
?chain=mainnetto?chain=sepolia; block detail back-link and explorer URL carry the chain (base-sepolia.blockscout.com);tips_chain_selectevent emits; graceful empty/error states; clean at 390px width. Live data (S3/RPC) requires the Vercel env creds and was not exercisable locally.