4.4 KiB
UI 与扩展设计 — 总览
所属项目: free-code .NET 10 重写 配套文档: 总体概述与技术选型 | 核心模块设计 | 基础设施设计 | 服务子系统设计
概述
UI 与扩展设计覆盖 free-code .NET 10 重写中所有面向用户的终端界面层,以及三个扩展机制:技能、插件和特性开关。
原始 TypeScript 实现以 React/Ink 渲染终端 UI,用文件系统约定管理技能,用动态 import() 加载插件,用编译时 feature() 函数控制特性开关。.NET 重写将这四个关注点各自封装为独立模块:Terminal.Gui 替代 Ink 提供声明式终端 UI,ISkillLoader 替代目录扫描约定,AssemblyLoadContext 替代动态导入实现插件隔离,IFeatureFlagService 在运行时桥接编译时标志与配置驱动开关。
架构概览
REPLScreen (Terminal.Gui Window)
│
├── PermissionDialog 工具使用审批
├── CompanionSpriteView ASCII 精灵渲染
│
├── ISkillLoader 技能加载与执行
│ └── SkillDefinition + SkillHooks
│
├── IPluginManager 插件生命周期管理
│ └── PluginLoadContext (AssemblyLoadContext)
│
└── IFeatureFlagService 特性开关查询
└── FeatureFlags (54+ 常量)
子模块列表
Terminal.Gui 终端 UI
覆盖 TerminalApp 应用启动与主题配置、REPLScreen 主交互屏幕的完整实现,以及 PermissionDialog 和 CompanionSpriteView 组件。
原始来源: ../../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
PluginLoadContext 以 isCollectible: true 创建,允许在 UninstallPluginAsync 调用后通过 GC 完整回收插件的所有托管内存和类型元数据。这在语义上等价于原始 TypeScript 的动态 import() 隔离,但提供更强的确定性卸载保证。
特性开关双模式并存
编译时标志(#if ULTRAPLAN)用于完全消除死代码,减小最终二进制体积。运行时标志(IFeatureFlagService.IsEnabled)用于不重新编译就能切换的开关,由 appsettings.json 中的 FeatureFlags 配置节驱动,取代原始 GrowthBook 的云端下发机制。