Repository navigation
docs: fix sei-skill bridges, add AI menu targets, and check redirects in CI - #84
Conversation
The overview still listed Wormhole and Axelar as bridges. The skill itself (sei-protocol/sei-skill@e2445c8) now names LayerZero V2 and Circle CCTP v2 as the bridges Sei documents, treats Wormhole as unverified because Sei has no Wormhole guide, and no longer mentions Axelar. Say the same here, and note that IBC is disabled in both directions, linking the SIP-03 section that explains it. Co-authored-by: Cursor <cursoragent@cursor.com>
Mintlify's contextual menu supports these targets now. grok and aistudio sit with the other open-in-chat options; add-mcp copies the npx add-mcp install command for the hosted MCP server and sits next to the existing mcp option. The other new targets (assistant, devin, devin-mcp) are left for a separate decision, since assistant responses cost Mintlify credits. Co-authored-by: Cursor <cursoragent@cursor.com>
Requesting every redirect source on docs.sei.io, 237 of 239 land on their destination. /evm/MyContract.json and /genesis.json return 404 without redirecting, so Mintlify doesn't apply redirects to paths ending in .json (other extensions, such as /node/priv_validator_state.json.tmp, redirect fine). Both are artifact paths from the Nextra-era tutorials rather than pages, so remove entries that never run. Co-authored-by: Cursor <cursoragent@cursor.com>
validate-docs checks that every nav page exists, but nothing checked redirect destinations, so renaming or deleting a page could leave redirects pointing at a 404. scripts/check-redirects.mjs resolves each internal destination to a page (.mdx, .md, or an index page), a static file such as /skill.md, or, for :slug* destinations, the directory the match forwards into. A destination that is itself a redirect source fails with a hint to point at the final page. Names are compared against directory listings so the check stays case-sensitive on macOS, matching the Linux runner. All 237 current destinations pass. Injecting a missing page, a missing wildcard directory, a redirect chain, and a wrong-case path failed on each; anchors, query strings, external URLs, and / pass. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
PR SummaryLow Risk Overview Content/config tweaks: Reviewed by Cursor Bugbot for commit 483f84b. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
This is a small, well-scoped PR: it corrects the sei-skill bridges line, adds three menu targets that are in the schema, removes two redirects that never fire, and adds a sound CI check for redirect destinations. I found no blocking issues; only minor nits remain.
Findings: 0 blocking | 6 non-blocking | 3 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review (
cursor-review.md) was empty, so that pass produced no output. Codex found no material issues, and I agree. REVIEW_GUIDELINES.mdis empty on the base branch, so this review applies only the conventions inAGENTS.md.- I confirmed that the new link anchor
/learn/sip-03-migration#ibc-is-disabledmatches the## IBC is disabledheading on that page. The CI job runs onubuntu-latest, and its Node version supports top-level await, so the new step needs no setup-node change. - 3 suggestion(s)/nit(s) flagged inline on specific lines.
| **Ecosystem** — infrastructure and integrations: | ||
| - RPC endpoints (public, community, paid SaaS) | ||
| - Bridges (LayerZero V2, Wormhole, Axelar, CCTP) | ||
| - Bridges (LayerZero V2, Circle CCTP v2 for native USDC); IBC is [disabled in both directions](/learn/sip-03-migration#ibc-is-disabled) |
There was a problem hiding this comment.
[nit] This bullet puts two ideas into one line joined by a semicolon: the supported bridges and the IBC status. AGENTS.md prefers one idea per sentence. Consider moving the IBC note into its own bullet, for example - IBC is [disabled in both directions](...).
|
|
||
| const candidates = path | ||
| ? [path, `${path}.mdx`, `${path}.md`, `${path}/index.mdx`, `${path}/index.md`] | ||
| : ['index.mdx', 'index.md']; |
There was a problem hiding this comment.
[nit] The first candidate is the bare path, so any file in the repo counts as a valid destination, including docs.json, images, and scripts. Pages are .mdx/.md, so this can hide a typo'd destination that happens to match a non-page file. It's fine if static-asset destinations are intended; otherwise consider dropping the bare-path candidate or limiting it to known asset extensions.
| const target = `/${path}`; | ||
| failures.push( | ||
| sources.has(target) | ||
| ? `${source} -> ${destination}: ${target} is itself a redirect; point at its destination instead` |
There was a problem hiding this comment.
[nit] The redirect-chain check only runs when no page exists at the destination. A destination that is both a page and a redirect source is never flagged. That's probably harmless, but the PR description says the script flags any destination that is itself a redirect, which is broader than what the code does. Consider narrowing the description or checking sources.has(target) without the page condition.
The bridges bullet carried two ideas joined by a semicolon, and AGENTS.md asks for one idea per sentence (seidroid nit on #84). Co-authored-by: Cursor <cursoragent@cursor.com>
Two seidroid nits on #84. The chain check only ran when no page existed at the destination, so a destination that was both a page and a redirect source passed; check sources first so any chained destination fails. And any repo file counted as a destination, so a typo matching docs.json, a script, or an image would pass; only markdown and text files such as /skill.md and /llms.txt can now match directly. All 237 current destinations still pass. /docs.json, /favicon.svg, and a destination that is both a page and a redirect source now fail alongside the earlier missing-page, wildcard, chain, and wrong-case cases. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This is a small, well-scoped PR. It corrects the sei-skill bridges list, adds three valid page-menu AI targets, drops two .json redirects that never fire, and adds a CI check that redirect destinations exist. The new #ibc-is-disabled anchor resolves in learn/sip-03-migration.mdx, and Codex reports that the checker passes. I found nothing blocking, only minor notes.
Findings: 0 blocking | 5 non-blocking | 2 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor second-opinion review file (
cursor-review.md) was empty, so that pass produced no output.REVIEW_GUIDELINES.mdwas also empty, so I usedAGENTS.mdconventions instead. check-redirects.mjsonly flags a redirect chain when the destination exactly matches a static source. A destination that is caught by a wildcard source such as/.sei/:path*would not be flagged. This is acceptable for now, but worth knowing about.- The checker only verifies that a page file exists. It does not check that the destination is listed in
docs.jsonnavigation. An orphaned page would pass, although the existing orphaned-MDX step partly covers this. - 2 suggestion(s)/nit(s) flagged inline on specific lines.
| - RPC endpoints (public, community, paid SaaS) | ||
| - Bridges (LayerZero V2, Wormhole, Axelar, CCTP) | ||
| - Bridges (LayerZero V2, Circle CCTP v2 for native USDC) | ||
| - IBC is [disabled in both directions](/learn/sip-03-migration#ibc-is-disabled) |
There was a problem hiding this comment.
[nit] The IBC line isn't an integration, so it reads a little oddly in a list of infrastructure items. Consider folding it into the bridges bullet, for example: Bridges (LayerZero V2, Circle CCTP v2 for native USDC; IBC is [disabled in both directions](...)).
| // script, or an image. | ||
| const candidates = path | ||
| ? [ | ||
| ...(/\.(md|txt)$/.test(path) ? [path] : []), |
There was a problem hiding this comment.
[nit] The elements of the array inside the ternary are indented at the same level as the ? [. Indenting them one more level, or letting Prettier format the block, would read more clearly.
The multi-line array inside the ternary was indented at the same level as its bracket (seidroid nit on #84). Keep the page candidates on one line and push the direct-file candidate separately. Behavior is unchanged: the same 237 destinations pass and the same injected cases fail. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This is a clean, well-scoped PR. It corrects the sei-skill bridges list, adds valid AI menu targets, drops two .json redirects that never fire, and adds a sound CI check for redirect destinations. I found no blocking issues, only minor notes.
Findings: 0 blocking | 5 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review file (
cursor-review.md) was empty, so that pass produced no output. Codex reported no material issues, and the redirect checker passed for all 237 local destinations. REVIEW_GUIDELINES.mdis empty, so I applied only the conventions inAGENTS.md.- The redirect-chain check in
scripts/check-redirects.mjscompares exact strings only. It misses a destination that differs from a redirect source by a trailing slash, and one that a wildcard source (for example/.sei/:path*) would match. This is acceptable for now; consider normalizing trailing slashes if chains become a concern. - I verified that the
#ibc-is-disabledanchor exists inlearn/sip-03-migration.mdx(the## IBC is disabledheading). - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| - RPC endpoints (public, community, paid SaaS) | ||
| - Bridges (LayerZero V2, Wormhole, Axelar, CCTP) | ||
| - Bridges (LayerZero V2, Circle CCTP v2 for native USDC) | ||
| - IBC is [disabled in both directions](/learn/sip-03-migration#ibc-is-disabled) |
There was a problem hiding this comment.
[nit] This IBC note sits in the Ecosystem list as its own bullet, but it isn't an infrastructure item like the others. Consider folding it into the Bridges bullet. For example: Bridges (LayerZero V2, Circle CCTP v2 for native USDC; IBC is [disabled in both directions](...)). Or nest it under Bridges as a sub-bullet.
seidroid asked on #84 first for the IBC note to be its own line (one idea per sentence), then pointed out that a top-level IBC bullet isn't an infrastructure item like its neighbors. A sub-bullet under Bridges keeps both: its own line, grouped with the bridges it constrains. Co-authored-by: Cursor <cursoragent@cursor.com>
…ions Destinations were already compared without a trailing slash, but sources were compared as written, so a source like /evm/networks/ never matched a destination of /evm/networks and the chain went unflagged (seidroid note on #84). Strip trailing slashes from sources too, keeping / as the root. All 237 current destinations still pass, and an injected /evm/networks/ source now fails the redirect that points at /evm/networks. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
The content fix, the page-menu additions, the removal of two dead .json redirects, and the new redirect-destination check in CI all look correct. The #ibc-is-disabled anchor exists in learn/sip-03-migration.mdx, and Codex found no issues. Only minor notes remain.
Findings: 0 blocking | 5 non-blocking | 2 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review file (
cursor-review.md) was empty, so that pass produced no output.REVIEW_GUIDELINES.mdwas also empty, so no repo-specific guidelines were applied. - The redirect-chain check only catches exact matches against static sources. A destination covered by a wildcard source (e.g. anything under
/.sei/:path*) would still pass as long as a page exists there. This is an acceptable edge case, and a comment in the script could note it. - In
exists(), the parallelPromise.all(candidates.map(isFile))calls can race and read the same directory more than once before the cache fills. The result is still correct; it just repeats some work. Caching the readdir promise instead of the resolved Set would remove the duplicate reads. - 2 suggestion(s)/nit(s) flagged inline on specific lines.
| - RPC endpoints (public, community, paid SaaS) | ||
| - Bridges (LayerZero V2, Wormhole, Axelar, CCTP) | ||
| - Bridges (LayerZero V2, Circle CCTP v2 for native USDC) | ||
| - IBC is [disabled in both directions](/learn/sip-03-migration#ibc-is-disabled) |
There was a problem hiding this comment.
[nit] Nesting the IBC note under "Bridges" reads as if IBC were one of the bridges the skill covers. You could make it a parenthetical on the bridges line, or a separate bullet. Optional.
| for (const name of path.split('/')) { | ||
| if (!listings.has(dir)) { | ||
| listings.set(dir, new Set(await readdir(`${repoDir}${dir}`).catch(() => []))); | ||
| } |
There was a problem hiding this comment.
[nit] Suggestion: store the readdir promise in listings, e.g. listings.set(dir, readdir(...).then(n => new Set(n), () => new Set())), and await it. Concurrent isFile calls from Promise.all would then share a single read.
The listing cache stored the resolved Set, so the parallel isFile calls for one destination could each read the same directory before the cache filled. Cache the readdir promise instead so they share one read. Also note in the chain check that only exact sources are matched: a destination under a wildcard source such as /.sei/:path* is not flagged (both seidroid notes on #84). Results are unchanged: all 237 destinations pass and every injected case still fails. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This PR is clean and ready to merge. It corrects the bridges list on the sei-skill page and links it to an anchor that exists (#ibc-is-disabled in learn/sip-03-migration.mdx). It adds valid contextual.options entries, removes two .json redirects that never fire, and adds a sound redirect-destination check to CI. Codex found no issues, and I found no blockers.
Findings: 0 blocking | 5 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review file (
cursor-review.md) was empty, so there was no second opinion from Cursor. Codex reported no material issues and said the redirect check passes for all 237 local destinations. REVIEW_GUIDELINES.mdis empty on the base branch, so I reviewed againstAGENTS.mdconventions only.- The chain check in
check-redirects.mjsonly compares destinations against exact redirect sources. A destination caught by a wildcard source (for example/.sei/:path*) won't be flagged as a chain. The code comment says this is intentional; a regression fixture could be added later if you want to lock in this behavior. - Optional: have the script say which case it hit (missing
.mdx, missing index, wrong case) so failures are quicker to fix. It's usable as it is. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| const isFile = async (path) => | ||
| (await exists(path)) && (await stat(`${repoDir}${path}`)).isFile(); | ||
| const isDirectory = async (path) => | ||
| !path || ((await exists(path)) && (await stat(`${repoDir}${path}`)).isDirectory()); |
There was a problem hiding this comment.
[nit] isDirectory('') returns true because of the !path || short-circuit. A dynamic destination like /:slug* (no static prefix) therefore always passes. That's reasonable because the repo root always exists, but a short comment would make it clear this is intended.
What is the purpose of the change?
Corrects stale content on the sei-skill overview, adds three AI targets to the page menu, removes two redirects that never fire, and adds a CI guard so redirects can't silently point at missing pages. These are the quick wins from the Sei vs. Solana docs review.
Describe the changes to the documentation
ai/sei-skill/index.mdx: The bridges line listed Wormhole and Axelar. It now matches the current skill source (sei-skill@e2445c8): LayerZero V2 and Circle CCTP v2 are the bridges Sei documents, and IBC is disabled in both directions, linked to the SIP-03 section that explains it.docs.json→contextual.options): Addsgrok,aistudio, andadd-mcp. All three are in the enum in Mintlify's publisheddocs.jsonschema.assistant,devin, anddevin-mcpare also available but left out for now; assistant responses cost Mintlify credits.docs.json): Removes/evm/MyContract.jsonand/genesis.json. I requested all 239 redirect sources on docs.sei.io: 237 land on their destination, and these two return 404 without redirecting. Mintlify doesn't apply redirects to paths ending in.json.validate-docs.yml,scripts/check-redirects.mjs): A new step fails when a redirect's destination isn't a page in the repo (or, for:slug*destinations, a directory to forward into). It also flags a destination that is itself a redirect.AGENTS.mdnow mentions the script in its Redirects section.Notes
node scripts/check-redirects.mjspasses for all 237 destinations. Injected bad redirects (missing page, missing wildcard directory, redirect chain, wrong-case path) each fail, and anchors, query strings, external URLs, and/pass.mint validate(strict) andmint broken-linkspass with the latest CLI, typos passes, and Vale reports nothing on the changed lines.references/ecosystem/bridges.md. That fix belongs insei-protocol/sei-skill.