Skip to content

feat(frontend): agents registry, proof ledger, run replay and sign-out splash (stacked on #5) - #6

Merged
OfficialAbhinavSingh merged 31 commits into
mergit-io:mainfrom
OfficialAbhinavSingh:feat/frontend-agents-proofs
Oct 24, 2026
Merged

OfficialAbhinavSingh merged 31 commits into
mergit-io:mainfrom
OfficialAbhinavSingh:feat/frontend-agents-proofs

Conversation

@OfficialAbhinavSingh

@OfficialAbhinavSingh OfficialAbhinavSingh commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Summary

Updates three dashboard screens to match the dashboard in the team's landing design video, and adds the sign-out splash from the end of the video. Overview stays exactly as the Figma design. Frontend only, demo data.

Stacked on #5 (which is stacked on #4). Review only the last 8 commits here (44237c5 to 1c0d489). Once #4 and #5 merge, this diff shrinks to just those.

What it does:

  • Agents: a "Your team" row and an agent registry with category tabs, search and a verified-only switch. "+ Add" opens a side panel (model, permissions), then signs, mints an ERC-8004 identity and adds the agent to the team.
  • Proofs: a new "Proof ledger & analytics" screen. Stats count up, the runs chart draws in with a hover tooltip, plus work by agent, proofs per block, an activity heatmap, and a settlement trace whose receipts land pending and then confirm. The first receipt opens the existing work-proof page from feat(frontend): Porcelain dashboard with synced light and dark mode #4.
  • Run page: RUN-2048 replays when opened, from Running at 0m 00s to Completed at 2m 14s in about 7 seconds. Tasks appear and finish in order, the log streams, receipts settle during the settle step, and the side panel fills in once its task is done.
  • Sign out: the dashboard fades away while the Mergit mark blurs into focus with "Real work. Verifiable proof." and the settlement line. It holds for 1.7s, the session ends behind it, and it fades into the landing page. With reduced motion it shows briefly without animating. (This was feat(frontend): sign-out splash (stacked on #6) #7, folded in here.)

Copy follows the current paper, not the video: ERC-8004 identity instead of soulbound passport, value density (D) instead of star ratings, L2 testnet instead of Monad, including on the splash.

Closes #2.

Type of change

  • paper — correction, derivation, or new section in the research
  • docs — requirements, README, or other prose
  • feat — new functionality
  • fix — bug fix
  • contracts — Solidity
  • chore — dependencies, tooling, CI

What I verified

  • Verified:
    • Each screen compared frame by frame with the video at the same moments, at 1440px (the video's dashboard is a 1440 layout scaled up). Comparison images below.
    • Fresh clone on Node 22: npm ci, lint, format check, build, and 68 Playwright tests pass, 5 runs in a row, and in Firefox 157.
    • The new tests were checked to fail when the behaviour they cover is broken (team not updated, replay finishing instantly, panel details shown too early, receipt link removed, splash removed, chart labels shrunk on a phone).
    • The splash matches the video frame at 1440px: brand row, tagline and settlement line sit at the same positions, and their widths are within 1px.
    • Light and dark mode; no horizontal scroll at 1440, 1024, 390 and 320px. On phones the runs chart redraws at its real width so its labels stay readable; wider screens are pixel-identical to before.
    • Overview is unchanged.
  • Not verified:
    • Safari.
    • Anything against a backend: the mint, registry and ledger are demo data.
    • Fonts: the dashboard keeps the Figma font (Onest); the video's dashboard looks like Manrope.

Checklist

  • One concern per PR — this change does one thing
  • No secrets committed (no private keys, API keys, .env files, mnemonics)
  • Claims in the diff are supported by something a reviewer can check

Evidence

Agents → Proofs → Run replay:

dashboard walkthrough

Light Dark
Agents
Proofs
Run

Video (left) and build (right):

agents
proofs
run

Sign out:

sign out

The splash now uses the brand kit lockup:

splash with the brand kit logo

splash, video vs build, before the logo change

Runs chart at 390px:

runs chart on a phone

To run it: cd frontend && npm install && npm run dev, sign in at /, then npm run test:e2e.

Breaking changes / follow-ups

  • None breaking. The /app/proofs tab now shows the ledger instead of redirecting to proof #1840; that page is still at /app/proofs/1840.

Adds the frontend workspace for the Porcelain dashboard (mergit-io#2): Vite,
React 19, React Router and strict TypeScript, with node_modules and
build output ignored.
Ports the colour, type and shape tokens from the approved Figma files
(Porcelain and Porcelain Night) to CSS variables keyed on data-theme,
plus the shared component styles. Every colour a component uses is a
token, so switching theme is one attribute change.
- First visit follows the OS; a choice is saved, and picking the OS
  theme again clears it so the app follows the OS from then on.
- An inline script sets the theme before first paint, so no flash.
- Open tabs stay in sync through the storage event, and OS changes
  apply live while nothing is saved.
- The toggle reveals the new theme in a circle from the button via the
  View Transitions API, with a colour cross-fade fallback. Reduced
  motion switches instantly.
Floating pill nav with a sliding active tab, the theme toggle beside
notifications, shared components (badges, avatars, segmented control,
sparkline, toast), typed demo data and the Overview screen. Run filters
and approvals work locally; no number in the demo data is measured.
The run workspace draws the task graph from the design; selecting a
node updates the side panel, and the canvas zooms and pans on small
screens. New run has the prompt composer, draft plan and ask-before
switches.
Copy follows the current design rather than v0.2: identities are
ERC-8004, the receipt contract is ReceiptRegistry, the chain is an
unnamed L2 testnet, and ranking reads as value density.
Wallet shows ETH on the L2 testnet and the Identity, ReceiptRegistry
and ReputationAnchor contracts. Sign-in carries its own theme toggle.
Checks first paint follows the OS before React mounts, a saved choice
beats the OS, the toggle persists across reloads, a switch in one tab
reaches the others, the OS is followed live until a choice is saved,
and reduced motion skips the view transition. Every route renders in
both themes with the right tab active and no stale v0.2 terms.
How to run, build and test it, the route list, and how light and dark
mode work.
- Overview badge said "Proof of work", a superseded v0.2 term; it now
  reads "Verified receipts". The stale-term test checks for it.
- Spark divided by zero on a single point and crashed on none.
- Buttons with no backend behind them now say so instead of doing
  nothing.
- Segmented controls follow the radio-group keyboard pattern: arrow
  keys move the selection and focus, one tab stop per group.
- Reduced motion turns animations off rather than shortening them, so
  content never waits on a frame tick to fade in.
settle() polled running animations, which can pass in the frame before
the reveal starts, so a test could read the theme before the switch
applied. :active-view-transition is true from the moment a transition
is requested.
Controls that looked interactive but did nothing, or did the wrong thing:
- Run rows opened RUN-2048 whatever row you clicked; each row now opens
  its own run. Runs without a demo trace say so, unknown ids are a 404.
- Proof pages showed proof 1840 for any id; unknown ids are a 404, and
  the breadcrumb no longer links back to itself.
- The leaderboard range switch changed nothing; each range has its own
  ranking now.
- "Two actions are waiting" and the nav badge never changed. Approvals
  live in one provider: they count down, expire, and update both.
- Agent sort is a real select and sorts; "Verified only" reads a
  verified field.
- Wallet copy copied a literal with an ellipsis; it copies the address.
- Sign-in accepted an empty email; it is required.
- Buttons whose action needs a backend now say so instead of nothing.

Structure:
- One file per shared component instead of a grab-bag ui.tsx.
- Toast, theme and approvals split into context and provider files so
  fast refresh works; useCopy, useNotWired and useSlidingThumb are hooks.
- Run workspace split into the page, the flow graph and the task panel.
- Every displayed number and string comes from mock/data.ts, typed.
- Inline style objects replaced by named classes; only data-driven
  values (sizes, positions) stay inline.

Also fixes two regressions found by diffing against the design: graph
edges were invisible with reduced motion, and the proof facts lost the
rule under the last row.
New behaviour tests: approving updates the header count and nav badge,
asks expire on the clock, each run row opens its own run, unknown run
and proof ids are a 404, the timeline selects tasks, the leaderboard
range changes the ranking, agent sort, search and category work, sign
in requires an email, and the composer refuses an empty prompt.
- ESLint 10 with typescript-eslint strictTypeChecked, React hooks,
  react-refresh and jsx-a11y-x (the maintained fork that supports
  ESLint 10).
- Prettier at 120 columns, and an EditorConfig.
- noUncheckedIndexedAccess, so array and record lookups must handle a
  missing entry.
- lint and format scripts, Node 22.12 in engines, README updated.
Runs lint, format check, type-check and build, then the Playwright
suite, on any pull request that touches frontend/. Uploads the test
results when something fails.
- Overview: on a phone ", 17m ago" wraps together with its block number
  instead of landing on a line of its own, and "View all" no longer
  breaks onto two lines. Desktop is unchanged from the design.
- Integrations: one card per row on phones, and permission rows put the
  scope above its purpose so the access badge has its own column.
- Wallet: the settlement lag chart fills its card once the layout drops
  to one column.
- Proof diff: long lines scroll sideways instead of being cut off.
- Run: the zoom control no longer covers the proof node on phones.
- New run: the send button keeps its size at 320px.

Adds checks that no page scrolls sideways at 320 and 390px and that
integration cards keep their contents inside.
@OfficialAbhinavSingh
OfficialAbhinavSingh force-pushed the feat/frontend-agents-proofs branch from 17e81b9 to f2eb963 Compare October 14, 2026 17:01
@OfficialAbhinavSingh OfficialAbhinavSingh changed the title feat(frontend): agents registry, proof ledger and run replay (stacked on #5) feat(frontend): agents registry, proof ledger, run replay and sign-out splash (stacked on #5) Oct 14, 2026
The task activity chart's screen-reader table carried `.sr-only`
itself, but a table grows to fit its rows whatever height it is given,
so in Chrome the invisible table hung below the page and let the
overview scroll 27px into empty space at 1440 x 900. The table now sits
inside an `.sr-only` box that clips it. Nothing visible changes.

Adds a check that the overview is exactly 900px tall once its entrance
animation settles.
Swaps the old merge mark for the black-and-white logo from brand kit
v1.0. MergitLogo.tsx is the kit's component, unchanged; it draws in
currentColor, so it is ink in light mode and moon in dark mode.

- Nav and sign-in page: the horizontal lockup, since the kit says not
  to set the name in type next to the symbol.
- Wallet card: the symbol on its own.
- Favicon set, apple touch icon, app icons and web manifest from the
  kit, with the head tags from its head.html.

The old BrandMark and its circle style are gone. Tests check the nav
logo links home and that every icon in the head and the manifest
serves an image.
The landing page will own `/`, so the dashboard moves under `/app`.
Every route now comes from one paths module instead of string literals.

Signed out, a dashboard route shows the dashboard blurred and inert
behind a "Connect to Mergit" window, as in the landing design video:
pick a wallet, sign, connected, and the dashboard comes into focus.
There is no auth backend yet, so the wallet is simulated behind one
`connectWallet` function, and the session is a localStorage record.

The sign-in page's account options sign in to the demo account and its
wallet option opens the same Connect window. An account menu on the
avatar holds Sign out, which clears the session and returns to `/`.

Tests move to `/app` and start signed in through a shared fixture.
Built section by section from the 98-second landing design recording,
measured at the video's 1920px width and scaled with the viewport:

- Intro: points gather into a dotted globe with glowing nodes, arcs and
  hash labels, then the globe flies into the hero. Plays once a session,
  skips on click or key, never with reduced motion.
- Hero: word-by-word headline, a scripted agent card (prompt types,
  results land, run completes, replays), a proof-block chain that moves
  as blocks settle, floating tool tiles and a handwritten note.
- 01 How it works, 02 the team, 03 connected work, 04 a working
  approval demo, 05 the credential boundary, 06 verified receipts with
  a settling timeline, 07 FAQ, 08 call to action, and the footer.

"Try the demo" opens the Connect window. Manrope, JetBrains Mono and
Caveat match the video's type; light and dark both work.

Copy follows the current paper rather than the video: an Ethereum L2
testnet instead of Monad, ERC-8004 identities instead of soulbound
passports, value density instead of a reputation score, and receipts
instead of proof of work.
The intro hands over and can be skipped, reduced motion shows the page
at once, the section demos respond, and both themes render without
errors or stale terms. Try the demo connects and unlocks the dashboard,
Escape backs out, Sign out locks it again, and the sign-in page's
account and wallet options both work.
- The landing page's own `.landing a { color: inherit }` outranked
  `.l-btn`, so once signed in the nav's Open dashboard pill painted its
  label in the pill's colour and looked empty. The global link reset
  already does this at lower specificity, so the rule is gone.
- The Connect window sized itself against its backdrop's grid track,
  which grew to 420px, so on a 390px screen its right edge and close
  button were cut off. It now caps against the viewport.

Tests check the label colour differs from the pill and that the window
fits a phone screen.
The landing unit was `min(1px, calc(100vw / 1920))`. Firefox rounds a
sub-pixel min() result down to its 1/60px grid, so at 1440px the unit
came out 0.733px instead of 0.75px and the whole page drew about 2%
smaller than in Chrome. Taking min() of whole lengths and dividing
afterwards gives the exact value in both. Chrome renders pixel-identical
to before at 1920, 1440, 1024 and 390px.
Moves prefersReducedMotion and the typewriter hook out of the landing
page so the dashboard can use them, adds a count-up hook, the icons the
new screens need, a plain Spark variant, and the chart colours from the
design video. The typing caret moves to the shared component styles.
Removes select-chip and .cells .wide, which nothing uses any more.
Follows the Agents screen in the landing design video. "Your team"
shows the six starter agents and open slots. The registry has category
tabs, search and a verified-only switch. Adding an agent opens a drawer
(model, permissions), then signs, mints an ERC-8004 identity and puts
the agent on the team. Copy uses ERC-8004 identity and value density
instead of the video's soulbound passport and star rating.
The Proofs tab now opens the ledger from the design video: stat cards
that count up, runs vs settled proofs with a hover tooltip, work by
agent, proofs per block, an activity heatmap and a settlement trace
whose receipts land pending and then confirm. The first receipt opens
the existing work-proof page. The block number ticks while open.
As in the design video, RUN-2048 plays from 0m 00s to 2m 14s in about
seven seconds: the header shows Running with a live clock, tasks appear
and complete in order, the log streams, receipts settle during the
settle step, and the side panel's summary types out once its task is
done. Reduced motion shows the finished run at once.
Adding an agent mints an identity and puts it on the team; Escape backs
out; category, search and verified-only filter the registry. The ledger
counts up, confirms receipts, opens the first one and shows a hover
tooltip; the block ticks. The run replays over seconds (not one frame),
fills the side panel when its task finishes, and reduced motion shows
the finished run at once. Each new test was checked to fail when the
behaviour it covers is broken.
As at the end of the landing design video: Sign out fades the dashboard
away while the Mergit mark blurs into focus over white, with the tagline
and settlement line. It holds for 1.7s, the session ends behind it, and
it fades away over the landing page. Reduced motion holds it briefly
without animating. Sizes and position match the video frame.
Checked to fail when the splash is removed.
The chart scales the 1120px design plot into its card, which on a phone
shrank the axis labels to a few pixels. Below 600px it now redraws at its
real width instead, so labels stay at their set size. Wider screens keep
the scaled design plot unchanged.

@Viscous106 Viscous106 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@OfficialAbhinavSingh
OfficialAbhinavSingh merged commit 2da7d73 into mergit-io:main Oct 24, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Kanban Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Mergit Frontend planning

2 participants