Nx CLI 工具链设计文档
版本: 1.0.0 创建日期: 2026-01-31 最后更新: 2026-01-31
概述
将 Nx CLI 从一个仅针对 NextUI Framework 项目的内部工具,扩展为一个通用的 .NET 项目工具链,同时提供针对 NextUI Framework 应用的增强功能。
目录
当前状态分析
现有命令分类
| 命令 | 当前状态 | 问题 |
|---|---|---|
doctor |
半通用 | 检查 NextUI 特定的 workloads |
init |
通用 | 可用于任何项目 |
build |
半通用 | 依赖 nx.json 配置 |
run |
通用 | 通过配置驱动 |
watch |
通用 | 通过配置驱动 |
test |
半通用 | 硬编码 tests/ 目录 |
publish |
Framework 专用 | 硬编码 NuGet 服务器 |
new |
Framework 专用 | 仅支持 NextUI 模板 |
package |
Framework 专用 | 仅显示 NextUI 包 |
核心问题
硬编码路径和 URL
- NuGet 服务器:
https://nuget.easyrote.net/ - 测试目录:
tests/ - 解决方案文件:
NextUI.sln
- NuGet 服务器:
缺乏项目类型检测
- 无法区分 Framework 项目 vs 应用项目
- 无法检测项目是否使用 NextUI
缺少代码检查功能
- 无代码质量检查
- 无最佳实践验证
- 无配置验证
扩展目标
支持的项目类型
┌─────────────────────────────────────────────────────────┐
│ Nx CLI 工具链 │
├─────────────────────────────────────────────────────────┤
│ 通用 .NET 项目功能 │
│ - build, run, watch, test, doctor, init, doc │
├─────────────────────────────────────────────────────────┤
│ NextUI Framework 应用功能 │
│ - lint (代码检查) │
│ - check (配置检查) │
│ - upgrade (升级依赖) │
│ - ai (AI 辅助检查) │
├─────────────────────────────────────────────────────────┤
│ NextUI Framework 开发功能 (仅框架项目) │
│ - publish (发布到 NuGet) │
│ - package (包管理) │
└─────────────────────────────────────────────────────────┘
新增命令
1. nx doc - 文档查看
查看项目文档。
nx doc list # 列出所有文档
nx doc view <name> # 查看文档内容 (Markdown)
nx doc html <name> # 在浏览器中查看 (转换为 HTML)
nx doc open <name> # 同 html,打开默认浏览器
功能:
| 子命令 | 说明 |
|---|---|
list |
列出所有 MD 文档,显示名称、标题、摘要 |
view |
在终端中显示 MD 内容(支持语法高亮) |
html |
转换为 HTML 并在浏览器中打开 |
open |
html 的别名 |
文档来源:
docs/目录下所有.md文件README.md- 组件 API 文档
- 设计文档
- Token 文档
实现细节:
public class DocCommand
{
// 扫描文档目录
public IEnumerable<DocInfo> ListDocs()
{
var docs = new List<DocInfo>();
// 1. docs/ 目录
foreach (var file in Directory.GetFiles("docs", "*.md"))
{
docs.Add(ParseDocInfo(file));
}
// 2. README.md
if (File.Exists("README.md"))
docs.Add(ParseDocInfo("README.md"));
return docs;
}
// 解析文档信息(标题、摘要)
private DocInfo ParseDocInfo(string path)
{
var lines = File.ReadLines(path).Take(10);
var title = lines.FirstOrDefault(l => l.StartsWith("# "))?.TrimStart('#', ' ');
var summary = lines.Skip(1).FirstOrDefault(l => !string.IsNullOrWhiteSpace(l));
return new DocInfo(path, title, summary);
}
// MD 转 HTML
public string ConvertToHtml(string markdown)
{
// 使用 Markdig 库
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.Build();
return Markdown.ToHtml(markdown, pipeline);
}
}
2. nx lint - 代码检查
检查代码是否符合 NextUI 最佳实践。
nx lint [--fix] [--rule <rule>] [path]
nx lint --list-rules # 列出所有可用规则
检查项:
| 规则 ID | 说明 | 自动修复 | 需要 AI |
|---|---|---|---|
NX001 |
组件缺少 @inject INextUILocalizer |
是 | 否 |
NX002 |
硬编码的 UI 文本 | 否 | 是 |
NX003 |
未使用 SxAppRoot 包裹应用 | 是 | 否 |
NX004 |
缺少 ThemeProvider 配置 | 是 | 否 |
NX005 |
缺少 LocaleState 服务注册 | 是 | 否 |
NX006 |
组件未继承正确基类 | 是 | 否 |
NX007 |
CSS 变量使用不规范 | 否 | 否 |
NX008 |
未正确处理暗色模式 | 否 | 是 |
3. nx check - 配置检查
检查项目配置是否正确。
nx check [--verbose]
检查项:
| 检查项 | 说明 |
|---|---|
| NextUI 版本一致性 | 所有 NextUI 包版本是否一致 |
| 必需包完整性 | 是否安装了必需的 NextUI 包 |
| SDK 版本兼容性 | .NET SDK 版本是否兼容 |
| 服务注册完整性 | Program.cs 是否正确注册服务 |
| 本地化配置 | 是否正确配置本地化 |
| 静态资源配置 | wwwroot 配置是否正确 |
| launchSettings | 端口和 HTTPS 配置 |
4. nx upgrade - 升级依赖
升级 NextUI 相关依赖。
nx upgrade [--preview] [--version <ver>]
功能:
- 检查可用的 NextUI 版本
- 显示升级变更和破坏性更改
- 自动更新 .csproj 文件
- 运行迁移脚本(如有)
5. nx ai - AI 辅助检查
使用 AI 分析代码问题。
nx ai check [path] # AI 检查代码
nx ai fix <issue-id> # AI 修复问题
nx ai explain <file> # AI 解释代码
nx ai review [path] # AI 代码审查
功能:
- 检测潜在的代码问题
- 建议最佳实践改进
- 解释代码逻辑
- 代码审查建议
AI 集成方案
架构设计
┌─────────────────────────────────────────────────────────┐
│ nx ai 命令 │
├─────────────────────────────────────────────────────────┤
│ AI Provider 抽象层 │
│ IAiProvider 接口 │
├─────────────────────────────────────────────────────────┤
│ Claude Code │ Claude API │ Cursor │ OpenAI/Codex │
│ (Headless) │ (直接) │(Headless)│ (API) │
└─────────────────────────────────────────────────────────┘
优先级策略
Claude Code Headless (默认,如果已安装且有订阅)
- 使用订阅流量,无额外费用
- 通过
claude --headless调用
Claude API (备选)
- 需要 API Key
- 按使用量计费
其他提供者 (可配置)
- Cursor Headless
- OpenAI/Codex API
- 本地模型 (Ollama 等)
配置
{
"ai": {
"provider": "claude-code", // claude-code | claude-api | cursor | openai | ollama
"claudeCode": {
"path": "claude", // Claude Code CLI 路径
"model": "sonnet" // 默认模型
},
"claudeApi": {
"apiKeyEnv": "ANTHROPIC_API_KEY",
"model": "claude-sonnet-4-20250514"
},
"cursor": {
"path": "cursor"
},
"openai": {
"apiKeyEnv": "OPENAI_API_KEY",
"model": "gpt-4"
},
"ollama": {
"endpoint": "http://localhost:11434",
"model": "codellama"
}
}
}
提供者接口
public interface IAiProvider
{
string Name { get; }
bool IsAvailable { get; }
int Priority { get; } // 用于自动选择
Task<AiResponse> AnalyzeAsync(string prompt, string code);
Task<AiResponse> FixAsync(string issue, string code);
Task<AiResponse> ExplainAsync(string code);
}
public class ClaudeCodeProvider : IAiProvider
{
public string Name => "Claude Code";
public int Priority => 100; // 最高优先级
public bool IsAvailable =>
File.Exists(GetClaudeCodePath()) && HasSubscription();
public async Task<AiResponse> AnalyzeAsync(string prompt, string code)
{
// 调用 claude --headless
var process = Process.Start(new ProcessStartInfo
{
FileName = "claude",
Arguments = "--headless --print",
RedirectStandardInput = true,
RedirectStandardOutput = true
});
await process.StandardInput.WriteLineAsync($"{prompt}\n\n```\n{code}\n```");
process.StandardInput.Close();
return new AiResponse(await process.StandardOutput.ReadToEndAsync());
}
}
自动选择逻辑
public class AiProviderFactory
{
private readonly List<IAiProvider> _providers;
public IAiProvider GetProvider()
{
// 1. 检查配置中指定的提供者
if (config.Ai?.Provider != null)
{
var specified = _providers.FirstOrDefault(p =>
p.Name.Equals(config.Ai.Provider, StringComparison.OrdinalIgnoreCase));
if (specified?.IsAvailable == true)
return specified;
}
// 2. 按优先级自动选择可用的提供者
return _providers
.Where(p => p.IsAvailable)
.OrderByDescending(p => p.Priority)
.FirstOrDefault()
?? throw new InvalidOperationException("No AI provider available");
}
}
检查规则系统
设计原则
- 配置化: 规则定义在 JSON 文件中,可随时扩展
- 可扩展: 支持自定义规则
- 分层: 静态规则 + AI 规则
规则定义格式
规则配置文件: nx-rules.json (或在 nx.json 中的 rules 字段)
{
"rules": {
"NX001": {
"enabled": true,
"severity": "error",
"description": "组件缺少 @inject INextUILocalizer",
"pattern": {
"type": "razor",
"match": "@inherits.*ComponentBase",
"notMatch": "@inject\\s+INextUILocalizer"
},
"fix": {
"insert": "@inject INextUILocalizer L\n",
"position": "after:@inherits"
}
},
"NX002": {
"enabled": true,
"severity": "warning",
"description": "硬编码的 UI 文本",
"requiresAi": true,
"aiPrompt": "检查以下代码中是否有硬编码的用户可见文本..."
},
"NX003": {
"enabled": true,
"severity": "error",
"description": "未使用 SxAppRoot 包裹应用",
"pattern": {
"type": "razor",
"file": "**/App.razor",
"notMatch": "<SxAppRoot>"
}
}
}
}
规则引擎
public interface ILintRule
{
string Id { get; }
string Description { get; }
LintSeverity Severity { get; }
bool RequiresAi { get; }
Task<IEnumerable<LintIssue>> AnalyzeAsync(LintContext context);
Task<LintFix?> GetFixAsync(LintIssue issue);
}
public class PatternBasedRule : ILintRule
{
private readonly RuleConfig _config;
public async Task<IEnumerable<LintIssue>> AnalyzeAsync(LintContext context)
{
var issues = new List<LintIssue>();
foreach (var file in context.GetFiles(_config.Pattern.Type))
{
if (_config.Pattern.File != null &&
!Glob.IsMatch(file, _config.Pattern.File))
continue;
var content = await File.ReadAllTextAsync(file);
var hasMatch = Regex.IsMatch(content, _config.Pattern.Match);
var hasNotMatch = _config.Pattern.NotMatch == null ||
!Regex.IsMatch(content, _config.Pattern.NotMatch);
if (hasMatch && hasNotMatch)
{
issues.Add(new LintIssue(Id, file, Description, Severity));
}
}
return issues;
}
}
public class AiBasedRule : ILintRule
{
public bool RequiresAi => true;
public async Task<IEnumerable<LintIssue>> AnalyzeAsync(LintContext context)
{
var aiProvider = context.GetAiProvider();
var issues = new List<LintIssue>();
foreach (var file in context.GetFiles())
{
var content = await File.ReadAllTextAsync(file);
var response = await aiProvider.AnalyzeAsync(_config.AiPrompt, content);
// 解析 AI 响应
issues.AddRange(ParseAiResponse(response, file));
}
return issues;
}
}
默认规则文件位置
- 内置规则: 编译到 CLI 中
- 项目规则:
{project}/nx-rules.json - 用户规则:
~/.nx/rules.json
优先级: 用户规则 > 项目规则 > 内置规则
项目类型检测
public enum ProjectType
{
Generic, // 普通 .NET 项目
NextUIFramework, // NextUI 框架本身
NextUIApp // 使用 NextUI 的应用
}
public static ProjectType DetectProjectType(string projectPath)
{
// 1. 检查 nx.json 中的 projectType
if (config.ProjectType != null)
return ParseProjectType(config.ProjectType);
// 2. 检查是否是框架项目
if (HasProject("NextUI.Core") || HasProject("NextUI.Blazor"))
return ProjectType.NextUIFramework;
// 3. 检查是否引用 NextUI 包
if (ReferencesNextUI())
return ProjectType.NextUIApp;
return ProjectType.Generic;
}
现有命令改进
1. doctor 命令增强
+ 检测项目类型 (nextui-app / generic)
+ 检查 NextUI 版本是否为最新
+ 检查本地化配置
+ 检查主题配置
- 移除 Framework 特定的检查(对于 app 项目)
2. build 命令增强
+ 支持从 .csproj 自动发现项目(无需 nx.json)
+ 支持 --all 构建所有项目
+ 支持 --affected 仅构建受影响的项目
+ 集成 lint 检查(可选)
3. test 命令增强
+ 配置化测试目录和模式
+ 支持代码覆盖率报告
+ 支持并行测试
+ 支持 --watch 模式
4. publish 命令增强
+ 配置化 NuGet 服务器
+ 支持多个 NuGet 源
+ 更灵活的版本号策略
配置扩展
完整 nx.json 配置示例
{
"name": "My NextUI App",
"projectType": "nextui-app",
"nextui": {
"version": "1.3.9",
"features": ["blazor"]
},
"ai": {
"provider": "claude-code",
"claudeCode": {
"path": "claude",
"model": "sonnet"
},
"claudeApi": {
"apiKeyEnv": "ANTHROPIC_API_KEY"
}
},
"lint": {
"rulesFile": "nx-rules.json",
"exclude": ["**/bin/**", "**/obj/**"],
"rules": {
"NX001": { "enabled": true, "severity": "error" },
"NX002": { "enabled": true, "severity": "warning" }
}
},
"docs": {
"directories": ["docs", "src/**/docs"],
"include": ["README.md", "CHANGELOG.md"]
},
"runTargets": {
"dev": {
"project": "src/MyApp/MyApp.csproj",
"port": 5000
}
},
"tests": {
"directory": "tests",
"pattern": "*.Tests.csproj"
},
"nuget": {
"source": "https://api.nuget.org/v3/index.json",
"apiKeyEnv": "NUGET_API_KEY"
}
}
文件结构
src/NextUI.Cli/
├── Engine/
│ ├── NxContext.cs (修改: 添加项目类型检测)
│ ├── NxConfig.cs (修改: 扩展配置模型)
│ ├── ProjectTypeDetector.cs (新增)
│ └── NextUIVersionChecker.cs (新增)
├── Commands/
│ ├── DocCommand.cs (新增)
│ ├── LintCommand.cs (新增)
│ ├── CheckCommand.cs (新增)
│ ├── UpgradeCommand.cs (新增)
│ ├── AiCommand.cs (新增)
│ ├── DoctorCommand.cs (修改)
│ ├── BuildCommand.cs (修改)
│ ├── TestCommand.cs (修改)
│ └── PublishCommand.cs (修改)
├── Docs/
│ ├── DocEngine.cs (新增)
│ ├── DocInfo.cs (新增)
│ └── MarkdownRenderer.cs (新增)
├── Linting/
│ ├── ILintRule.cs (新增)
│ ├── LintEngine.cs (新增)
│ ├── RuleLoader.cs (新增)
│ └── Rules/
│ ├── PatternBasedRule.cs (新增)
│ └── AiBasedRule.cs (新增)
├── Checking/
│ ├── IProjectChecker.cs (新增)
│ ├── CheckEngine.cs (新增)
│ └── Checkers/
│ ├── PackageVersionChecker.cs
│ ├── ServiceRegistrationChecker.cs
│ └── ...
├── AI/
│ ├── IAiProvider.cs (新增)
│ ├── AiProviderFactory.cs (新增)
│ └── Providers/
│ ├── ClaudeCodeProvider.cs (新增)
│ ├── ClaudeApiProvider.cs (新增)
│ ├── CursorProvider.cs (新增)
│ └── OpenAiProvider.cs (新增)
└── Resources/
└── default-rules.json (新增: 内置规则)
实现优先级
Phase 1: 基础设施 (核心)
- 扩展 NxConfig 支持新字段
- 实现项目类型检测
- 配置化现有硬编码值
Phase 2: 文档命令
- 实现
nx doc命令 - MD 文件扫描和解析
- MD 转 HTML 功能
- 浏览器打开功能
Phase 3: 检查命令
- 实现
nx check命令 - 实现基础检查器
Phase 4: 代码检查
- 设计规则配置格式
- 实现
nx lint命令 - 实现静态规则检查
- 实现自动修复
Phase 5: AI 集成
- 设计 AI Provider 接口
- 实现 Claude Code Provider (默认)
- 实现 Claude API Provider (备选)
- 实现
nx ai命令 - AI 规则检查
Phase 6: 升级和增强
- 实现
nx upgrade命令 - 增强现有命令
Phase 7: 扩展提供者 (可选)
- Cursor Provider
- OpenAI Provider
- 本地模型支持
验证方案
- 在现有 NextUI Framework 项目测试
- 创建测试用的 NextUI 应用项目
- 测试所有新命令
- 验证向后兼容性
关键文件路径
/Users/xuesong/work/Projects/nextui/src/NextUI.Cli//Users/xuesong/work/Projects/nextui/nx.json/Users/xuesong/work/Projects/nextui/src/NextUI.Cli/Engine/NxContext.cs/Users/xuesong/work/Projects/nextui/src/NextUI.Cli/Engine/NxConfig.cs/Users/xuesong/work/Projects/nextui/src/NextUI.Cli/Commands/
变更日志
v1.2.0 (2026-01-31)
- Phase 3 完成:
nx check命令- 实现 CheckEngine 和 IProjectChecker 接口
- 包版本一致性检查 (NX-PKG-001)
- SDK 版本兼容性检查 (NX-SDK-001)
- 服务注册完整性检查 (NX-SVC-001)
- 本地化配置检查 (NX-L10N-001)
- 静态资源检查 (NX-ASSET-001)
- 启动配置检查 (NX-LAUNCH-001)
- Phase 4 完成:
nx lint命令 + 规则系统- 实现 LintEngine 和 ILintRule 接口
- 缺少本地化服务规则 (NX001)
- 缺少 SxAppRoot 规则 (NX003)
- CSS 变量规范规则 (NX007)
- 支持自动修复 (--fix)
- Phase 5 完成: AI 集成 +
nx ai命令- 实现 IAiProvider 接口和 AiProviderFactory
- Claude Code Provider (默认,优先级 100)
- Claude API Provider (备选,优先级 90)
nx ai check- AI 检查代码问题nx ai explain- AI 解释代码nx ai review- AI 代码审查nx ai fix- AI 修复问题
- Phase 6 完成:
nx upgrade命令- 扫描项目中的 NextUI 包
- 检查 NuGet 上的最新版本
- 预览和执行升级
- 支持预发布版本
v1.1.0 (2026-01-31)
- Phase 1 完成: 基础设施扩展
- 扩展 NxConfig 支持新配置字段(projectType, nextui, ai, lint, docs, tests, nuget)
- 实现 ProjectTypeDetector 项目类型自动检测
- 配置化硬编码值(NuGet 服务器、测试目录)
- 更新 NxContext 集成项目类型检测
- Phase 2 完成:
nx doc命令nx doc list- 列出所有文档nx doc view <name>- 终端内查看文档nx doc html <name>- 浏览器中查看文档nx doc open <name>- html 别名
v1.0.0 (2026-01-31)
- 初始设计文档
- 定义 AI 集成方案(Claude Code Headless 优先)
- 定义配置化规则系统
- 新增
doc命令设计 - 新增
lint、check、upgrade、ai命令设计 - 定义 7 个实现阶段
© 2026 NextUI Team