Skip to content

docs: add TOC page actions split dropdown with LLM + markdown actions#2333

Draft
notrab wants to merge 2 commits into
mainfrom
docs/page-actions-dropdown
Draft

docs: add TOC page actions split dropdown with LLM + markdown actions#2333
notrab wants to merge 2 commits into
mainfrom
docs/page-actions-dropdown

Conversation

@notrab

@notrab notrab commented Jun 22, 2026

Copy link
Copy Markdown
Member

DO NOT REVIEW

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • What changed (1-3 bullets, no essays).

Why

  • Why this change exists. Link to related GitHub issues where relevant.

Testing

  • How this was tested.
  • If you didn't test it, say why.

Notes for Reviewer (Optional)

  • Anything non-obvious or worth a heads-up.

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

Copilot AI review requested due to automatic review settings June 22, 2026 08:26
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
enskit-react-example.ensnode.io Ready Ready Preview, Comment Jun 23, 2026 7:28pm
ensnode.io Ready Ready Preview, Comment Jun 23, 2026 7:28pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Jun 23, 2026 7:28pm
ensrainbow.io Skipped Skipped Jun 23, 2026 7:28pm

@changeset-bot

changeset-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e141152

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Eight SVG icon atom components are added (ChatGptIcon, ClaudeIcon, MarkdownIcon, ChevronDownIcon, CopyIcon, FileTextIcon, LinkIcon, SparklesIcon). A new PageActionsMenu.astro molecule uses these icons to render a split-button AI actions menu per page, and is inserted into the TableOfContents override. The ai-llm.mdx doc page receives grammar fixes, quickstart clarifications, a new Verify Installation section, and llms.txt usage guidance.

Changes

PageActionsMenu Component

Layer / File(s) Summary
SVG icon atoms
docs/ensnode.io/src/components/atoms/icons/ChatGptIcon.tsx, ClaudeIcon.tsx, MarkdownIcon.tsx, ChevronDownIcon.tsx, CopyIcon.tsx, FileTextIcon.tsx, LinkIcon.tsx, SparklesIcon.tsx
Eight new exported SVG React components added, each accepting SVGProps<SVGSVGElement> with passthrough props and accessibility attributes.
PageActionsMenu: URL logic, markup, client script, styles
docs/ensnode.io/src/components/molecules/PageActionsMenu.astro
Computes GitHub raw markdown source URL from the Starlight route; renders split-button toggle and dropdown for ChatGPT, Claude, view-as-Markdown, copy-URL, and copy-page actions; implements HEAD probe for index.md, async action handlers, menu state management, and scoped styles.
TableOfContents override wiring
docs/ensnode.io/src/components/overrides/TableOfContents.astro
Imports PageActionsMenu and inserts <PageActionsMenu /> into the rendered markup before the first <br />.

AI/LLM Documentation Updates

Layer / File(s) Summary
ai-llm.mdx content improvements
docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
Adjusts intro phrasing; adds Node vs. non-Node guidance for quickstart paths; introduces a Verify Installation subsection with a sample prompt.md block; adds a note distinguishing /llms.txt and /llms-full.txt usage.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(173, 216, 230, 0.5)
    participant User
    participant PageActionsMenu
    participant HeadProbe as HEAD index.md probe
    participant ClipboardAPI as navigator.clipboard
    participant WindowOpen as window.open
  end

  User->>PageActionsMenu: click toggle button
  PageActionsMenu->>HeadProbe: HEAD route-relative index.md
  HeadProbe-->>PageActionsMenu: 200 OK or fallback to sourceMarkdownUrl

  User->>PageActionsMenu: click action item
  alt Ask in ChatGPT or Claude
    PageActionsMenu->>WindowOpen: open with encoded prompt + markdownUrl
  else View as Markdown
    PageActionsMenu->>WindowOpen: open markdownUrl
  else Copy Markdown URL
    PageActionsMenu->>ClipboardAPI: writeText(markdownUrl)
  else Copy page content
    PageActionsMenu->>HeadProbe: GET markdownUrl
    HeadProbe-->>PageActionsMenu: markdown text
    PageActionsMenu->>ClipboardAPI: writeText(markdownContent)
  end
  PageActionsMenu-->>User: show success/error feedback (auto-hide)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • namehash/ensnode#1805: Both PRs modify docs/ensnode.io/src/components/overrides/TableOfContents.astro to alter auxiliary UI rendered alongside the table of contents.
  • namehash/ensnode#2112: Both PRs modify docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx, updating installation and llms.txt guidance on the same page.

