free-code-dotnet/docs/UI与扩展设计/UI与扩展设计.md
应文浩wenhao.ying@xiaobao100.com e25ac591a7 init easy-code
2026-04-06 07:24:24 +08:00

4.4 KiB
Raw Blame History

UI 与扩展设计 — 总览

所属项目: free-code .NET 10 重写 配套文档: 总体概述与技术选型 | 核心模块设计 | 基础设施设计 | 服务子系统设计


概述

UI 与扩展设计覆盖 free-code .NET 10 重写中所有面向用户的终端界面层,以及三个扩展机制:技能、插件和特性开关。

原始 TypeScript 实现以 React/Ink 渲染终端 UI用文件系统约定管理技能用动态 import() 加载插件,用编译时 feature() 函数控制特性开关。.NET 重写将这四个关注点各自封装为独立模块Terminal.Gui 替代 Ink 提供声明式终端 UIISkillLoader 替代目录扫描约定,AssemblyLoadContext 替代动态导入实现插件隔离,IFeatureFlagService 在运行时桥接编译时标志与配置驱动开关。


架构概览

REPLScreen (Terminal.Gui Window)
    │
    ├── PermissionDialog          工具使用审批
    ├── CompanionSpriteView       ASCII 精灵渲染
    │
    ├── ISkillLoader              技能加载与执行
    │       └── SkillDefinition + SkillHooks
    │
    ├── IPluginManager            插件生命周期管理
    │       └── PluginLoadContext (AssemblyLoadContext)
    │
    └── IFeatureFlagService       特性开关查询
            └── FeatureFlags (54+ 常量)

子模块列表

Terminal.Gui 终端 UI

覆盖 TerminalApp 应用启动与主题配置、REPLScreen 主交互屏幕的完整实现,以及 PermissionDialogCompanionSpriteView 组件。

原始来源: ../../src/screens/REPL.tsx, ../../src/components/50+ React/Ink 组件)


技能系统

覆盖 ISkillLoader 接口、SkillDefinition 数据模型、SkillHooks 生命周期钩子,以及 SkillLoader 的目录扫描与 YAML frontmatter 解析实现。

原始来源: ../../src/skills/


插件系统

覆盖 IPluginManager 接口、PluginLoadContext 可卸载程序集加载上下文、PluginManager 的完整实现,以及 PluginManifest 清单结构。

原始来源: ../../src/plugins/


特性开关系统

覆盖 FeatureFlags 完整常量清单54+ 标志)、IFeatureFlagService 接口,以及 FeatureFlagService 的配置驱动实现。说明编译时 #if 与运行时 IsEnabled() 的双模式设计。

原始来源: scripts/build.ts feature() 编译时开关 + 运行时 GrowthBook


关键设计决策

Terminal.Gui 替代 React/Ink

原始项目深度依赖 React 组件模型和 Ink 的虚拟 DOM 终端渲染。.NET 重写选用 Terminal.Gui它提供与 Ink 语义最接近的声明式布局(Pos/Dim)、事件驱动模型和色彩主题系统,同时完全原生于 .NET 运行时,无需 Node.js 桥接。

技能作为 System Prompt 注入

技能系统不引入自定义执行运行时。技能的 Markdown 内容直接注入 QueryEngine 的 System Prompt参数拼接到提示末尾其余执行逻辑全部复用主查询管道。这与原始实现的语义完全一致且不新增任何抽象层。

插件隔离通过 isCollectible: true

PluginLoadContextisCollectible: true 创建,允许在 UninstallPluginAsync 调用后通过 GC 完整回收插件的所有托管内存和类型元数据。这在语义上等价于原始 TypeScript 的动态 import() 隔离,但提供更强的确定性卸载保证。

特性开关双模式并存

编译时标志(#if ULTRAPLAN)用于完全消除死代码,减小最终二进制体积。运行时标志(IFeatureFlagService.IsEnabled)用于不重新编译就能切换的开关,由 appsettings.json 中的 FeatureFlags 配置节驱动,取代原始 GrowthBook 的云端下发机制。


参考资料