feature: MCP Server + Skill #3497
Conversation
- Introduced a new script `build-meta.mjs` to aggregate component metadata from various sources. - Added a new command `generate:meta` in `package.json` to run the metadata generation. - Created `meta/components.json` to store the generated component metadata, including categories and global tokens.
- Replaced direct comparison of import.meta.url with pathToFileURL for improved URL handling.
# Conflicts: # .gitignore # scripts/build-llms.mjs # scripts/site/vite-plugin-llms.mjs
Co-Authored-By: Claude <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough新增 ChangesNutUI React 离线 CLI 与 MCP
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant Agent
participant NutUIReactCLI
participant OfflineData
Agent->>NutUIReactCLI: request component information
NutUIReactCLI->>OfflineData: read metadata, docs, demos, or tokens
OfflineData-->>NutUIReactCLI: return structured data
NutUIReactCLI-->>Agent: return JSON or MCP response
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat_v4.x #3497 +/- ##
=============================================
+ Coverage 88.33% 88.44% +0.11%
=============================================
Files 295 296 +1
Lines 19747 19812 +65
Branches 3117 3135 +18
=============================================
+ Hits 17443 17523 +80
+ Misses 2298 2283 -15
Partials 6 6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
src/sites/sites-react/doc-taro/router.ts (1)
51-51: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value转义正则表达式中的点号并增加对正则执行结果的安全校验。
正则表达式中的
.会匹配任意字符,为了保证提取文件名的语义绝对准确,应将其转义为\.。同时,exec()可能会在未匹配时返回null,直接断言为any[]并强行读取下标[1]存在引发运行时TypeError的风险,建议改用可选链语法进行安全访问。
src/sites/sites-react/doc-taro/router.ts#L51-L51: 建议修改为let name = (/docs\/ai-taro\/(.*?)\.md$/.exec(path))?.[1] || '';src/sites/sites-react/doc-taro/router.ts#L60-L60: 建议修改为let name = (/docs\/ai-taro\/(.*?)\.en-US\.md$/.exec(path))?.[1] || '';src/sites/sites-react/doc/router.ts#L74-L74: 建议修改为let name = (/docs\/ai-react\/(.*?)\.md$/.exec(path))?.[1] || '';src/sites/sites-react/doc/router.ts#L83-L83: 建议修改为let name = (/docs\/ai-react\/(.*?)\.en-US\.md$/.exec(path))?.[1] || '';🤖 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 `@src/sites/sites-react/doc-taro/router.ts` at line 51, Update the filename extraction expressions in src/sites/sites-react/doc-taro/router.ts lines 51-51 and 60-60, and src/sites/sites-react/doc/router.ts lines 74-74 and 83-83: escape literal dots, require the expected .md or .en-US.md suffix with an end anchor, and safely access the match via optional chaining with an empty-string fallback when exec() returns null.packages/nutui-react-cli/src/cli.ts (1)
11-124: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value建议使用
.parseAsync()替代.parse()更好地处理异步命令由于
mcp命令的回调runMcp是一个异步函数,目前使用.parse()会导致 Promise 处于浮动(floating)状态(也是此处禁用 eslint 规则的原因)。建议改用.parseAsync()来确保顶层异步错误(例如 MCP 服务连接失败)能被 yargs 捕获或链式.catch()正确处理,而不会引发unhandledRejection。♻️ 建议的重构
如果你使用的是 ESM 且支持顶层 await:
-// eslint-disable-next-line `@typescript-eslint/no-floating-promises` -yargs(hideBin(process.argv)) +await yargs(hideBin(process.argv)) .scriptName('nutui-react') // ... 中间命令保持不变 ... .wrap(null) - .parse() + .parseAsync()或者使用链式调用捕获:
-// eslint-disable-next-line `@typescript-eslint/no-floating-promises` yargs(hideBin(process.argv)) .scriptName('nutui-react') // ... 中间命令保持不变 ... .wrap(null) - .parse() + .parseAsync() + .catch((err) => { + console.error(err); + process.exit(1); + })🤖 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 `@packages/nutui-react-cli/src/cli.ts` around lines 11 - 124, Update the yargs invocation to use parseAsync instead of parse, and handle the returned Promise with appropriate top-level rejection handling so asynchronous failures from runMcp and other command callbacks do not become unhandled rejections. Remove the now-unnecessary no-floating-promises suppression while preserving the existing command configuration.packages/nutui-react-cli/package.json (1)
43-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win将运行时依赖移至
devDependencies以实现真正的零依赖安装。在配套的
tsup.config.ts文件中,已经通过noExternal配置将yargs和@modelcontextprotocol/sdk打包进了最终的产物。但如果它们依然留在dependencies字段中,用户在通过npm install或npx获取 CLI 时,NPM 仍会解析并下载这些包。建议将它们移至devDependencies,从而真正实现产物的自包含与“零依赖安装”,提升终端用户的下载与执行速度。♻️ 建议的修改
- "dependencies": { - "`@modelcontextprotocol/sdk`": "^1.29.0", - "yargs": "^17.7.2" - }, "devDependencies": { + "`@modelcontextprotocol/sdk`": "^1.29.0", + "yargs": "^17.7.2", "`@types/node`": "^22.5.5",🤖 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 `@packages/nutui-react-cli/package.json` around lines 43 - 46, 将 package.json 中的 yargs 和 `@modelcontextprotocol/sdk` 从 dependencies 移至 devDependencies,保持 tsup.config.ts 的 noExternal 打包配置不变,确保 CLI 产物自包含且安装时不再解析这些运行时依赖。packages/nutui-react-cli/src/format.ts (1)
17-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value确保行内列数与表头一致,防止表格错位。
当前的
line函数是通过遍历cells来生成列。如果某一行的数据(cells数组)长度小于表头(headers)长度,这一行就会缺少最后几列,导致排版错乱。建议遍历widths来生成每一列,确保每一行都能被正确补充到预期的列数。♻️ 建议的重构
- const line = (cells: string[]) => - cells.map((c, i) => pad(c ?? '', widths[i])).join(' ') + const line = (cells: string[]) => + widths.map((w, i) => pad(cells[i] ?? '', w)).join(' ')🤖 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 `@packages/nutui-react-cli/src/format.ts` around lines 17 - 18, Update the line function to iterate over widths rather than cells, using each width index to read the corresponding cell and pad missing values with an empty string. Preserve the existing spacing and joining behavior so every row matches the header column count.
🤖 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 `@packages/nutui-react-cli/src/data.ts`:
- Around line 88-93: Update readDemo to validate name before constructing the
file path, rejecting path traversal components and any characters outside the
allowed demo-name format; return null for invalid names. Preserve support for
the optional .tsx suffix while ensuring the resolved path remains within the
component’s demos directory.
In `@packages/nutui-react-cli/src/mcp/tools.ts`:
- Around line 199-203: Update the lang selection in the nutui_doc case to
preserve any explicitly provided params.lang value, including 'zh', and only
fall back to ctx.lang when params.lang is nullish or absent. Keep the existing
readDoc(comp, lang) flow unchanged.
---
Nitpick comments:
In `@packages/nutui-react-cli/package.json`:
- Around line 43-46: 将 package.json 中的 yargs 和 `@modelcontextprotocol/sdk` 从
dependencies 移至 devDependencies,保持 tsup.config.ts 的 noExternal 打包配置不变,确保 CLI
产物自包含且安装时不再解析这些运行时依赖。
In `@packages/nutui-react-cli/src/cli.ts`:
- Around line 11-124: Update the yargs invocation to use parseAsync instead of
parse, and handle the returned Promise with appropriate top-level rejection
handling so asynchronous failures from runMcp and other command callbacks do not
become unhandled rejections. Remove the now-unnecessary no-floating-promises
suppression while preserving the existing command configuration.
In `@packages/nutui-react-cli/src/format.ts`:
- Around line 17-18: Update the line function to iterate over widths rather than
cells, using each width index to read the corresponding cell and pad missing
values with an empty string. Preserve the existing spacing and joining behavior
so every row matches the header column count.
In `@src/sites/sites-react/doc-taro/router.ts`:
- Line 51: Update the filename extraction expressions in
src/sites/sites-react/doc-taro/router.ts lines 51-51 and 60-60, and
src/sites/sites-react/doc/router.ts lines 74-74 and 83-83: escape literal dots,
require the expected .md or .en-US.md suffix with an end anchor, and safely
access the match via optional chaining with an empty-string fallback when exec()
returns null.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e1f3da90-af2f-4b65-8e7f-e9612381d399
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (37)
.gitignorepackage.jsonpackages/nutui-react-cli/.gitignorepackages/nutui-react-cli/README.mdpackages/nutui-react-cli/package.jsonpackages/nutui-react-cli/scripts/prepare-data.mjspackages/nutui-react-cli/src/cli.tspackages/nutui-react-cli/src/commands/_shared.tspackages/nutui-react-cli/src/commands/demo.tspackages/nutui-react-cli/src/commands/doc.tspackages/nutui-react-cli/src/commands/info.tspackages/nutui-react-cli/src/commands/list.tspackages/nutui-react-cli/src/commands/mcp.tspackages/nutui-react-cli/src/commands/token.tspackages/nutui-react-cli/src/data.tspackages/nutui-react-cli/src/error.tspackages/nutui-react-cli/src/format.tspackages/nutui-react-cli/src/mcp/prompts.tspackages/nutui-react-cli/src/mcp/tools.tspackages/nutui-react-cli/src/types.tspackages/nutui-react-cli/tsconfig.jsonpackages/nutui-react-cli/tsup.config.tspnpm-workspace.yamlscripts/build-llms.mjsscripts/build-semantic.mjsscripts/site/vite-plugin-llms.mjssrc/sites/config/baseConfig.tssrc/sites/sites-react/doc-taro/App.tsxsrc/sites/sites-react/doc-taro/router.tssrc/sites/sites-react/doc/App.tsxsrc/sites/sites-react/doc/components/header/header.tsxsrc/sites/sites-react/doc/components/nav/nav.tsxsrc/sites/sites-react/doc/docs/ai-react/llms.en-US.mdsrc/sites/sites-react/doc/docs/ai-react/llms.mdsrc/sites/sites-react/doc/docs/ai-taro/llms.en-US.mdsrc/sites/sites-react/doc/docs/ai-taro/llms.mdsrc/sites/sites-react/doc/router.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@packages/nutui-react-cli/skills/nutui-react/SKILL.md`:
- Around line 21-30: 统一固定所有 npx 示例的精确版本,避免在未本地安装时拉取远程最新包;更新
packages/nutui-react-cli/skills/nutui-react/SKILL.md 第21-30行、第97-103行,以及
packages/nutui-react-cli/README.md 第102-103行中的命令,同时保持本地 nutui-react 调用方式可用。
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 64fcea5a-6687-4923-9653-f218fc2a4a06
📒 Files selected for processing (4)
packages/nutui-react-cli/README.mdpackages/nutui-react-cli/package.jsonpackages/nutui-react-cli/skills/.npmignorepackages/nutui-react-cli/skills/nutui-react/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/nutui-react-cli/package.json
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/sites/config/baseConfig.ts (2)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value建议同步更新导航项的
name字段以保持语义一致虽然
name字段目前仅在头部渲染时用作 Reactkey,但由于 AI 导航已经扩展包含了for-agents、cli、mcp等页面,继续使用'llms'作为name会有些过时。建议在 PC 和 Taro 两个配置中将其同步更新为'ai'或'for-agents',以保持代码语义的整洁。
src/sites/config/baseConfig.ts#L46-51: 将SiteReact.header中 AI 导航项的name从'llms'改为'ai'。src/sites/config/baseConfig.ts#L100-105: 将SiteReactTaro.header中 AI 导航项的name从'llms'改为'ai'。🤖 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 `@src/sites/config/baseConfig.ts` at line 1, Update the AI navigation item name from “llms” to “ai” in both SiteReact.header and SiteReactTaro.header within the base configuration, keeping the navigation targets and other fields unchanged.
46-51: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value建议同步更新导航项的
name字段以保持语义一致虽然
name字段目前仅在头部渲染时用作 Reactkey,但由于 AI 导航已经扩展包含了for-agents、cli、mcp等页面,继续使用'llms'作为name会有些过时。建议将其更新为'ai'或'for-agents'。💡 建议的修改
- name: 'llms', + name: 'ai', cName: 'AI', eName: 'AI', path: '/zh-CN/ai/for-agents', pathName: 'for-agents'🤖 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 `@src/sites/config/baseConfig.ts` around lines 46 - 51, 更新 baseConfig 中 path 为 /zh-CN/ai/for-agents 的导航项,将过时的 name 值从“llms”改为与 AI 导航语义一致的“ai”或“for-agents”,并保持其他字段不变。
🤖 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.
Nitpick comments:
In `@src/sites/config/baseConfig.ts`:
- Line 1: Update the AI navigation item name from “llms” to “ai” in both
SiteReact.header and SiteReactTaro.header within the base configuration, keeping
the navigation targets and other fields unchanged.
- Around line 46-51: 更新 baseConfig 中 path 为 /zh-CN/ai/for-agents 的导航项,将过时的 name
值从“llms”改为与 AI 导航语义一致的“ai”或“for-agents”,并保持其他字段不变。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 2c5d3562-fa4c-456c-9e29-e6ad4bbcb8b0
📒 Files selected for processing (8)
src/sites/config/baseConfig.tssrc/sites/sites-react/doc/components/nav/nav.tsxsrc/sites/sites-react/doc/docs/ai-react/cli.en-US.mdsrc/sites/sites-react/doc/docs/ai-react/cli.mdsrc/sites/sites-react/doc/docs/ai-react/for-agents.en-US.mdsrc/sites/sites-react/doc/docs/ai-react/for-agents.mdsrc/sites/sites-react/doc/docs/ai-react/mcp.en-US.mdsrc/sites/sites-react/doc/docs/ai-react/mcp.md
Co-authored-by: Cursor <cursoragent@cursor.com>
… Agents' documentation
背景
AI 编程助手(Claude Code / Cursor / Copilot 等)在写 NutUI React 代码时,常凭记忆猜测组件 API,导致 Prop 名、枚举值出现「幻觉」。本 MR
新增一套离线知识查询能力,让 Agent 从「猜 API」变成「查 API」,从根源消除幻觉。
主要改动
1. 新增
@nutui/nutui-react-cli包面向 AI Coding 的离线知识查询 CLI,把组件的 Props、文档、示例、Design Token 在构建期打包随包分发:
--format json,供 Agent 直接解析。list [--category]info <Component>doc <Component> [--lang zh|en]demo <Component> [name]token [Component]2. MCP 服务(IDE 集成)
nutui-react mcp启动本地 stdio MCP 服务,把同一份离线知识注册成 IDE 原生工具,供 Claude Code / Cursor / VS Code / Codex 在对话中按需自动调用,暴露 5个只读工具(
nutui_list/nutui_info/nutui_doc/nutui_demo/nutui_token)与 2 个提示词(nutui-expert/nutui-page-generator)。3. 内置 Skill(约束 Agent 何时用)
内置一份遵循 Anthropic Agent Skills 规范的 Skill 文件随包分发。CLI/MCP 提供「能力」,Skill 则约束 Agent「什么时候、按什么顺序」使用——例如「写组件前先
info查 Props、再
demo拿示例」「定制样式用var(--nutui-*)token 而非硬编码颜色」。4. 文档站点更新
ai-react文档:for-agents/cli/mcp(均含中英文)。llms调整为for-agents,作为面向 Agent 的统一入口。使用方式
测试计划
Summary by CodeRabbit