Suggested labels

docs

🐇 Hop, hop, a menu appears!
ChatGPT and Claude, I click with cheers,
Eight icons gleam in SVG rows,
Markdown copied wherever it goes.
Ask the AI — the rabbit knows! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely unfilled, containing only the template structure with 'DO NOT REVIEW' header and empty placeholder sections. Complete all required sections: provide a concise summary of changes, explain the rationale with any issue links, describe testing approach, and fill in reviewer notes if applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: adding a TOC page actions component with LLM and markdown integration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/page-actions-dropdown

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds “page actions” UI to the docs Table of Contents area so readers can quickly copy the current page’s Markdown, open the page in popular LLM chats, or grab the raw Markdown URL. Also tightens up the AI/LLM tooling docs with additional guidance and a “verify installation” prompt.

Changes:

  • Adds a new PageActions split-button dropdown and mounts it above the TOC via the Starlight TableOfContents override.
  • Introduces new icon components (ChatGPT/Claude/Markdown) used by the page actions menu.
  • Expands the AI/LLM docs page with clearer “when to use which install path” guidance and /llms*.txt usage notes.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx Improves AI/LLM tooling documentation clarity and adds a verification prompt.
docs/ensnode.io/src/components/overrides/TableOfContents.astro Renders the new PageActions component above the TOC for docs pages.
docs/ensnode.io/src/components/molecules/PageActions.astro Implements the split-button dropdown UI + client-side handlers for copy/open actions.
docs/ensnode.io/src/components/atoms/icons/MarkdownIcon.tsx Adds a Markdown icon for menu items.
docs/ensnode.io/src/components/atoms/icons/ClaudeIcon.tsx Adds a Claude icon for menu items.
docs/ensnode.io/src/components/atoms/icons/ChatGptIcon.tsx Adds a ChatGPT icon for menu items.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +140 to +142
function getRouteMarkdownUrl() {
return new URL("index.md", window.location.href.replace(/\/?$/, "/")).toString();
}
Comment on lines +12 to +14
>
<title>OpenAI</title>
<path d="M21.55 10.004a5.416 5.416 0 00-.478-4.501c-1.217-2.09-3.662-3.166-6.05-2.66A5.59 5.59 0 0010.831 1C8.39.995 6.224 2.546 5.473 4.838A5.553 5.553 0 001.76 7.496a5.487 5.487 0 00.691 6.5 5.416 5.416 0 00.477 4.502c1.217 2.09 3.662 3.165 6.05 2.66A5.586 5.586 0 0013.168 23c2.443.006 4.61-1.546 5.361-3.84a5.553 5.553 0 003.715-2.66 5.488 5.488 0 00-.693-6.497v.001zm-8.381 11.558a4.199 4.199 0 01-2.675-.954c.034-.018.093-.05.132-.074l4.44-2.53a.71.71 0 00.364-.623v-6.176l1.877 1.069c.02.01.033.029.036.05v5.115c-.003 2.274-1.87 4.118-4.174 4.123zM4.192 17.78a4.059 4.059 0 01-.498-2.763c.032.02.09.055.131.078l4.44 2.53c.225.13.504.13.73 0l5.42-3.088v2.138a.068.068 0 01-.027.057L9.9 19.288c-1.999 1.136-4.552.46-5.707-1.51h-.001zM3.023 8.216A4.15 4.15 0 015.198 6.41l-.002.151v5.06a.711.711 0 00.364.624l5.42 3.087-1.876 1.07a.067.067 0 01-.063.005l-4.489-2.559c-1.995-1.14-2.679-3.658-1.53-5.63h.001zm15.417 3.54l-5.42-3.088L14.896 7.6a.067.067 0 01.063-.006l4.489 2.557c1.998 1.14 2.683 3.662 1.529 5.633a4.163 4.163 0 01-2.174 1.807V12.38a.71.71 0 00-.363-.623zm1.867-2.773a6.04 6.04 0 00-.132-.078l-4.44-2.53a.731.731 0 00-.729 0l-5.42 3.088V7.325a.068.068 0 01.027-.057L14.1 4.713c2-1.137 4.555-.46 5.707 1.513.487.833.664 1.809.499 2.757h.001zm-11.741 3.81l-1.877-1.068a.065.065 0 01-.036-.051V6.559c.001-2.277 1.873-4.122 4.181-4.12.976 0 1.92.338 2.671.954-.034.018-.092.05-.131.073l-4.44 2.53a.71.71 0 00-.365.623l-.003 6.173v.002zm1.02-2.168L12 9.25l2.414 1.375v2.75L12 14.75l-2.415-1.375v-2.75z" />
Comment on lines +13 to +15
>
<title>Anthropic</title>
<path d="m50.228 170.321 50.357-28.257.843-2.463-.843-1.361h-2.462l-8.426-.518-28.775-.778-24.952-1.037-24.175-1.296-6.092-1.297L0 125.796l.583-3.759 5.12-3.434 7.324.648 16.202 1.101 24.304 1.685 17.629 1.037 26.118 2.722h4.148l.583-1.685-1.426-1.037-1.101-1.037-25.147-17.045-27.22-18.017-14.258-10.37-7.713-5.25-3.888-4.925-1.685-10.758 7-7.713 9.397.649 2.398.648 9.527 7.323 20.35 15.75L94.817 91.9l3.889 3.24 1.555-1.102.195-.777-1.75-2.917-14.453-26.118-15.425-26.572-6.87-11.018-1.814-6.61c-.648-2.723-1.102-4.991-1.102-7.778l7.972-10.823L71.42 0 82.05 1.426l4.472 3.888 6.61 15.101 10.694 23.786 16.591 32.34 4.861 9.592 2.592 8.879.973 2.722h1.685v-1.556l1.36-18.211 2.528-22.36 2.463-28.776.843-8.1 4.018-9.722 7.971-5.25 6.222 2.981 5.12 7.324-.713 4.73-3.046 19.768-5.962 30.98-3.889 20.739h2.268l2.593-2.593 10.499-13.934 17.628-22.036 7.778-8.749 9.073-9.657 5.833-4.601h11.018l8.1 12.055-3.628 12.443-11.342 14.388-9.398 12.184-13.48 18.147-8.426 14.518.778 1.166 2.01-.194 30.46-6.481 16.462-2.982 19.637-3.37 8.88 4.148.971 4.213-3.5 8.62-20.998 5.184-24.628 4.926-36.682 8.685-.454.324.519.648 16.526 1.555 7.065.389h17.304l32.21 2.398 8.426 5.574 5.055 6.805-.843 5.184-12.962 6.611-17.498-4.148-40.83-9.721-14-3.5h-1.944v1.167l11.666 11.406 21.387 19.314 26.767 24.887 1.36 6.157-3.434 4.86-3.63-.518-23.526-17.693-9.073-7.972-20.545-17.304h-1.36v1.814l4.73 6.935 25.017 37.59 1.296 11.536-1.814 3.76-6.481 2.268-7.13-1.297-14.647-20.544-15.1-23.138-12.185-20.739-1.49.843-7.194 77.448-3.37 3.953-7.778 2.981-6.48-4.925-3.436-7.972 3.435-15.749 4.148-20.544 3.37-16.333 3.046-20.285 1.815-6.74-.13-.454-1.49.194-15.295 20.999-23.267 31.433-18.406 19.702-4.407 1.75-7.648-3.954.713-7.064 4.277-6.286 25.47-32.405 15.36-20.092 9.917-11.6-.065-1.686h-.583L44.07 198.125l-12.055 1.555-5.185-4.86.648-7.972 2.463-2.593 20.35-13.999-.064.065Z" />

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/ensnode.io/src/components/molecules/PageActions.astro`:
- Around line 2-4: Replace the relative import paths in the three icon imports
(ChatGptIcon, ClaudeIcon, and MarkdownIcon) with the configured `@components` path
alias. Instead of using "../atoms/icons/", use "`@components/atoms/icons/`" as the
import path for all three icon imports to comply with the docs-site path alias
conventions for src files.
- Around line 196-204: The openInChatGPT and openInClaude functions are
experiencing popup blocking because they await the getLlmPrompt() async
operation before calling openChat, creating an async gap that causes the browser
to lose transient user activation needed for window.open to succeed. Move the
openChat() call outside of the async chain to execute synchronously on the user
click event, then fetch the prompt asynchronously afterward. You can either call
openChat with a temporary placeholder message immediately and update it after
the prompt loads, or refactor to open the window first synchronously and then
update its location/content once getLlmPrompt completes.

In `@docs/ensnode.io/src/components/overrides/TableOfContents.astro`:
- Line 4: The import statement for PageActions on line 4 is using a relative
path instead of following the project's path alias policy for src files. Replace
the relative path `"../molecules/PageActions.astro"` in the PageActions import
with the `@components` path alias to comply with the docs-site coding guidelines
that require all imports in src Astro files to use established path aliases.

In `@docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx`:
- Around line 52-53: The version token `v${snapshot.sdkVersion}` is wrapped in
markdown backticks which prevents it from being interpolated and causes it to
display as literal text instead of the actual version number. Remove the
backticks surrounding the `v${snapshot.sdkVersion}` token in the sentence about
pinning to the matching version tag so that the variable can be properly
interpolated and display the actual SDK version to readers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb18cf90-1420-4aeb-8a1f-8fd0ffda8b2b

📥 Commits

Reviewing files that changed from the base of the PR and between 8889927 and 0d720c6.

📒 Files selected for processing (6)
  • docs/ensnode.io/src/components/atoms/icons/ChatGptIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/ClaudeIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/MarkdownIcon.tsx
  • docs/ensnode.io/src/components/molecules/PageActions.astro
  • docs/ensnode.io/src/components/overrides/TableOfContents.astro
  • docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx

Comment on lines +2 to +4
import { ChatGptIcon } from "../atoms/icons/ChatGptIcon";
import { ClaudeIcon } from "../atoms/icons/ClaudeIcon";
import { MarkdownIcon } from "../atoms/icons/MarkdownIcon";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use configured @components aliases instead of relative imports.

These new imports on Line 2-Line 4 bypass the docs-site alias contract for src files.

Suggested change
-import { ChatGptIcon } from "../atoms/icons/ChatGptIcon";
-import { ClaudeIcon } from "../atoms/icons/ClaudeIcon";
-import { MarkdownIcon } from "../atoms/icons/MarkdownIcon";
+import { ChatGptIcon } from "`@components/atoms/icons/ChatGptIcon`";
+import { ClaudeIcon } from "`@components/atoms/icons/ClaudeIcon`";
+import { MarkdownIcon } from "`@components/atoms/icons/MarkdownIcon`";

As per coding guidelines: docs/ensnode.io/{config,scripts,src}/**/*.{ts,tsx,astro} must use path aliases (@components, @content, @data, @lib, @scripts, @styles, @assets, @workspace).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ChatGptIcon } from "../atoms/icons/ChatGptIcon";
import { ClaudeIcon } from "../atoms/icons/ClaudeIcon";
import { MarkdownIcon } from "../atoms/icons/MarkdownIcon";
import { ChatGptIcon } from "`@components/atoms/icons/ChatGptIcon`";
import { ClaudeIcon } from "`@components/atoms/icons/ClaudeIcon`";
import { MarkdownIcon } from "`@components/atoms/icons/MarkdownIcon`";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/components/molecules/PageActions.astro` around lines 2 -
4, Replace the relative import paths in the three icon imports (ChatGptIcon,
ClaudeIcon, and MarkdownIcon) with the configured `@components` path alias.
Instead of using "../atoms/icons/", use "`@components/atoms/icons/`" as the import
path for all three icon imports to comply with the docs-site path alias
conventions for src files.

