Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f2e93ff
feat: add meta generation script and components metadata
Jul 8, 2026
9f4a7e8
feat: add LLMs documentation generation and Vite plugin
alvinhui Jul 8, 2026
fbf8f8c
fix: correct syntax errors in component metadata JSON
alvinhui Jul 8, 2026
debb24c
feat: add English summary for NutUI React documentation
alvinhui Jul 8, 2026
f34eda8
fix: update URL handling in build-llms script
alvinhui Jul 8, 2026
f1d61be
feat: add semantic documentation generation for components
alvinhui Jul 9, 2026
3428c62
chore: update .gitignore and package.json for meta generation
alvinhui Jul 9, 2026
4331871
feat: enhance LLMs documentation generation for multiple platforms
alvinhui Jul 9, 2026
2d23b7a
Merge branch 'feat/ai-coding' into feat/ai-coding-semantic
alvinhui Jul 9, 2026
198d772
feat: add AI documentation support for NutUI-React and Taro
alvinhui Jul 10, 2026
b80f08c
Merge branch 'feat_v4.x' into feat/ai-coding-site
alvinhui Jul 10, 2026
530ef3c
fix: correct formatting and punctuation in LLMs documentation for AI …
alvinhui Jul 10, 2026
672494e
fix: convert paths to POSIX format in Sass @import to support Windows
alvinhui Jul 10, 2026
e79593e
feat: add @nutui/nutui-react-cli package for AI coding support
alvinhui Jul 15, 2026
8b62e21
feat: implement MCP service in nutui-react-cli for IDE integration
alvinhui Jul 15, 2026
04442b6
feat: add skills support and documentation for NutUI React CLI
alvinhui Jul 15, 2026
b4b1583
Merge branch 'feat_v4.x' into feat/ai-coding-cli
alvinhui Jul 15, 2026
14ed61c
feat: update paths and add navigation for 'For Agents' in NutUI-React…
alvinhui Jul 16, 2026
57f7748
feat: harden readDemo path checks and fix nutui_doc lang fallback
alvinhui Jul 16, 2026
762fc2a
fix: add -y flag to npx commands in README for improved usability
alvinhui Jul 16, 2026
81c548e
chore: update version to 0.1.0 in package.json for @nutui/nutui-react…
alvinhui Jul 16, 2026
dc92d26
feat: enhance prepare-data script to auto-regenerate meta
alvinhui Jul 16, 2026
d374fea
docs: add installation instruction for @nutui/nutui-react-cli in 'For…
alvinhui Jul 16, 2026
f39d609
docs: update links to @nutui/nutui-react-cli in CLI documentation for…
alvinhui Jul 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/nutui-react-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
data
.DS_Store
*.log
124 changes: 124 additions & 0 deletions packages/nutui-react-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# @nutui/nutui-react-cli

面向 AI Coding 的 **NutUI React 离线知识查询 CLI**。把组件的 Props、文档、示例、Design Token 打包随包分发,让 AI 编程助手(Claude Code / Cursor / Copilot 等)从「猜 API」变成「查 API」,从根源消除 API 幻觉。

## 特点

- **完全离线、零 API Key**:组件元数据与文档/示例在构建期打包进入,安装后本地毫秒级查询。
- **结构化输出**:所有命令支持 `--format json`,供 Agent 直接解析,而非正则抓文本。
- **拼写纠错**:组件名大小写不敏感,未命中时给出「你是否想找」建议。

## 使用

免安装(推荐):

```bash
npx -y @nutui/nutui-react-cli list
npx -y @nutui/nutui-react-cli info Button
```

或全局安装后用 `nutui-react` 命令:

```bash
npm i -g @nutui/nutui-react-cli
nutui-react info Button --format json
```

## 命令

| 命令 | 说明 |
| --- | --- |
| `nutui-react list [--category <enName>]` | 按分类列出全部组件(名称 / 中文名 / 版本) |
| `nutui-react info <Component>` | 查看组件 Props 表(属性 / 说明 / 类型 / 默认值) |
| `nutui-react doc <Component> [--lang zh\|en]` | 查看组件完整文档,默认中文 |
| `nutui-react demo <Component> [name]` | 省略 `name` 列出全部示例;指定 `name`(如 `demo1`)输出源码 |
| `nutui-react token [Component]` | 查看 Design Token;省略组件名则列出全局 token |
| `nutui-react mcp` | 启动本地 MCP 服务(stdio),供 Claude Code / Cursor / VS Code / Codex 等 IDE 调用 |

全局选项:`--format, -f <text\|json>`(默认 `text`)、`--help, -h`、`--version, -v`。

示例:

```bash
nutui-react list --category feedback
nutui-react info Button --format json
nutui-react doc Button --lang en
nutui-react demo Button # 列出示例
nutui-react demo Button demo1 # 查看某个示例源码
nutui-react token Button
```

## MCP(IDE 集成)

