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 包

核心问题

  1. 硬编码路径和 URL

    • NuGet 服务器: https://nuget.easyrote.net/
    • 测试目录: tests/
    • 解决方案文件: NextUI.sln
  2. 缺乏项目类型检测

    • 无法区分 Framework 项目 vs 应用项目
    • 无法检测项目是否使用 NextUI
  3. 缺少代码检查功能

    • 无代码质量检查
    • 无最佳实践验证
    • 无配置验证

扩展目标

支持的项目类型

┌─────────────────────────────────────────────────────────┐
│                    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)       │
└─────────────────────────────────────────────────────────┘

优先级策略

  1. Claude Code Headless (默认,如果已安装且有订阅)

    • 使用订阅流量,无额外费用
    • 通过 claude --headless 调用
  2. Claude API (备选)

    • 需要 API Key
    • 按使用量计费
  3. 其他提供者 (可配置)

    • 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;
    }
}

默认规则文件位置

  1. 内置规则: 编译到 CLI 中
  2. 项目规则: {project}/nx-rules.json
  3. 用户规则: ~/.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: 基础设施 (核心)

  1. 扩展 NxConfig 支持新字段
  2. 实现项目类型检测
  3. 配置化现有硬编码值

Phase 2: 文档命令

  1. 实现 nx doc 命令
  2. MD 文件扫描和解析
  3. MD 转 HTML 功能
  4. 浏览器打开功能

Phase 3: 检查命令

  1. 实现 nx check 命令
  2. 实现基础检查器

Phase 4: 代码检查

  1. 设计规则配置格式
  2. 实现 nx lint 命令
  3. 实现静态规则检查
  4. 实现自动修复

Phase 5: AI 集成

  1. 设计 AI Provider 接口
  2. 实现 Claude Code Provider (默认)
  3. 实现 Claude API Provider (备选)
  4. 实现 nx ai 命令
  5. AI 规则检查

Phase 6: 升级和增强

  1. 实现 nx upgrade 命令
  2. 增强现有命令

Phase 7: 扩展提供者 (可选)

  1. Cursor Provider
  2. OpenAI Provider
  3. 本地模型支持

验证方案

  1. 在现有 NextUI Framework 项目测试
  2. 创建测试用的 NextUI 应用项目
  3. 测试所有新命令
  4. 验证向后兼容性

关键文件路径

  • /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 命令设计
  • 新增 lintcheckupgradeai 命令设计
  • 定义 7 个实现阶段

© 2026 NextUI Team