UI组件跨平台桌面应用【免费下载链接】Terminal.GuiCross Platform Terminal UI toolkit for .NET项目地址https://gitcode.com/gh_mirrors/te/Terminal.Gui点击查看免费下载面向 Terminal.Gui v2 仓库的文档代码片段校验器DocSnippetValidator是一套基于 Roslyn 的 C# 文档示例保鲜方案它提取ai-v2-primer.md、Claude 任务文档等 AI Agent 文档中的每一个 csharp 代码块并针对构建出的Terminal.Gui.dll进行真实编译让 v1 API 残留、改名成员、无效构造函数等示例腐烂example rot在 CI 阶段直接失败而不是误导 Agent 与用户。读完本文你将掌握它的完整用法、两种编译模式、跳过机制、废弃 API 拦截策略与 CI 集成方式并能把它复用到你自己的文档仓库中。Terminal.Gui v2 是一次完全重写见 ai-v2-primer.md 中的说明Terminal.Gui v2 is a complete rewrite旧版大量 API 已被替换或标记废弃。这意味着任何以 v1 知识写成的示例代码都可能看起来合法、实际上无法编译。为此仓库在 Scripts/DocSnippetValidator 下提供了一套独立的校验工具配合 .github/workflows/validate-doc-snippets.yml 在 CI 中持续执行。工具定位编译文档而不是检查文档DocSnippetValidator 的核心思路非常朴素但有效把文档当作代码来编译。它遍历指定 Markdown 文件中的每一个csharp /cs 围栏代码块将其送入 RoslynMicrosoft.CodeAnalysis.CSharp编译为真实的程序集并以是否存在编译错误作为唯一判定标准。项目文件 DocSnippetValidator.csproj 中唯一的关键依赖正是PackageReference IncludeMicrosoft.CodeAnalysis.CSharp /同时它把OutputType设为Exe即它本身是一个命令行工具入口逻辑在 Program.cs。这个设计解决的是 AI Agent 协作场景下的特有痛点Agent 训练数据与文档中残留的 v1 写法如静态Application.Init()不会产生任何语法错误但一旦被复制进真实项目就会编译失败。只有当示例代码能真正编译通过时文档才是可信的。快速开始两条命令跑通校验README 中给出的用法非常直接先构建库再运行校验器把Terminal.Gui.dll的路径和要校验的文档列表作为参数传入dotnet build Terminal.Gui/Terminal.Gui.csproj -c Debug dotnet run --project Scripts/DocSnippetValidator -- \ Terminal.Gui/bin/Debug/net10.0/Terminal.Gui.dll \ ai-v2-primer.md .claude/tasks/build-app.md .claude/cookbook/common-patterns.md命令行格式为DocSnippetValidator path-to-Terminal.Gui.dll markdown-file...参数含义如下参数说明Terminal.Gui.dll已构建的库路径。程序启动时会先做File.Exists检查找不到则提示 Library not found: ... — build Terminal.Gui first. 并以退出码 2 结束见 Program.cs 第 16-23 行markdown-file...一个或多个待校验的 Markdown 文档路径不存在的文件会计入失败数并输出 File not found: ...校验结束后会打印汇总行Doc snippets: N compiled, M skipped, K failed.退出码约定为0表示全部通过1表示存在编译失败的代码块2表示命令行参数使用错误。这个退出码是 CI 能让失败直接阻断流水线的基础。两种编译模式完整单元与语句片段文档中的代码块形态各异有的包含完整的类型声明有的只是孤立的语句如X Pos.Center ();。SnippetCompiler.cs 的Compile方法通过解析语法树来自动区分这两种形态1. 完整单元complete units若代码块包含类型声明或using指令则将其视为独立编译单元在块内容前自动拼接一组标准using见下文按原样编译。若块中还包含顶层语句top-level statements则以OutputKind.ConsoleApplication编译成可执行程序否则以DynamicallyLinkedLibrary编译成库。2. 语句片段statement fragments若代码块既没有类型声明也没有using则视为片段。编译器会把它包装进一个继承自Runnablestring?的宿主类__SnippetHost的方法体内使块中的语句可以直接引用下面这些已经在作用域内的公共字段class __SnippetHost : Runnablestring? { IApplication app null!; View view null!; View otherView null!; Button button null!; Button loginButton null!; TextField textField null!; TextField usernameField null!; ListView listView null!; CheckBox checkbox null!; Label label null!; }选择字段而非参数是有讲究的源码注释明确指出字段允许片段中的局部变量与字段同名shadow不会触发CS0136局部变量与字段重名错误。如果包成方法体编译失败编译器会退而求其次把片段当作类成员重新包装编译——这覆盖了那些片段本身就是方法声明的文档用例见 SnippetCompiler.cs 第 85-99 行。标准 using 集合无论哪种模式代码块都会在开头拼接如下标准using保证片段无需自行引入命名空间即可引用 v2 的主要类型这正是 v2 去扁平化的体现——using Terminal.Gui;裸命名空间已不再存在取而代之的是按功能拆分的子命名空间using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.IO; using System.Linq; using Terminal.Gui.App; using Terminal.Gui.Configuration; using Terminal.Gui.Drawing; using Terminal.Gui.Input; using Terminal.Gui.Text; using Terminal.Gui.ViewBase; using Terminal.Gui.Views;缩进还原与错误行号提取器 SnippetExtractor.cs 会记录围栏起始行StartLine并剥离围栏自身的缩进前缀保证嵌套在列表或引用块中的代码块也能被正确还原。编译错误会换算回片段内相对行号输出减去拼接的前缀行数例如file.md(12): snippet does not compile: (snippet line 4) CS0246: The type or namespace name Toplevel could not be found ...如何让某个代码块跳过校验并非所有代码块都应该通过编译。文档里常出现的反例anti-pattern示例是故意写错的用于对比新旧 API。提取器内置了三类自动跳过标记见 SnippetExtractor.cs 中的_wrongMarkers块内包含// WRONG块内包含❌块内包含✗另外也可以在围栏的前两行内放置 HTML 注释!-- snippet: ignore --来显式跳过某个块!-- snippet: ignore -- csharp Application.Init (); // 故意展示的 v1 写法不参与编译这两种方式分别对应 [README.md](https://link.gitcode.com/i/19517b4f6b5120704a0e912b64f7e212) 中Opting a block out一节的两种途径覆盖了自动识别反例与人工显式豁免两类需求。被跳过的块会计入汇总行的 skipped 计数。 ## 废弃 API 被视为失败拦截 v1 腐烂的关键策略 这是整个工具最有价值的设计决策。默认情况下Roslyn 对 [Obsolete] 成员的调用只产生 **警告**CS0618/CS0612代码依然能编译通过。但 DocSnippetValidator 在 CompileSource 中通过 specificDiagnosticOptions 把这两条警告**升级为错误** csharp new (CS0105, ReportDiagnostic.Suppress), // 消除标准 usings 拼接导致的重复 using 噪音 new (CS0612, ReportDiagnostic.Error), // 废弃 API 使用 失败 new (CS0618, ReportDiagnostic.Error),同时源码特意不使用blanket 的#pragma warning disable——因为那会把上述两条升级规则一并压制掉。这样做的直接后果是即使某个废弃成员仍然以[Obsolete]垫片shim的形式存在于库中、语法上能编译任何用到它的文档示例也会失败。以 v1 的静态Application.Init为例它在 Terminal.Gui/App/Legacy/Application.Lifecycle.cs 中仍以[Obsolete(The legacy static Application object is going away. Use Application.Create() for new code.)]的形式保留见该文件第 18 行但其用法一旦出现在文档代码块中就会被判为失败。这确保了 旧写法仍然能运行 不等于 旧写法可以写进文档。测试与 CI 集成负向测试防止回归工具的自身行为也受到回归保护。仓库提供了 testdata/obsolete-api.md 作为负向测试夹具该文件使用废弃的 v1 APIApplication.Init ();与Application.Shutdown ();且没有任何// WRONG标记因此一个行为正确的校验器必须拒绝它、返回非零退出码。CI 工作流 .github/workflows/validate-doc-snippets.yml 中的最后一步专门验证这一点它故意对夹具运行校验器若命令意外成功退出码为 0则输出::error::validator accepted an obsolete-API snippet并使整个 CI 失败只有命令如预期地返回非零才打印negative test passed。这样校验器不再对废弃 API 报错这一回归本身也会被抓出来。工作流触发与执行步骤validate-doc-snippets.yml在pushdevelop 分支与pull_request时触发且带有paths过滤只有下列内容发生变化时才运行ai-v2-primer.md.claude/tasks/build-app.md.claude/cookbook/common-patterns.mdllms.txtTerminal.Gui/**库代码变化会破坏既有示例因此也要触发Scripts/DocSnippetValidator/**工具自身变化.github/workflows/validate-doc-snippets.yml工作流变化执行流程共四步检出代码fetch-depth: 0供 GitVersion.MsBuild 使用→ 安装 .NET 10dotnet-version: 10.x→ 以 Debug 配置构建Terminal.Gui.csproj→ 对四个文档含llms.txt运行校验器。注意CI 校验的文档集合比 README 示例多一个llms.txt实际以工作流中的命令为准。端到端调用链一览综合 Program.cs 与各组件一次完整校验的执行链路为Program.cs参数校验计数 └─ SnippetExtractor.Extract(mdPath) # 提取 csharp/cs 块识别 WRONG/ignore 标记 └─ SnippetCompiler.Compile(snippet) # 判定完整单元/片段包装并编译 └─ CSharpCompilation引用 TPA 全量程序集 Terminal.Gui.dll └─ 错误收集 → 输出 file(line): snippet does not compile: 行号对齐的错误其中编译器构造时会将运行时TRUSTED_PLATFORM_ASSEMBLIES中的全部框架程序集逐一声明为元数据引用再追加传入的Terminal.Gui.dll见 SnippetCompiler.cs 第 56-66 行因此编译环境与正常 .NET 项目一致。所有编译均启用可空上下文NullableContextOptions.Enable并使用LanguageVersion.Preview解析语法。结语与复用建议DocSnippetValidator 给出了一个可迁移的通用范式凡是面向 AI Agent 或外部用户的文档都应该把示例代码纳入编译验证。本仓库通过完整单元原样编译 语句片段注入宿主类的双模式策略兼容了各种代码块形态通过WRONG 标记自动跳过 snippet: ignore显式豁免处理了反例示例通过废弃 API 升级为错误拦截了最隐蔽的 v1 腐烂最后用负向测试夹具锁住了工具自身的行为。若你维护自己的文档仓库只需仿照 validate-doc-snippets.yml 将文档路径加入触发列表即可为文档示例建立同样的持续保鲜机制。相关实现与测试均可在仓库中直接查阅Program.cs、SnippetCompiler.cs、SnippetExtractor.cs 与 testdata/obsolete-api.md。赞分享UI组件跨平台桌面应用【免费下载链接】Terminal.GuiCross Platform Terminal UI toolkit for .NET项目地址https://gitcode.com/gh_mirrors/te/Terminal.Gui点击查看免费下载相关推荐Clippy 持续集成实战在 GitHub Actions、GitLab CI 与 Travis CI 中接入 Rust 代码检查Clippy 持续集成实战在 GitHub Actions、GitLab CI 与 Travis CI 中接入 Rust 代码检查 Clippy 是 Rust静态分析代码质量开发工具Shipping Artifacts 文档集让 AI 编写的代码可审查、可审计pm-ai-shipping 技能详解Shipping Artifacts 文档集让 AI 编写的代码可审查、可审计pm ai shipping 技能详解 AI 代理写代码很快但它不会留下关AI 技能AI 插件AI SDK Code Mode 实战让模型在 QuickJS 沙箱中编写代码编排你的 AI 工具AI SDK Code Mode 实战让模型在 QuickJS 沙箱中编写代码编排你的 AI 工具 ai sdk/code mode 是 AI SDK 官方人工智能AI 应用AI Agent工具调用MCP Clients上一篇2024-01-15 周一下一篇PDFarranger终极指南三步学会免费PDF页面重排与合并创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考