CLI 是「Agent 主动敲命令」,MCP 则把同一份能力注册成 IDE 原生工具,让 Claude Code / Cursor / VS Code / Codex 在对话中**按需自动调用**,无需拼命令行字符串。二者复用同一份离线 meta 快照,等于给同一个知识库套了两种调用协议。

`nutui-react mcp` 启动一个 stdio MCP 服务,暴露 5 个只读工具与 2 个提示词:

| 工具 | 说明 |
| --- | --- |
| `nutui_list` | 列出全部组件(可按分类筛选) |
| `nutui_info` | 组件 Props 规格 |
| `nutui_doc` | 组件完整文档(`lang: zh\|en`) |
| `nutui_demo` | H5 示例列表 / 源码 |
| `nutui_token` | Design Token(全局 / 组件级) |

| 提示词 | 说明 |
| --- | --- |
| `nutui-expert` | 把 Agent 定位为 NutUI React 专家(先查后写) |
| `nutui-page-generator` | 基于组件生成完整可运行页面 |

### 客户端配置

**Claude Code**(`.mcp.json` 或 `claude mcp add`)、**Cursor**(`.cursor/mcp.json`)、**VS Code**(`.vscode/mcp.json` 的 `servers` 字段)通用配置:

```json
{
"mcpServers": {
"nutui-react": {
"command": "npx",
"args": ["-y", "@nutui/nutui-react-cli", "mcp"]
}
}
}
```

**Codex**(`~/.codex/config.toml`):

```toml
[mcp_servers.nutui-react]
command = "npx"
args = ["-y", "@nutui/nutui-react-cli", "mcp"]
```

> `npx -y` 免全局安装即可拉起;也可全局安装后把 `command` 换成 `nutui-react`、`args` 换成 `["mcp"]`。

## CLI 内 Skill(教 Agent 何时用)

CLI 内置一份 [Skill 文件](./skills/nutui-react/SKILL.md)(遵循 Anthropic Agent Skills 规范),随 npm 包一起分发。CLI / MCP 提供的是「能力」,Skill 则约束 Agent「**什么时候、按什么顺序**」用这些能力——例如「写组件前先 `nutui-react info` 查 Props、再 `nutui-react demo` 拿示例」「定制样式用 `var(--nutui-*)` token 而非硬编码颜色」。

安装(skill 已随包 bundle,装好 CLI 后从本地路径装进当前项目):

```bash
npm i -D @nutui/nutui-react-cli
npx skills add ./node_modules/@nutui/nutui-react-cli/skills/nutui-react
```

兼容 Claude Code / Cursor / VS Code / Codex 等所有支持 [skills](https://github.com/vercel-labs/skills) 协议的 Agent。安装后,Agent 在遇到 NutUI React 相关任务时会自动遵循「先查后写」的流程。

## 本地开发

```bash
# 本包:构建(build 会先自动 generate:meta 再 prepare-data + tsup)
pnpm --dir packages/nutui-react-cli build
# 本地试跑
node packages/nutui-react-cli/dist/cli.js list
```

## 发布

```bash
# 发布 beta(bumpp 选版本 -> prepublishOnly 跑 build -> pnpm publish --tag beta)
pnpm --dir packages/nutui-react-cli release:beta
# 或发布正式版
pnpm --dir packages/nutui-react-cli release
```
55 changes: 55 additions & 0 deletions packages/nutui-react-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "@nutui/nutui-react-cli",
"version": "0.1.0",
"type": "module",
"description": "NutUI React 面向 AI Coding 的离线知识查询 CLI:list / info / doc / demo / token。",
"keywords": [
"nutui",
"nutui-react",
"cli",
"ai-coding",
"llm",
"react component"
],
"license": "MIT",
"author": "jdcfe",
"homepage": "https://github.com/jdf2e/nutui-react.git",
"repository": {
"type": "git",
"url": "https://github.com/jdf2e/nutui-react.git"
},
"bin": {
"nutui-react": "./dist/cli.js"
},
"files": [
"dist",
"data",
"skills"
],
"engines": {
"node": ">=18.12.0"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"prepare-data": "node scripts/prepare-data.mjs",
"build": "node scripts/prepare-data.mjs && tsup",
"dev": "tsup --watch",
"typecheck": "tsc --noEmit",
"prepublishOnly": "pnpm run build",
"release": "bumpp && pnpm publish",
"release:beta": "bumpp --preid beta && pnpm publish --tag beta"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.29.0",
"yargs": "^17.7.2"
},
"devDependencies": {
"@types/node": "^22.5.5",
"@types/yargs": "^17.0.33",
"bumpp": "^9.5.2",
"tsup": "^8.3.0",
"typescript": "^5.6.2"
}
}
114 changes: 114 additions & 0 deletions packages/nutui-react-cli/scripts/prepare-data.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// 读仓库根 meta/components.json,为 @nutui/nutui-react-cli 产出自包含的 data/ 快照。
// 仅 React(H5)端:docs 取 h5(中文)/enUS(英文),demos 取 h5。忽略 zhTW / taro 维度。
// 让发布后的 CLI 无需依赖仓库源码即可离线运行 doc / demo 命令。
// 会先自动重生成 meta(generate:meta),无需手动同步。
// DO NOT manual edit the output (data/). Run: pnpm run prepare-data
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { execFileSync } from 'node:child_process'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const PKG_DIR = path.resolve(__dirname, '..')
// 仓库根:packages/nutui-react-cli/scripts -> ../../..
const REPO_ROOT = path.resolve(PKG_DIR, '..', '..')
const META_PATH = path.join(REPO_ROOT, 'meta/components.json')
const BUILD_META_SCRIPT = path.join(REPO_ROOT, 'scripts/build-meta.mjs')
const DATA_DIR = path.join(PKG_DIR, 'data')