Source: Coding guidelines

Comment on lines +196 to +204
async function openInChatGPT() {
const message = encodeURIComponent(await getLlmPrompt());
openChat(`https://chatgpt.com/?q=${message}`);
}

async function openInClaude() {
const message = encodeURIComponent(await getLlmPrompt());
openChat(`https://claude.ai/new?q=${message}`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Do modern browsers block window.open() if it is called after awaiting asynchronous work inside a click handler due loss of transient user activation?

💡 Result:

Modern browsers generally block window.open when it is called after an asynchronous operation (e.g., an await in a promise) because the transient user activation required for the operation may expire or be consumed [1][2][3]. Transient activation is a temporary state granted by the browser upon meaningful user interaction (like a click) that allows protected features—such as opening popups—to function [4][5]. This state has a short expiration timer (typically around one second) [2][3]. While some browsers may permit window.open if the call occurs within that short window, relying on asynchronous code introduces a risk of failure because the browser may treat the operation as no longer directly tied to the original user gesture [1][6][7][8]. To ensure consistent behavior across all browsers, the recommended technical approach is to call window.open synchronously within the initial event handler to obtain a window reference immediately [1][6]. You can then perform your asynchronous work and subsequently update the already-opened window (for example, by setting its location) once the data is ready [1][8]. Example of the recommended pattern: function handleButtonClick { // Open the window synchronously to secure the transient activation const newWindow = window.open('about:blank', '_blank'); if (newWindow) { // Perform asynchronous work fetch('/api/target-url').then(response => response.json).then(data => { // Navigate the already-opened window newWindow.location.href = data.url; }).catch( => { newWindow.close; }); } }

Citations:


🏁 Script executed:

cat -n docs/ensnode.io/src/components/molecules/PageActions.astro | head -250 | tail -100

Repository: namehash/ensnode

Length of output: 3605


🏁 Script executed:

cat -n docs/ensnode.io/src/components/molecules/PageActions.astro | sed -n '240,350p'

Repository: namehash/ensnode

Length of output: 3580


Open-in-chat actions can be popup-blocked due to async gap before window.open.

The openInChatGPT and openInClaude functions await getLlmPrompt() before calling openChat(). Since these handlers are invoked from a click event listener (line 271) and the async chain includes a fetch operation, the browser may lose transient user activation before window.open() executes, causing the popup to be blocked.

Suggested change
 async function openInChatGPT() {
-  const message = encodeURIComponent(await getLlmPrompt());
-  openChat(`https://chatgpt.com/?q=${message}`);
+  const popup = window.open("about:blank", "_blank", "noopener,noreferrer");
+  if (!popup) throw new Error("Popup blocked");
+  try {
+    const message = encodeURIComponent(await getLlmPrompt());
+    popup.location.replace(`https://chatgpt.com/?q=${message}`);
+  } catch (error) {
+    popup.close();
+    throw error;
+  }
 }
 
 async function openInClaude() {
-  const message = encodeURIComponent(await getLlmPrompt());
-  openChat(`https://claude.ai/new?q=${message}`);
+  const popup = window.open("about:blank", "_blank", "noopener,noreferrer");
+  if (!popup) throw new Error("Popup blocked");
+  try {
+    const message = encodeURIComponent(await getLlmPrompt());
+    popup.location.replace(`https://claude.ai/new?q=${message}`);
+  } catch (error) {
+    popup.close();
+    throw error;
+  }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function openInChatGPT() {
const message = encodeURIComponent(await getLlmPrompt());
openChat(`https://chatgpt.com/?q=${message}`);
}
async function openInClaude() {
const message = encodeURIComponent(await getLlmPrompt());
openChat(`https://claude.ai/new?q=${message}`);
}
async function openInChatGPT() {
const popup = window.open("about:blank", "_blank", "noopener,noreferrer");
if (!popup) throw new Error("Popup blocked");
try {
const message = encodeURIComponent(await getLlmPrompt());
popup.location.replace(`https://chatgpt.com/?q=${message}`);
} catch (error) {
popup.close();
throw error;
}
}
async function openInClaude() {
const popup = window.open("about:blank", "_blank", "noopener,noreferrer");
if (!popup) throw new Error("Popup blocked");
try {
const message = encodeURIComponent(await getLlmPrompt());
popup.location.replace(`https://claude.ai/new?q=${message}`);
} catch (error) {
popup.close();
throw error;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/components/molecules/PageActions.astro` around lines 196
- 204, The openInChatGPT and openInClaude functions are experiencing popup
blocking because they await the getLlmPrompt() async operation before calling
openChat, creating an async gap that causes the browser to lose transient user
activation needed for window.open to succeed. Move the openChat() call outside
of the async chain to execute synchronously on the user click event, then fetch
the prompt asynchronously afterward. You can either call openChat with a
temporary placeholder message immediately and update it after the prompt loads,
or refactor to open the window first synchronously and then update its
location/content once getLlmPrompt completes.

---
import Default from "@astrojs/starlight/components/TableOfContents.astro";

import PageActions from "../molecules/PageActions.astro";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Switch the new PageActions import to @components alias.

The added import on Line 4 should follow the docs-site alias policy for src Astro files.

Suggested change
-import PageActions from "../molecules/PageActions.astro";
+import PageActions from "`@components/molecules/PageActions.astro`";

As per coding guidelines: docs/ensnode.io/{config,scripts,src}/**/*.{ts,tsx,astro} must use path aliases (@components, @content, @data, @lib, @scripts, @styles, @assets, @workspace).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import PageActions from "../molecules/PageActions.astro";
import PageActions from "`@components/molecules/PageActions.astro`";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/components/overrides/TableOfContents.astro` at line 4,
The import statement for PageActions on line 4 is using a relative path instead
of following the project's path alias policy for src files. Replace the relative
path `"../molecules/PageActions.astro"` in the PageActions import with the
`@components` path alias to comply with the docs-site coding guidelines that
require all imports in src Astro files to use established path aliases.

Source: Coding guidelines

Comment on lines +52 to +53
Pinning to the matching `v${snapshot.sdkVersion}` tag keeps your installed skills aligned with this docs/API version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inline version token is rendered literally instead of interpolated.

v${snapshot.sdkVersion} inside markdown backticks will display as plain text, so readers won’t see the actual pinned version tag.

Suggested fix
-Pinning to the matching `v${snapshot.sdkVersion}` tag keeps your installed skills aligned with this docs/API version.
+Pinning to the matching <code>{`v${snapshot.sdkVersion}`}</code> tag keeps your installed skills aligned with this docs/API version.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Pinning to the matching `v${snapshot.sdkVersion}` tag keeps your installed skills aligned with this docs/API version.
Pinning to the matching <code>{`v${snapshot.sdkVersion}`}</code> tag keeps your installed skills aligned with this docs/API version.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx` around lines 52 -
53, The version token `v${snapshot.sdkVersion}` is wrapped in markdown backticks
which prevents it from being interpolated and causes it to display as literal
text instead of the actual version number. Remove the backticks surrounding the
`v${snapshot.sdkVersion}` token in the sentence about pinning to the matching
version tag so that the variable can be properly interpolated and display the
actual SDK version to readers.


const markdown = await response.text();
await navigator.clipboard.writeText(markdown);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"Ask in ChatGPT"/"Ask in Claude" call window.open() only after awaiting an async HEAD-probe, so the click's transient user activation is gone and the new tab is blocked by popup blockers.

Fix on Vercel

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/ensnode.io/src/components/molecules/PageActionsMenu.astro (1)

144-181: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix cross-page URL cache bleed in resolveMarkdownUrl.

resolvedMarkdownUrl is module-global. After the first resolve, subsequent calls (including after astro:page-load) can reuse a stale URL from a different page/root, so copy/open actions target the wrong markdown source.

Suggested fix
-  let resolvedMarkdownUrl;
+  const resolvedMarkdownUrlByRoot = new WeakMap();

   async function resolveMarkdownUrl(root) {
-    if (resolvedMarkdownUrl) {
-      return resolvedMarkdownUrl;
+    const cached = resolvedMarkdownUrlByRoot.get(root);
+    if (cached) {
+      return cached;
     }
@@
       if (probeResponse.ok || probeResponse.status === 405) {
-        resolvedMarkdownUrl = routeMarkdownUrl;
-        return resolvedMarkdownUrl;
+        resolvedMarkdownUrlByRoot.set(root, routeMarkdownUrl);
+        return routeMarkdownUrl;
       }
@@
     const sourceMarkdownUrl = getSourceMarkdownUrl(root);
     if (sourceMarkdownUrl) {
-      resolvedMarkdownUrl = sourceMarkdownUrl;
-      return resolvedMarkdownUrl;
+      resolvedMarkdownUrlByRoot.set(root, sourceMarkdownUrl);
+      return sourceMarkdownUrl;
     }

-    resolvedMarkdownUrl = routeMarkdownUrl;
-    return resolvedMarkdownUrl;
+    resolvedMarkdownUrlByRoot.set(root, routeMarkdownUrl);
+    return routeMarkdownUrl;
   }

Also applies to: 376-391

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/components/molecules/PageActionsMenu.astro` around lines
144 - 181, The `resolvedMarkdownUrl` variable is module-global, causing it to
cache the markdown URL from one page and reuse it incorrectly on subsequent
pages after navigation. Instead of storing the resolved URL at module scope in
the `resolveMarkdownUrl` function, use the existing `feedbackHideTimers` WeakMap
pattern to cache the resolved URL keyed by the root element. This way, each root
element maintains its own resolved URL cache, and stale URLs from previous pages
will not bleed into current page operations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/ensnode.io/src/components/molecules/PageActionsMenu.astro`:
- Around line 2-8: The import statements for icons (ChevronDownIcon, ClaudeIcon,
CopyIcon, FileTextIcon, LinkIcon, MarkdownIcon, SparklesIcon) are using relative
paths with `../atoms/icons/` instead of the configured `@components` path alias.
Replace all these relative imports with the `@components` alias to comply with
the docs-site coding guidelines for Astro files in the `src` directory. For
example, change `import { ChevronDownIcon } from
"../atoms/icons/ChevronDownIcon"` to use
`@components/atoms/icons/ChevronDownIcon` instead.

---

Outside diff comments:
In `@docs/ensnode.io/src/components/molecules/PageActionsMenu.astro`:
- Around line 144-181: The `resolvedMarkdownUrl` variable is module-global,
causing it to cache the markdown URL from one page and reuse it incorrectly on
subsequent pages after navigation. Instead of storing the resolved URL at module
scope in the `resolveMarkdownUrl` function, use the existing
`feedbackHideTimers` WeakMap pattern to cache the resolved URL keyed by the root
element. This way, each root element maintains its own resolved URL cache, and
stale URLs from previous pages will not bleed into current page operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dd6dc510-c61c-4fb3-bdf4-86a794b902d5

📥 Commits

Reviewing files that changed from the base of the PR and between 0d720c6 and e141152.

📒 Files selected for processing (7)
  • docs/ensnode.io/src/components/atoms/icons/ChevronDownIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/CopyIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/FileTextIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/LinkIcon.tsx
  • docs/ensnode.io/src/components/atoms/icons/SparklesIcon.tsx
  • docs/ensnode.io/src/components/molecules/PageActionsMenu.astro
  • docs/ensnode.io/src/components/overrides/TableOfContents.astro

Comment on lines +2 to +8
import { ChevronDownIcon } from "../atoms/icons/ChevronDownIcon";
import { ClaudeIcon } from "../atoms/icons/ClaudeIcon";
import { CopyIcon } from "../atoms/icons/CopyIcon";
import { FileTextIcon } from "../atoms/icons/FileTextIcon";
import { LinkIcon } from "../atoms/icons/LinkIcon";
import { MarkdownIcon } from "../atoms/icons/MarkdownIcon";
import { SparklesIcon } from "../atoms/icons/SparklesIcon";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use configured @components aliases instead of relative imports.

Line 2–8 imports violate the docs-site alias policy for src Astro files.

Suggested fix
-import { ChevronDownIcon } from "../atoms/icons/ChevronDownIcon";
-import { ClaudeIcon } from "../atoms/icons/ClaudeIcon";
-import { CopyIcon } from "../atoms/icons/CopyIcon";
-import { FileTextIcon } from "../atoms/icons/FileTextIcon";
-import { LinkIcon } from "../atoms/icons/LinkIcon";
-import { MarkdownIcon } from "../atoms/icons/MarkdownIcon";
-import { SparklesIcon } from "../atoms/icons/SparklesIcon";
+import { ChevronDownIcon } from "`@components/atoms/icons/ChevronDownIcon`";
+import { ClaudeIcon } from "`@components/atoms/icons/ClaudeIcon`";
+import { CopyIcon } from "`@components/atoms/icons/CopyIcon`";
+import { FileTextIcon } from "`@components/atoms/icons/FileTextIcon`";
+import { LinkIcon } from "`@components/atoms/icons/LinkIcon`";
+import { MarkdownIcon } from "`@components/atoms/icons/MarkdownIcon`";
+import { SparklesIcon } from "`@components/atoms/icons/SparklesIcon`";

As per coding guidelines, docs/ensnode.io/{config,scripts,src}/**/*.{ts,tsx,astro} must use @components/other configured path aliases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ensnode.io/src/components/molecules/PageActionsMenu.astro` around lines
2 - 8, The import statements for icons (ChevronDownIcon, ClaudeIcon, CopyIcon,
FileTextIcon, LinkIcon, MarkdownIcon, SparklesIcon) are using relative paths
with `../atoms/icons/` instead of the configured `@components` path alias.
Replace all these relative imports with the `@components` alias to comply with
the docs-site coding guidelines for Astro files in the `src` directory. For
example, change `import { ChevronDownIcon } from
"../atoms/icons/ChevronDownIcon"` to use
`@components/atoms/icons/ChevronDownIcon` instead.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants