Repository navigation
docs(chains): generate agent-facing Supported Chains tables - #553
pedromcunha-uneven wants to merge 3 commits into
Conversation
Supported Chains renders its tables client-side, so its Markdown export and llms-full.txt list no chains. scripts/build-chains.mjs writes Markdown tables from /chains into snippets shown only to agents, and an hourly workflow opens a sync PR when the list changes.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
|
Claude finished @pedromcunha-uneven's task in 1m 3s —— View job Code review
I found no blocking bugs. The approach fits the problem, and the workflow does what Sync Changelog does. Notes below, most important first. 1. Chain names go into MDX with only 2. The "already carries these chains" check is written differently from Sync Changelog ( 3. An API outage turns the hourly job red 4. Name casing differs slightly from the live table (cosmetic) 5. Docs and process gaps (non-blocking)
Checked and fine
I didn't run |
[Medium impact] The PR appears safe to merge; no new actionable issues were found.
|
Escape MDX characters and collapse whitespace in generated cells, render both environments before writing either snippet, document the generated snippets in AGENTS.md, and restore the key rationale comments from Sync Changelog.
|
Claude finished @pedromcunha-uneven's task in 44s —— View job Code review (re-review after
|
Delete the sync branch whenever its own changes touch only the chain snippets and those snippets match main, measured from the merge base so unrelated merges to main do not block it. Guard the sort against a missing displayName.
|
Claude finished @pedromcunha-uneven's task in 38s —— View job Code review (re-review after
|
| Situation | Result |
|---|---|
Sync PR merged (squash or merge), snippets match main |
Branch deleted ✅ |
/chains reverted before merge |
Branch deleted, so the stale PR closes ✅ |
| Branch has a non-snippet human edit | Warning only, branch kept ✅ |
| No sync branch on the remote | ls-remote fails, no-op ✅ |
main changed meanwhile, /chains still differs |
Force-update path runs, as before ✅ |
fetch-depth: 0 fetches all branches, so origin/$SYNC_BRANCH and the merge base are available to the script.
Minor, non-blocking
- Human edits are protected in one path but not the other (
sync-chains.yml, thegit checkout -B+git push --forcepath). The delete path is careful to leave a branch that carries human edits, but whenever/chainsdiffers frommain, the update path rebuilds the branch asmainplus one commit and force-pushes. That throws away the same edits the delete path protects. Sync Changelog has the same behavior, and the snippets are marked "never edit by hand", so this is consistent with the existing design. If you want the protection to be real, apply the samemerge-basecheck before the force push and warn instead of pushing. - The comment on the delete path overstates the guarantee. It says the branch "may hold edits this job did not make", which suggests those edits are kept. Given the point above, it would help to say that only this path preserves them.
set -eandmerge-base: ifgit merge-baseever finds no common ancestor (for example after a force-rewrite ofmain), the step exits red without a clear message. This is very unlikely, and failing loudly is acceptable.
Checked and fine
- The page puts the generated tables inside
<Visibility for="agents">.<Chains>returnsnullserver-side, so readers see one table and the Markdown export shows the other. - The generated output is clean. The 57 mainnet rows have no escaped characters today, and the testnet snippet lists Base Sepolia and Sepolia.
- Sorting matches the live table (
displayName, thenid), the output is deterministic, and--checkdoesn't write anything. - Actions are pinned by SHA, the cron runs at :47 (no collision), and
concurrencyblocks overlapping runs.
I couldn't run the script or mint dev because this runner can't reach api.relay.link, and the local clone has no merge base with origin/main. This review is based on the diff and the workflow logic.
|
Closing in favor of a different approach: serving Supported Chains to agents from a small reverse proxy in front of docs.relay.link that builds the table live from /chains, instead of generated snippets and a sync workflow. Tracked in Linear. |
Supported Chains renders its chain tables in the browser (
snippets/Chains.mdxfetches/chainsclient-side and returnsnullotherwise). As a result, the page's Markdown export, andllms-full.txt, show empty "Mainnets" and "Testnets" headings, so agents never see Bitcoin, Solana, Tron, TON or Hyperliquid. This keeps the live table for readers and gives agents a generated copy.Changes / decisions to review
scripts/build-chains.mjsfetcheshttps://api.relay.link/chainsandhttps://api.testnets.relay.link/chainsand writes one Markdown table per environment tosnippets/supported-chains-{mainnets,testnets}.mdx. Each table has these columns: Chain, Chain ID, VM type, Supported Tokens. Rows are sorted by display name, like the live table. Both environments are fetched and rendered before either file is written, so if either API call errors or returns no chains, the script fails and writes nothing. Cell values have MDX characters (| { } < >) escaped and line breaks collapsed, so an unusual chain name can't break the page. The output is deterministic, and--checkexits 1 when a snippet is stale.bvm,svm,tvm,tonvm,hypevm, …).<Visibility for="agents">under the existing<Chains>component. Readers see only the live table, and the Markdown export shows only the generated one..github/workflows/sync-chains.ymlruns hourly at :47, offset from Sync Changelog (:17) and Sync API Reference (:37), and on pushes tomainthat change the script. It copies Sync Changelog's flow: rebuild, then open or force-update onebot/chains-syncPR, and leave an open PR alone when its content already matches. Unlike the changelog, a chain list can revert, so the job deletes the sync branch (closing its PR) whenever the branch's own changes touch only the snippets and the snippets matchmainagain. That check runs from the merge base, so unrelated merges tomaindon't block it. A branch carrying any other edit is left alone with a warning.markdown.instructionschange. The page now carries the list itself.Verification
mint dev: the page's.mdexport lists all 57 mainnet chains and 2 testnet chains, with no leftover markup. The rendered page shows only the live table (57 + 2 rows), and there's no visible "VM type" column.| < > { }, the page still compiles and renders, and the Markdown export shows those characters literally.build-chains.mjs --checkpasses on fresh output and exits 1 after one row is edited by hand.ghin five cases: no change (no-op), change with no PR (opens one), same change with a PR open (left alone), new change with a PR open (force-updated),maincaught up (branch deleted),/chainsreverting before merge (stale branch deleted), a squash merge after unrelated commits landed onmain(branch deleted), and a human edit on the sync branch followed by a revert (branch kept, with a warning).mint validatestill fails onmainbecause of the existing<StatusWebsockets>error incalling-integration-guide.mdx. This PR doesn't touch that file.