// meta.docs 的 key -> CLI 语言维度。仅保留 React/H5 端用到的两种。
const DOC_KEYS = ['h5', 'enUS']

// 先重生成 meta 再读,确保快照与仓库源码(config/properties/demos/...)同步,
// 免去手动 generate:meta 的漏同步风险。build-meta 纯读源码且幂等,可安全重复执行。
function regenerateMeta() {
if (!fs.existsSync(BUILD_META_SCRIPT)) {
// 脱离 monorepo(如已发布包被重新 build),无源码可生成,沿用现有快照。
console.log('ℹ️ 未找到 build-meta 脚本,跳过 meta 重生成(沿用现有快照)')
return
}
console.log('🔄 重新生成 meta/components.json(generate:meta)...')
execFileSync(process.execPath, [BUILD_META_SCRIPT], { stdio: 'inherit' })
}

function readMeta() {
try {
regenerateMeta()
} catch (err) {
// meta 生成失败:有旧快照则告警后沿用,否则无从继续。
if (fs.existsSync(META_PATH)) {
console.warn(
`⚠️ meta 重生成失败(${err.message}),沿用现有 ${path.relative(REPO_ROOT, META_PATH)}`
)
} else {
console.error(
`❌ meta 重生成失败且无现有快照:${err.message}\n` +
` 请在仓库根手动执行:npm run generate:meta`
)
process.exit(1)
}
}
if (!fs.existsSync(META_PATH)) {
console.error(
`❌ 未找到 ${path.relative(REPO_ROOT, META_PATH)}。\n` +
` 它是构建产物,请先在仓库根执行:npm run generate:meta`
)
process.exit(1)
}
return JSON.parse(fs.readFileSync(META_PATH, 'utf-8'))
}

// meta 里的路径始终是 posix 相对仓库根路径,用 posix 取 basename,再 join 到本地。
function copyRepoFile(relPosixPath, destAbs) {
const srcAbs = path.join(REPO_ROOT, relPosixPath)
if (!fs.existsSync(srcAbs)) return false
fs.mkdirSync(path.dirname(destAbs), { recursive: true })
fs.copyFileSync(srcAbs, destAbs)
return true
}

function main() {
console.log('🚀 building @nutui/nutui-react-cli data snapshot (React/H5) ...')
const meta = readMeta()

// 全量重建,避免残留上一版删掉的组件。
fs.rmSync(DATA_DIR, { recursive: true, force: true })
fs.mkdirSync(DATA_DIR, { recursive: true })

// 1. meta.json 逐字复制。
fs.copyFileSync(META_PATH, path.join(DATA_DIR, 'meta.json'))

let docCount = 0
let demoCount = 0
const missing = []

for (const c of Object.values(meta.components)) {
// 2. docs:仅 h5 / enUS 的非 null 路径。
for (const key of DOC_KEYS) {
const rel = c.docs && c.docs[key]
if (!rel) continue
const ok = copyRepoFile(rel, path.join(DATA_DIR, 'docs', c.id, `${key}.md`))
if (ok) docCount++
else missing.push(rel)
}

// 3. demos:仅 H5,扁平放到 data/demos/<id>/<basename>.tsx(无 platform 子层)。
const h5Demos = (c.demos && c.demos.h5) || []
for (const rel of h5Demos) {
const base = path.posix.basename(rel)
const ok = copyRepoFile(rel, path.join(DATA_DIR, 'demos', c.id, base))
if (ok) demoCount++
else missing.push(rel)
}
}

console.log(`✅ 写入 ${path.relative(PKG_DIR, DATA_DIR)}/`)
console.log(` meta.json + docs ${docCount} 份 + demos ${demoCount} 份`)
if (missing.length) {
console.log(`\n⚠️ ${missing.length} 个 meta 引用的文件在仓库中缺失(已跳过):`)
for (const m of missing.slice(0, 20)) console.log(` - ${m}`)
if (missing.length > 20) console.log(` … 其余 ${missing.length - 20} 条省略`)
}
}

main()
1 change: 1 addition & 0 deletions packages/nutui-react-cli/skills/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/node_modules
Loading
Loading