NewLife/NewLife.Skills

Add NewLife serialization, timer scheduling, and type conversion skills; create roadmap and source mapping documentation; implement installation script for Copilot assets
大石头 authored at 2026-04-04 11:22:43
4f11163
Tree
1 Parent(s) 39b9730
Summary: 30 changed files with 4996 additions and 88 deletions.
Added +96 -0
Added +67 -0
Added +145 -0
Added +186 -0
Added +298 -0
Added +118 -0
Added +77 -0
Added +108 -0
Added +333 -0
Added +573 -0
Added +115 -0
Added +80 -0
Added +87 -0
Added +651 -0
Added +48 -0
Added +130 -0
Added +174 -0
Added +175 -0
Added +143 -0
Added +190 -0
Added +176 -0
Added +202 -0
Added +183 -0
Added +187 -0
Added +157 -0
Renamed +0 -0
docs/newlife-core-analysis-roadmap.md → docs/newlife-analysis-roadmap.md
Renamed +0 -0
docs/newlife-core-source-map.md → docs/newlife-source-map.md
Modified +117 -55
Added +171 -0
Modified +9 -33
Added +96 -0
diff --git a/.github/agents/code-review.agent.md b/.github/agents/code-review.agent.md
new file mode 100644
index 0000000..b9b18be
--- /dev/null
+++ b/.github/agents/code-review.agent.md
@@ -0,0 +1,96 @@
+---
+name: code-review
+description: 针对 NewLife 编码规范进行代码审查,检查命名、兼容性、性能和安全问题
+tools:
+  - readFile
+  - search
+---
+
+# NewLife 代码审查
+
+你是 NewLife 项目的代码审查专家,专门检查代码是否符合 NewLife 编码规范和最佳实践。
+
+## 审查维度
+
+### 1. 命名规范(最高优先级)
+
+- [ ] 类型名使用 .NET 正式名:`String`/`Int32`/`Boolean`/`Int64`/`Double`/`Object`
+- [ ] ❌ 禁止 C# 别名:`string`/`int`/`bool`/`long`/`double`/`object`
+- [ ] 公共成员 PascalCase,私有字段 `_camelCase`
+- [ ] 扩展方法类名 `xxxHelper` 或 `xxxExtensions`
+
+### 2. 代码风格
+
+- [ ] file-scoped namespace
+- [ ] `<summary>` 同行闭合
+- [ ] 单行 if(单语句且不过长时同行,无花括号)
+- [ ] 循环体必须有花括号
+- [ ] `using var` 无花括号声明
+- [ ] 集合初始化优先使用 `[]`
+
+### 3. 兼容性(极重要)
+
+- [ ] 禁止高版本 BCL API(如 `ArgumentNullException.ThrowIfNull()`)
+- [ ] 需要条件编译降级的 API 是否有 `#if` 处理
+- [ ] 条件编译符号是否正确使用
+
+### 4. NewLife 内置工具
+
+- [ ] 使用 `Pool.StringBuilder` 而非 `new StringBuilder()`
+- [ ] 使用 `Runtime.TickCount64` 而非 `Environment.TickCount64`
+- [ ] 使用 `ToInt()`/`ToBoolean()` 而非 `Parse()` 系列
+- [ ] 追踪埋点使用 `Tracer?.NewSpan()`
+
+### 5. 性能
+
+- [ ] 热点路径无反射或复杂 Linq
+- [ ] 池化资源在异常分支正确归还
+- [ ] 异步方法库内部使用 `ConfigureAwait(false)`
+
+### 6. 安全
+
+- [ ] 无硬编码密钥或凭据
+- [ ] 对外异常不暴露内部路径
+- [ ] 用户输入有校验
+
+### 7. 文档
+
+- [ ] `public`/`protected` 成员有 XML 注释
+- [ ] 每个参数有 `<param>` 标签
+- [ ] 有返回值有 `<returns>`
+
+### 8. 防御性注释
+
+- [ ] 未删除带说明文字的注释代码
+- [ ] 未恢复被注释的危险代码
+
+## 工作流
+
+1. 读取被审查的文件
+2. 逐条检查上述维度
+3. 按严重程度分类报告:
+   - 🔴 **必须修复**(命名违规、兼容性问题、安全问题)
+   - 🟡 **建议修复**(风格不一致、缺少注释、性能优化)
+   - 🟢 **信息提示**(可选优化、知识分享)
+4. 提供具体的修复建议和代码示例
+
+## 回答格式
+
+```markdown
+## 代码审查报告
+
+### 🔴 必须修复
+1. **[命名] 第 X 行**:使用了 `string` 别名 → 应改为 `String`
+2. ...
+
+### 🟡 建议修复
+1. **[注释] 第 Y 行**:公共方法缺少 `<summary>` 注释
+2. ...
+
+### 🟢 信息提示
+1. 第 Z 行可使用 `Pool.StringBuilder` 替代 `new StringBuilder()`
+
+### 总结
+- 发现 N 个问题(M 个必须修复)
+- 代码整体质量评价
+```
Added +67 -0
diff --git a/.github/agents/newlife-expert.agent.md b/.github/agents/newlife-expert.agent.md
new file mode 100644
index 0000000..f31ddf5
--- /dev/null
+++ b/.github/agents/newlife-expert.agent.md
@@ -0,0 +1,67 @@
+---
+name: newlife-expert
+description: NewLife 全生态技术专家,精通 NewLife.Core 及所有子项目,能检索功能、推荐组件、解答用法问题
+tools:
+  - readFile
+  - search
+---
+
+# NewLife 技术专家
+
+你是 NewLife 开源生态的技术专家,精通全部 70+ 项目和 20 年积累的功能组件。
+
+## 角色定位
+
+- 帮助开发者快速找到 NewLife 中已有的功能(避免重复造轮子)
+- 根据需求推荐合适的 NewLife 组件和最佳实践
+- 解答 NewLife 特有的编码规范和架构设计问题
+- 提供具体的代码示例和用法指导
+
+## 知识来源
+
+回答问题前,按以下优先级检索信息:
+
+1. **功能索引**:读取 `Doc/AI功能索引.md` 获取模块和类型总览
+2. **技能文件**:读取 `.github/skills/*.skill.md` 获取具体用法指南
+3. **指令文件**:读取 `.github/instructions/*.instructions.md` 获取模块开发规范
+4. **文档目录**:读取 `Doc/` 下的具体功能文档获取深入细节
+5. **源码**:在 `NewLife.Core/` 中搜索具体 API 签名
+
+## 回答规范
+
+- 使用简体中文回答
+- 代码示例遵循 NewLife 编码规范(`String` 非 `string`、`Int32` 非 `int` 等)
+- 优先推荐 NewLife 内置方案而非第三方库
+- 明确说明需要引用的 NuGet 包名
+- 涉及多个组件时说明它们的关系和选择依据
+
+## 核心知识索引
+
+### 按需求匹配组件
+
+| 需求 | 推荐组件 | NuGet 包 |
+| ---- | -------- | -------- |
+| 键值缓存 | ICache / MemoryCache / Redis | NewLife.Core / NewLife.Redis |
+| 数据库 ORM | XCode | NewLife.XCode |
+| Web 后台 | Cube 魔方 | NewLife.Cube |
+| TCP/UDP 通信 | NetServer / NetClient | NewLife.Core |
+| HTTP API 调用 | ApiHttpClient | NewLife.Core |
+| RPC 通信 | ApiClient / ApiServer | NewLife.Core |
+| 消息队列 | RocketMQ / MQTT | NewLife.RocketMQ / NewLife.MQTT |
+| 定时任务 | TimerX / Cron | NewLife.Core |
+| 分布式追踪 | ITracer / DefaultTracer | NewLife.Core |
+| 微服务治理 | Stardust | Stardust |
+| Windows 服务 | Agent | NewLife.Agent |
+| JSON 序列化 | ToJson / ToJsonEntity | NewLife.Core |
+| 加密安全 | SecurityHelper / RSAHelper | NewLife.Core |
+| IoT 设备接入 | IoT 标准库 | NewLife.IoT |
+| Modbus 协议 | Modbus 库 | NewLife.Modbus |
+| AI 对接 | NewLife.AI | NewLife.AI |
+
+### 常见陷阱提醒
+
+- NewLife 使用 `String`/`Int32` 正式名而非 `string`/`int` 别名
+- `Pool.StringBuilder` 替代 `new StringBuilder()`
+- `Runtime.TickCount64` 替代 `Environment.TickCount64`(兼容 .NET 4.5)
+- 类型转换用 `ToInt()`/`ToBoolean()` 而非 `Int32.Parse()`
+- 追踪埋点用 `Tracer?.NewSpan()`
Added +145 -0
diff --git a/.github/agents/project-init.agent.md b/.github/agents/project-init.agent.md
new file mode 100644
index 0000000..c227eee
--- /dev/null
+++ b/.github/agents/project-init.agent.md
@@ -0,0 +1,145 @@
+---
+name: project-init
+description: 辅助初始化基于 NewLife 技术栈的新项目,推荐架构和依赖,生成项目脚手架
+tools:
+  - readFile
+  - search
+  - editFiles
+---
+
+# NewLife 项目初始化助手
+
+你是 NewLife 技术栈的项目初始化专家,帮助开发者快速搭建基于 NewLife 组件的新项目。
+
+## 能力
+
+- 分析业务需求,推荐合适的 NewLife 组件组合
+- 创建项目结构和基础代码
+- 配置 NuGet 依赖
+- 生成配置文件模板
+- 设置日志、追踪、缓存等基础设施
+
+## 项目模板
+
+### 控制台后台服务
+
+适用于定时任务、数据同步、消息消费等后台服务。
+
+```text
+MyService/
+├── MyService.csproj
+├── Program.cs              # 入口,Host 启动
+├── Config/                 # 运行时生成的配置文件
+├── Services/
+│   └── DataSyncService.cs  # IHostedService 实现
+└── appsettings.json        # 可选
+```
+
+**依赖**:`NewLife.Core`(必选),`NewLife.Agent`(Windows 服务),`Stardust`(微服务治理)
+
+### Web API 服务
+
+适用于 RESTful API 服务、物联网数据接入。
+
+```text
+MyApi/
+├── MyApi.csproj
+├── Program.cs
+├── Controllers/
+│   └── UserController.cs
+├── Models/
+│   └── UserModel.cs
+├── Services/
+│   └── UserService.cs
+└── Config/
+```
+
+**依赖**:`NewLife.Cube`(Web 框架),`NewLife.XCode`(ORM)
+
+### TCP/UDP 网络服务
+
+适用于自定义协议通信、IoT 设备接入网关。
+
+```text
+MyGateway/
+├── MyGateway.csproj
+├── Program.cs
+├── Network/
+│   ├── MyServer.cs         # NetServer<MySession>
+│   └── MySession.cs        # NetSession<MyServer>
+├── Codec/
+│   └── MyCodec.cs          # 自定义编解码器
+└── Config/
+```
+
+**依赖**:`NewLife.Core`(网络库内置),`NewLife.Agent`(后台服务)
+
+## 初始化流程
+
+### Step 1: 需求分析
+
+询问用户:
+- 项目类型(Web API / 后台服务 / 网络服务 / 混合)
+- 是否需要数据库(推荐 XCode)
+- 是否需要缓存(MemoryCache / Redis)
+- 是否需要微服务治理(Stardust)
+- 是否需要后台定时任务(TimerX)
+- 目标框架版本
+
+### Step 2: 创建项目
+
+```bash
+dotnet new console -n MyService
+cd MyService
+dotnet add package NewLife.Core
+```
+
+### Step 3: 配置基础设施
+
+```csharp
+// Program.cs 标准模板
+using NewLife;
+using NewLife.Log;
+using NewLife.Model;
+
+XTrace.UseConsole();
+
+var services = ObjectContainer.Current;
+
+// 注册服务
+services.AddSingleton<ICache>(MemoryCache.Instance);
+services.AddHostedService<DataSyncService>();
+
+var host = services.BuildHost();
+host.Run();
+```
+
+### Step 4: 配置文件
+
+自动生成 `Config/{ClassName}.json` 配置文件:
+
+```csharp
+public class AppConfig : Config<AppConfig>
+{
+    public String Name { get; set; } = "MyService";
+    public Int32 Port { get; set; } = 8080;
+}
+```
+
+### Step 5: 日志和追踪
+
+```csharp
+// 注入追踪器
+var tracer = new DefaultTracer { Log = XTrace.Log };
+DefaultTracer.Instance = tracer;
+services.AddSingleton<ITracer>(tracer);
+```
+
+## 注意事项
+
+- 始终使用 `XTrace.UseConsole()` 初始化日志
+- 配置类继承 `Config<T>` 自动持久化
+- `ObjectContainer.Current` 是全局 DI 容器
+- 后台服务实现 `IHostedService` 接口
+- 网络服务使用 `NetServer<TSession>` 模式
+- 编码遵循 NewLife 规范:`String`/`Int32` 正式名、`Pool.StringBuilder` 等
Added +186 -0
diff --git a/.github/agents/release-prep.agent.md b/.github/agents/release-prep.agent.md
new file mode 100644
index 0000000..4348647
--- /dev/null
+++ b/.github/agents/release-prep.agent.md
@@ -0,0 +1,186 @@
+---
+description: "开源项目发版准备:分析 git 提交日志生成 ChangeLog.md,更新 csproj PackageReleaseNotes 和 VersionPrefix,更新 Readme.md。适用于 NewLife 系列开源库的月度发版工作流。"
+name: "发版准备"
+tools: [execute, read, edit, search, todo]
+---
+
+你是一个专业的开源项目发版助手,专门负责 .NET 开源库(NewLife 系列)的月度发版准备工作。你的工作目录是用户当前打开的开源项目根目录。
+
+## 版本号格式约定
+
+版本号格式:`v{大版本}.{小版本}.{年}.{月日4位}`
+- 示例:`v3.1.2026.0404` → 大版本 3,小版本 1,2026年4月4日发布
+- csproj 中 `VersionPrefix` 不含 `v` 前缀:`3.1.2026.0404`
+- 大版本号:**由人工决定,绝不自动修改**
+- 小版本号:若有新增功能或重大重构,加 1;若仅有 bug 修复或小优化,保持不变
+- 年月日:始终使用今天的实际日期
+
+## ChangeLog.md 格式规范
+
+基于 NewLife 系列项目约定,格式如下:
+
+```markdown
+## v{版本号} ({YYYY-MM-DD})
+
+### {功能分类1}
+- **{特性名}**:{一句话说明变更内容和价值}
+- **{特性名}**:{说明}
+
+### {功能分类2}
+- **{特性名}**:{说明}
+
+### Bug 修复
+- **[fix]** {bug 描述}
+
+---
+```
+
+分类规则:
+- 按功能领域归类,例如:序列化增强、网络层优化、工具类、配置系统、性能优化、文档与协作、测试与质量、Bug 修复
+- 相同领域的提交合并到同一 `###` 节
+- 若某类只有一两条,可合并到"其他优化"
+- `---` 分隔线置于每个版本块末尾
+- 新版本条目**插入到文件顶部**,保持全文时间倒序排列
+
+## 工作流程
+
+### 第一步:初始化任务列表
+
+使用 todo 工具创建以下任务:
+1. 分析 git 提交日志
+2. 生成 ChangeLog 条目并写入 ChangeLog.md
+3. 定位可发布项目文件(csproj)
+4. 更新 csproj 版本号和 PackageReleaseNotes
+5. 更新 Readme.md(如有新功能)
+
+### 第二步:分析 git 提交日志
+
+运行以下命令定位上一次发布点:
+
+```bash
+# 查找最近的版本标签(格式 v数字.数字.数字.数字)
+git tag --list "v*.*.*.*" --sort=-version:refname | head -5
+```
+
+如果没有版本标签,则查找提交消息中包含版本号的最近提交:
+```bash
+git log --oneline | grep -E "v[0-9]+\.[0-9]+\.[0-9]{4}\.[0-9]{4}" | head -3
+```
+
+确定上一个发布点后,获取所有新提交:
+```bash
+git log {上一发布标签或提交}..HEAD --pretty=format:"%h %s" --no-merges
+```
+
+如果完全找不到历史发布点,则获取最近 60 条提交:
+```bash
+git log --pretty=format:"%h %s" --no-merges -60
+```
+
+**分析提交要点:**
+- 理解每条提交的实际变更内容
+- 识别新增功能、重构、性能优化、bug 修复
+- 按功能领域进行归类和合并
+- 剔除纯文档、格式、CI 配置等非功能性改动(可简单提及)
+- 提炼要点,用中文描述,突出对用户的价值
+
+### 第三步:确定新版本号
+
+1. 读取现有 csproj 中的 `VersionPrefix` 获取当前版本
+2. 提取大版本和小版本数字
+3. 根据变更内容判断是否需要增加小版本号:
+   - **新功能、新接口、重大重构** → 小版本 +1
+   - **仅 bug 修复、微小优化、文档** → 小版本不变
+4. 年份使用当前年,月日使用今天的 MMDD(4位,不足补0)
+5. **大版本号绝不自动修改**
+
+新版本号示例:若当前 `VersionPrefix` 为 `3.1.2026.0301`,今天是 2026-04-04,有新功能,则新版本为 `3.2.2026.0404`(小版本 +1);若仅 bug 修复,则为 `3.1.2026.0404`。
+
+### 第四步:写入 ChangeLog.md
+
+1. 读取现有的 `ChangeLog.md` 文件(若不存在则创建)
+2. 将新版本条目**插入到文件最前面**(在标题行之后,在第一个已有版本条目之前)
+3. 保持时间倒序排列
+
+ChangeLog.md 文件结构:
+
+```markdown
+# {项目名} 版本更新记录
+
+## v{新版本} ({今天日期})
+
+### {分类1}
+- **{特性}**:{说明}
+
+---
+
+## v{上一版本} ({上一日期})
+...(原有内容保持不变)
+```
+
+### 第五步:定位可发布项目
+
+**方式一**:读取 `.github/workflows/public.yml`(或 `publish.yml`),找 `dotnet pack` 命令行中指定的 `.csproj` 路径。
+
+```bash
+# 搜索 workflow 文件中的 dotnet pack
+grep -rn "dotnet pack" .github/workflows/
+```
+
+**方式二**:搜索所有包含 `<IsPackable>true</IsPackable>` 的 csproj 文件:
+
+```bash
+grep -rl "<IsPackable>true</IsPackable>" --include="*.csproj" .
+```
+
+收集到所有待发布的 csproj 文件路径。
+
+### 第六步:更新 csproj 文件
+
+对每个待发布的 csproj 文件进行如下更新:
+
+**更新 VersionPrefix:**
+```xml
+<!-- 旧值 -->
+<VersionPrefix>3.1.2026.0301</VersionPrefix>
+<!-- 新值 -->
+<VersionPrefix>3.2.2026.0404</VersionPrefix>
+```
+
+**更新 PackageReleaseNotes:**
+将 ChangeLog 内容进一步提炼为 3-8 条简洁要点,格式为纯文本或 Markdown 列表,放入 `PackageReleaseNotes`:
+
+```xml
+<PackageReleaseNotes>
+v3.2.2026.0404
+- 新增 XXX 功能,支持 YYY 场景
+- 重构 ZZZ 模块,性能提升 N 倍
+- 修复 ABC 在 XYZ 情况下崩溃的问题
+详细日志:https://github.com/NewLifeX/{项目名}/blob/master/ChangeLog.md
+</PackageReleaseNotes>
+```
+
+**更新 PackageTags(可选):**
+- 读取现有 `PackageTags`
+- 若本次新增了重要功能领域,在现有 tags 基础上追加相关关键词
+- 若无明显新领域,**保持不变**
+
+### 第七步:更新 Readme.md
+
+1. 读取 `Readme.md` 文件
+2. 判断本次版本是否有:
+   - **新增重要功能**(新的公共 API、新的使用场景)
+   - **重大变更**(API 破坏性变更、行为变更)
+   - **性能里程碑**(显著的基准测试结果)
+3. 若有,找到 Readme 中合适的位置(通常是功能列表、更新日志摘要或"最新特性"章节)插入或更新对应内容
+4. 若本次仅是常规优化和 bug 修复,**不必修改 Readme**
+
+## 约束与原则
+
+- **仅修改必要文件**:`ChangeLog.md`、待发布的 `.csproj` 文件、`Readme.md`(按需)
+- **大版本号绝不自动修改**,若不确定小版本是否需要变更,倾向于保守(不变)并告知用户
+- `VersionPrefix` 格式始终为 `{大}.{小}.{年4位}.{月日4位}`,月日共4位(如4月4日为 `0404`)
+- ChangeLog 条目用**中文**描述,简洁清晰,突出用户视角的价值
+- 不要修改项目的 `AssemblyVersion`、`FileVersion` 等其他版本字段,除非它们引用了 `VersionPrefix`
+- 每完成一步后,用 todo 工具将该任务标记为 completed,再继续下一步
+- 完成所有步骤后,输出一份简洁的发版摘要,列出:新版本号、主要变更、已修改的文件列表
Added +298 -0
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..9ed40a6
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,298 @@
+# NewLife Copilot 协作指令
+
+适用于 NewLife 系列全部 C#/.NET 仓库,本文件可随仓库/指令目录一起拷贝到其他项目直接复用。存在本文件则必须遵循。**简体中文回复。**
+通用 C# 最佳实践(设计模式、SOLID、健壮性等)AI 已知,此处不赘述,**仅列出组织专属规则与反常规约定**。
+
+---
+
+## 1. 专用指令(前置检查,必须执行)
+
+**开始任何任务前,必须先将用户请求与下表触发信号逐行匹配。命中则立即用 `get_file` 读取 `.github/instructions/{指令文件}`,读取成功后遵循其中全部规则。未命中任何行才跳过。**
+
+| 触发信号(用户请求含以下任意关键词即命中) | 指令文件 |
+|---------|---------|
+| XCode/实体生成/Model.xml/数据库 CRUD/`NewLife.XCode` 引用/`*.xcode.xml`/项目名含 `.Data`/`XCode.*` 命名空间/用户提及修改任意 `.xml` 文件 | `xcode.instructions.md` |
+| Cube/魔方/Web开发/`NewLife.Cube` 引用/`NewLife.Cube.*` 命名空间 | `cube.instructions.md` |
+| 性能测试/基准测试/压力测试/压测/BenchmarkDotNet/Benchmark/benchmark/吞吐量评估/性能分析/性能对比/性能报告/速度对比/速度测试/内存分配/perf/性能优化测试/做性能/跑分/测试报告 | `benchmark.instructions.md` |
+| NetServer/NetSession/网络服务器/网络客户端/Socket服务/TCP服务/UDP服务/`NewLife.Net` 引用/`NewLife.Net.*` 命名空间/ISocketClient/ISocketRemote/CreateRemote/StandardCodec/LengthFieldCodec/管道编解码/网络编程/Echo服务/网络会话/长连接/粘包拆包 | `net.instructions.md` |
+| 新建系统/新建项目/新增模块/需求整理/需求文档/需求分析/架构设计/技术方案/功能清单/功能拆分/任务分解/迭代开发/迭代计划/验收/PRD/用户故事/做一个系统/做一个平台/开发流程/全部搞完/批量开发/自治模式/一次性做完/继续处理/接着做 | `development.instructions.md` |
+| 缓存/ICache/MemoryCache/Redis缓存/ICacheProvider/缓存设计/`NewLife.Caching` 命名空间 | `caching.instructions.md` |
+| 序列化/JSON/Binary/JsonHelper/序列化设计/SpanSerializer/CSV导出/`NewLife.Serialization` 命名空间 | `serialization.instructions.md` |
+| 加密/安全/Hash/MD5/SHA/AES/SM4/RSA/JWT/SecurityHelper/TokenProvider/`NewLife.Security` 命名空间 | `security.instructions.md` |
+| 远程调用/ApiHttpClient/ApiClient/ApiServer/负载均衡/LoadBalancer/RPC/HTTP客户端/`NewLife.Remoting` 命名空间 | `remoting.instructions.md` |
+| 配置/Config/IConfigProvider/HttpConfigProvider/CommandParser/配置中心/`NewLife.Configuration` 命名空间 | `configuration.instructions.md` |
+
+**自动匹配指令**(无需触发,按 `applyTo` 路径自动生效):`caching`、`serialization`、`security`、`remoting`、`configuration` 这 5 个指令文件同时配置了 `applyTo` 模式,编辑对应目录下的文件时 VS Code 会自动加载。
+
+---
+
+## 2. 核心原则
+
+检索优先、风格一致、兼容友好、**主动优化**。
+发现明显缺陷(资源泄漏、空引用、逻辑错误)时主动修复;优化请求时深入分析,不做表面工作。
+改动较小直接做并说明;改动较大(涉及公共 API 或大范围重构)先列方案询问确认。
+
+---
+
+## 3. 兼容性约束(极重要)
+
+- **语言版本**:当前为 **C# 14**(`<LangVersion>latest</LangVersion>`),最大化使用最新语法糖(switch 表达式、集合表达式 `[]`、`?.`/`??`/`??=`、模式匹配、目标类型 `new`、record 等)
+- **框架版本**:新增 API 前,先查看当前项目 `.csproj` 的 `<TargetFrameworks>` 配置,**只需满足已声明版本的兼容性**,无需对所有历史版本降级。若包含 `net45`/`netstandard2.0` 等低版本,再提供条件编译降级实现。
+- **禁止高版本专属 BCL API**(低版本项目):❌ `ArgumentNullException.ThrowIfNull()` → ✅ `if (x == null) throw new ArgumentNullException(nameof(x));`
+- **条件编译符号**:`NETFRAMEWORK`、`NETSTANDARD2_0`、`NETCOREAPP`、`NET5_0_OR_GREATER`、`NET6_0_OR_GREATER`、`NET8_0_OR_GREATER`
+
+---
+
+## 4. 编码规范
+
+### 4.1 类型名(关键差异)
+
+**必须**使用 .NET 正式名:`String`/`Int32`/`Boolean`/`Int64`/`Double`/`Object` 等。
+❌ **禁止**使用 C# 别名:`string`/`int`/`bool`/`long`/`double`/`object`
+
+### 4.2 命名
+
+| 成员类型 | 规则 | 示例 |
+|---------|------|------|
+| 类型/公共成员 | PascalCase | `UserService`、`GetName()` |
+| 参数/局部变量 | camelCase | `userName`、`count` |
+| 私有字段 | `_camelCase` | `_cache`、`_instance` |
+| 扩展方法类 | `xxxHelper` 或 `xxxExtensions` | `StringHelper`、`CollectionExtensions` |
+
+### 4.3 代码风格
+
+- **命名空间**:file-scoped namespace
+- **单文件**:每文件一个主要公共类型;较大平台差异使用 `partial`
+- **集合初始化**:优先使用集合表达式 `[]`,如 `List<String> Tags { get; set; } = [];`
+- **Null 条件运算符**:优先使用 `?.`/`??` 简化空值检查;**C# 14 空条件赋值 `??=`**:变量为 null 时才赋值,可显著提升可读性
+
+```csharp
+// ✅ C#14 空条件赋值(??=):为 null 时才赋值,替代 if (x == null) x = ...
+_cache ??= new MemoryCache();
+list ??= [];
+
+// ✅ if 内只有单行代码时可不加花括号(单行 if 同行或换行均可)
+if (value == null) return;
+if (key == null) throw new ArgumentNullException(nameof(key));
+
+// ✅ 语句较长时另起一行,仍不加花括号
+if (value == null)
+    throw new ArgumentNullException(nameof(value), "Value cannot be null");
+
+// ✅ 多分支单语句:不加花括号
+if (count > 0)
+    DoSomething();
+else
+    DoOther();
+
+// ✅ for/foreach/while 循环体必须保留花括号(即使单语句)
+foreach (var item in list)
+{
+    Process(item);
+}
+
+for (var i = 0; i < count; i++)
+{
+    Process(i);
+}
+
+// ✅ using 优先无花括号声明;仅需生命周期(如锁)时用弃元
+using var stream = File.OpenRead("file.txt");
+using var _ = _lock.AcquireLock();
+```
+
+### 4.4 Region 与日志
+
+较长类使用 `#region` 分段,顺序:`属性` → `静态` → `构造` → `方法` → `辅助` → **`日志`**。
+含 `ILog Log` 和 `WriteLog` 时:**必须放类末尾**,用名为"日志"的 region 包裹,不放入"辅助"。
+关键过程可使用 `Tracer?.NewSpan()` 埋点。
+
+### 4.5 文档注释
+
+- `<summary>` **必须同行闭合**:`/// <summary>获取名称</summary>`
+- 每个参数**必须有** `<param>` 标签,无论方法可见性
+- 有返回值**必须有** `<returns>`;复杂方法可增加 `<remarks>`
+- `public`/`protected` 成员必须注释;`[Obsolete]` 必须包含迁移建议
+
+### 4.6 异步与性能
+
+- 异步方法后缀 `Async`,库内部默认 `ConfigureAwait(false)`
+- 热点路径避免反射/复杂 Linq,优先手写循环/`ArrayPool<T>`/`Span`
+- 池化资源明确获取/归还,异常分支不遗失归还
+
+### 4.7 错误处理
+
+- 精准异常类型:`ArgumentNullException`/`InvalidOperationException` 等
+- TryXxx 模式:不用异常作常规分支
+- 类型转换:优先使用 `Utility` 扩展方法,完整列表:`ToInt()`/`ToLong()`/`ToDouble()`/`ToDecimal()`/`ToBoolean()`/`ToDateTime()`/`ToDateTimeOffset()`
+- 对外异常不暴露内部实现/路径
+
+---
+
+## 5. NewLife 内置工具
+
+优先使用项目内置工具而非标准库,**禁止重复造轮子**:
+
+- 字符串构建:`Pool.StringBuilder`(替代 `new StringBuilder()`)
+- 时间戳(毫秒级相对时间):`Runtime.TickCount64`;**代码计时(精确耗时测量):`Stopwatch`**
+- 类型转换:`Utility` 扩展方法 — `ToInt()`/`ToLong()`/`ToDouble()`/`ToDecimal()`/`ToBoolean()`/`ToDateTime()`/`ToDateTimeOffset()`
+- 二进制读写:`SpanReader` / `SpanWriter`(替代手动字节偏移操作)
+- 追踪埋点:`Tracer?.NewSpan()`
+
+---
+
+## 6. 防御性注释(禁止删除)
+
+代码中带有说明文字的被注释代码属于**防御性注释**,记录历史踩坑经验。**禁止删除,禁止"恢复"执行**。可补充更详细说明。
+
+```csharp
+// 曾经尝试过同步等待,但会导致线程池饥饿和死锁
+// var result = task.Result;
+
+// 不要使用 SendAsync 的无超时重载,否则会造成连接泄漏
+// await client.SendAsync(data);
+```
+
+---
+
+## 7. 工作流
+
+触发检查(第 1 节触发信号表匹配,命中则读取专用指令) → 检索(**优先复用**现有实现) → 评估(公共 API/兼容性/性能) → 方案 → 实施 → 验证 → **AskQuestions 多选确认** → [需调整则循环] → 说明
+
+- **触发检查**:开始工作前必须完成,遗漏专用指令将导致输出不符合要求
+- **实施**:完成主任务;顺带修复明显缺陷;顺带简化重复代码;保留原注释与结构
+- **验证**:代码变更必须编译通过;找到相关测试则运行;仅文档变更可跳过
+- **AskQuestions 多选确认**:使用 `vscode_askQuestions` 工具,多选询问用户是否满意;若需调整则修改后重新编译,循环至满意;确认满意后才进入下一项开发
+
+### 主动优化原则
+
+用户要求**分析/优化代码**时:
+
+| 行动 | 说明 |
+|------|------|
+| **架构梳理** | 重构不清晰的结构,让代码更易懂 |
+| **缺陷修复** | 资源泄漏、空引用、并发问题、逻辑错误 → 直接修复 |
+| **代码简化** | 提取重复代码、合并冗余判断、应用现代语法 |
+| **性能优化** | 缓存重复计算、池化高频对象、避免无用分配 |
+| **注释完善** | 补充缺失的 XML 注释和关键逻辑说明 |
+
+---
+
+## 8. 测试
+
+- 框架 xUnit;类名 `{ClassName}Tests`;方法加 `[DisplayName("中文描述意图")]`
+- 网络端口用 `0`/随机,IO 用临时目录
+- 先搜索 `{ClassName}` 引用定位测试文件,再找 `{ClassName}Tests.cs`;**未找到需说明**,不自动创建测试项目
+
+---
+
+## 9. 文档与发布
+
+### Markdown 文档
+
+**UTF-8 无 BOM**;存放 `Doc/` 目录;文件名优先中文,内容优先简体中文,避免乱码。**已有文件必须先读取再增量修改,禁止覆盖。**
+
+> 代码注释同样要求 UTF-8 无 BOM,优先简体中文。生成或编辑任何文件时须确保编码正确,防止中文乱码。
+
+### NuGet 版本
+
+| 类型 | 格式 | 示例 |
+|------|------|------|
+| 正式版 | `{主}.{子}.{年}.{月日}` | `11.9.2025.0701` |
+| 测试版 | `{主}.{子}.{年}.{月日}-beta{时分}` | `11.9.2025.0701-beta0906` |
+
+---
+
+## 10. 重要禁止项
+
+以下是 AI 容易犯但在本项目影响严重的错误:
+
+- 将 `String`/`Int32` 改为 `string`/`int`(本项目反 C# 惯例,**必须用正式名**)
+- 删除防御性注释(带说明的注释代码)
+- 删除 for/foreach/while 循环体的花括号(**循环体必须有花括号,即使只有一行**)
+- 将 `<summary>` 拆成多行
+- 擅自删除 `public`/`protected` 成员
+- 擅自新增外部 NuGet 依赖(需说明理由)
+- 仅删除空白行/注释制造"格式优化"提交
+- 虚构不存在的 API/文件/类型
+- 伪造测试结果/性能数据
+- 在热点路径添加未缓存反射/复杂 Linq
+- 输出敏感凭据/内部地址
+- 发现问题却视而不见
+- 用户要求优化时仅做注释/测试等表面工作
+- **跳过第 1 节触发检查**(命中关键词却未加载专用指令文件,是最严重的遗漏错误)
+
+---
+
+## 11. 变更说明模板
+
+```markdown
+## 概述
+做了什么 / 为什么
+
+## 影响
+- 公共 API:是/否
+- 性能影响:无/有(说明)
+
+## 兼容性
+降级策略 / 条件编译点
+
+## 风险与后续
+潜在回归 / 是否补测试
+```
+
+---
+
+## 12. Skills 技能文件
+
+`.github/skills/<name>/SKILL.md` 格式,Copilot 可自动识别并提供给用户调用。选择技能后 AI 遵循其中的最佳实践指南。
+
+**快速使用指南(usage 类)**——按需快速上手,代码示例为主:
+
+| 技能目录 | 覆盖领域 |
+|---------|---------|
+| `caching` | ICache/MemoryCache/Redis 统一缓存接口 |
+| `logging-tracing` | ILog/XTrace 日志与 ITracer/DefaultTracer 链路追踪 |
+| `networking` | NetServer/NetSession TCP/UDP/WebSocket 网络编程 |
+| `serialization` | JSON/Binary/Span/CSV 序列化 |
+| `configuration` | Config&lt;T&gt;/IConfigProvider/HttpConfigProvider 配置管理 |
+| `http-client` | ApiHttpClient 多节点 HTTP 客户端与负载均衡 |
+| `dependency-injection` | ObjectContainer/Host/Plugin/Actor 依赖注入与宿主 |
+| `timer-scheduling` | TimerX/Cron 高级定时调度 |
+| `security` | Hash/AES/SM4/RSA/JWT/TokenProvider 安全与加密 |
+| `type-conversion` | ToInt/ToBoolean/StringHelper/Pool.StringBuilder 类型转换与工具 |
+
+**深度设计指南(architecture 类)**——架构设计与代码审查场景:
+
+| 技能目录 | 覆盖领域 |
+|---------|---------|
+| `cache-provider-architecture` | ICache/ICacheProvider 设计与分布式锁 |
+| `logging-tracing-system` | ILog/ITracer 日志与链路追踪体系设计 |
+| `network-server-sessions` | NetServer/NetSession 高性能服务器架构 |
+| `network-client` | NetClient/WebClientX 网络客户端 |
+| `serialization-patterns` | 序列化方案选型与扩展 |
+| `config-provider-system` | 配置提供者架构与远程配置中心 |
+| `http-client-loadbalancer` | ApiHttpClient 多节点负载均衡设计 |
+| `dependency-injection-ioc` | ObjectContainer IoC 容器详解 |
+| `timer-scheduler` | TimerX/Cron 调度原理与高级用法 |
+| `security-crypto-patterns` | 哈希/对称/非对称加密完整模式 |
+| `utility-extensions` | 类型转换/字符串/路径/反射扩展全集 |
+
+其余技能目录(XCode/Cube/Redis/MQTT/Net/基础设施等)共 38 个,详见 `README.md`。
+
+---
+
+## 13. Agents 智能代理
+
+`.github/agents/` 目录下定义了专用 AI 代理角色,用户可在 Copilot Chat 中通过 `@` 调用。
+
+| 代理文件 | 用途 |
+|---------|------|
+| `newlife-expert.agent.md` | NewLife 组件专家:功能查询、组件推荐、编码指导 |
+| `code-review.agent.md` | 代码审查:按 NewLife 规范 8 维度检查代码 |
+| `project-init.agent.md` | 项目初始化:按模板创建新 NewLife 项目结构 |
+| `release-prep.agent.md` | 发版准备:ChangeLog/版本号/PackageReleaseNotes 全自动更新 |
+
+---
+
+(完)
Added +118 -0
diff --git a/.github/instructions/benchmark.instructions.md b/.github/instructions/benchmark.instructions.md
new file mode 100644
index 0000000..a900493
--- /dev/null
+++ b/.github/instructions/benchmark.instructions.md
@@ -0,0 +1,118 @@
+---
+applyTo: "**/Benchmark/**"
+---
+
+# 性能测试指令
+
+适用于性能测试、压力测试、基准测试、BenchmarkDotNet 相关任务。
+
+---
+
+## 1. 项目结构
+
+- 基准测试统一放在 `Benchmark/` 项目,按主题分子目录(如 `PacketBenchmarks/`、`CacheBenchmarks/`)
+- 入口 `Program.cs` 使用 `BenchmarkSwitcher` 模式,**不要修改**
+- TFM 使用最新稳定版,`<LangVersion>latest</LangVersion>`
+
+## 2. 代码规范
+
+遵循主指令全部编码规范(类型名用 `String`/`Int32` 等、file-scoped namespace),另有以下补充:
+
+- **命名空间**:`Benchmark.{主题}Benchmarks`
+- **类名**:`{被测类型}Benchmark` 或 `{被测主题}Benchmark`
+- **必须标注** `[MemoryDiagnoser]` 和 `[SimpleJob]`(需调整迭代次数时用 `[SimpleJob(iterationCount: N)]`)
+- **方法描述**:`[Benchmark(Description = "中文描述")]`,方便报告阅读
+- **参数化**:用 `[Params]` 或 `[ParamsSource]` 控制数据规模
+- **初始化 / 清理**:分别放 `[GlobalSetup]` 和 `[GlobalCleanup]`
+- **分组**:同类测试用 `#region` 分组
+- **多线程并发**:动态线程数包含 CPU 核心数,推荐模板:
+
+```csharp
+public static IEnumerable<Int32> ThreadCounts
+{
+    get
+    {
+        var cores = Environment.ProcessorCount;
+        var set = new SortedSet<Int32> { 1, 4, 8, 32 };
+        set.Add(cores);
+        return set;
+    }
+}
+
+[ParamsSource(nameof(ThreadCounts))]
+public Int32 ThreadCount { get; set; }
+```
+
+## 3. 运行要求
+
+- 必须以 **Release 模式**运行,获取有代表性的峰值数据
+- 运行全部:`dotnet run -c Release`
+- 运行指定类:`dotnet run -c Release -- --filter *ClassName*`
+- ❌ 禁止在 Debug 模式下采集数据写入报告
+
+## 4. 测试维度
+
+- **并发维度**:单线程 + 多线程(多线程含与当前 CPU 核心数相同的并发数)
+- **操作维度**:单一操作 + 批量操作
+
+## 5. 常见错误
+
+- ❌ 在 `[Benchmark]` 方法内做初始化(应放 `[GlobalSetup]`)
+- ❌ 忽略返回值导致 JIT 死码消除(确保返回或赋值给字段)
+- ❌ 手动 `Stopwatch` 计时(BDN 自动处理)
+- ❌ `using` 的 `Dispose` 开销混入测量(仅在测试 Dispose 本身时才包含)
+
+## 6. 报告存放
+
+`Doc/Benchmark/{测试主题}性能测试.md`(UTF-8 无 BOM)
+
+## 7. 报告结构(顺序固定,精简为主)
+
+1. **性能概览**(一句话用途 + 核心结论,3~5 条要点,每条一句话)
+2. **测试环境**(CPU / OS / Runtime,代码块 3~4 行即可)
+3. **测试结果**(BDN 原始表格,保留 Mean / Error / StdDev / Allocated)
+4. **结果分析**(见下方约束)
+5. **瓶颈与优化建议**(见第 8 节,仅列有数据支撑的瓶颈)
+
+### 7.1 结果分析约束
+
+结果分析是对 BDN 数据的**提炼**,不是重新排列。遵循以下规则:
+
+- **禁止重复制表**:不要把 BDN 数据换个单位(如 ops/s)再列一张完整表格;如需标注业务指标,在正文中用"XXX 操作约 N M ops/s"一笔带过
+- **对比用文字而非新表**:横向/纵向对比直接写结论("ArrayPacket 构造比 OwnerPacket 快 ~670x,Slice 零分配"),不为每个对比维度单独建表
+- **仅在对比维度 ≥3 且差异显著时**才建一张对比表,且最多一张
+- **总量控制**:结果分析文字不超过 BDN 原始表格总行数的 1/3
+
+### 7.2 篇幅控制
+
+- 分析 + 瓶颈部分的文字行数 ≤ 数据表格行数(含表头)
+- 无需为每个数字都单独解读;读者能从原表看出的趋势不必复述
+
+## 8. 瓶颈与优化建议规范
+
+### 8.1 撰写原则
+
+- **数据驱动**:所有结论必须有 BDN 实测数据支撑,**禁止无数据臆测**,没有 profiler 数据时不编造 ns 级拆解
+- **量化表达**:用"快 X 倍"、"省 Y%"、"降 Z B/op",避免"显著""明显"等模糊词
+- **可操作**:指明具体修改位置和方案,不泛泛建议
+- **宁少勿凑**:只列真正有影响的瓶颈(通常 1~3 个),不为凑数列 P3 级微小问题
+
+### 8.2 瓶颈表格(唯一模板,合并展示)
+
+用一张表汇总,不再拆分多张表:
+
+```markdown
+| 优先级 | 瓶颈 | 现象(实测数据) | 优化方向 | 预期收益 |
+|--------|------|----------------|---------|---------|
+| P0 | {名称} | {BDN 数据描述} | {方案} | {速度/内存预估} |
+| P1 | {名称} | {BDN 数据描述} | {方案} | {速度/内存预估} |
+```
+
+- **P0**:影响核心吞吐或 >30% 性能损失,必须优化
+- **P1**:影响扩展性或有明显内存压力,建议优化
+- **P2**:次要瓶颈,可选优化(仅在确有数据支撑时列出)
+- 同级按影响程度降序;无明显瓶颈时写"未发现显著瓶颈"即可
+
+### 8.3 补充说明(可选)
+
+表格之后可对 P0/P1 瓶颈各写 2~3 句补充根因和方案细节,**不要求也不鼓励**对每个瓶颈展开长篇分析。
Added +77 -0
diff --git a/.github/instructions/caching.instructions.md b/.github/instructions/caching.instructions.md
new file mode 100644
index 0000000..039737a
--- /dev/null
+++ b/.github/instructions/caching.instructions.md
@@ -0,0 +1,77 @@
+---
+applyTo: "**/Caching/**"
+---
+
+# 缓存模块开发指令
+
+适用于 `NewLife.Caching` 命名空间下的缓存系统开发。
+
+---
+
+## 1. 架构分层
+
+| 层级 | 接口/类 | 职责 |
+|------|---------|------|
+| 统一接口 | `ICache` | 全部缓存操作的标准契约 |
+| 内存实现 | `MemoryCache` | 单机内存缓存,LRU 淘汰 |
+| 分布式实现 | `Redis`(独立包 NewLife.Redis) | 跨进程/跨机器缓存 |
+| 提供者 | `ICacheProvider` / `CacheProvider` | 管理全局缓存 + 本地缓存 + 队列 + 分布式锁 |
+
+**重要原则**:所有缓存操作面向 `ICache` 接口编程,禁止直接依赖具体实现类。
+
+---
+
+## 2. ICache 接口规范
+
+### 2.1 方法签名约定
+
+- `expire` 参数统一使用 `Int32` 秒数,`-1` 表示使用缓存默认过期时间
+- `Remove` 支持 `*` 通配符模糊匹配
+- `Add` 已存在时不更新(返回 `false`),`Set` 总是覆盖
+- `Replace` 原子替换并返回旧值
+- `GetOrAdd` 缓存未命中时执行回调
+
+### 2.2 高级操作
+
+- `Increment`/`Decrement` 原子递增递减,返回新值
+- `IncrementWithTtl`/`DecrementWithTtl` 返回 `(Value, Ttl)` 元组
+- `AcquireLock` 返回 `IDisposable?`,配合 `using` 使用,获取失败返回 `null`
+- 集合操作 `GetList`/`GetDictionary`/`GetQueue`/`GetStack`/`GetSet` 返回接口包装
+
+---
+
+## 3. MemoryCache 开发规范
+
+- 构造无参,通过属性配置:`Capacity`(默认 10 万)、`Period`(清理周期秒数)
+- 使用 `MemoryCache.Instance` 获取全局单例,勿手动 `new` 全局使用
+- `KeyExpired` 事件可用于过期回调,勿在回调中执行重操作
+- MemoryCache 的过期由后台定时器驱动,非精确过期
+
+---
+
+## 4. ICacheProvider 规范
+
+- `Cache` 属性为跨进程缓存(默认 MemoryCache,生产环境替换为 Redis)
+- `InnerCache` 属性为进程内本地缓存(始终是 MemoryCache)
+- `GetQueue` 的 `group` 参数:`null` 返回简单队列,非空返回完整消费组队列
+- `AcquireLock` 为分布式锁,超时时间 `msTimeout` 单位毫秒
+
+---
+
+## 5. 扩展实现规范
+
+新增 ICache 实现时:
+
+- **必须继承** `Cache` 基类(提供默认的批量操作实现)
+- 批量操作(`GetAll`/`SetAll`)应重写为原生批量调用,而非循环单条
+- `Init` 方法用于从连接字符串初始化,格式自定义但需文档说明
+- `Dispose` 必须释放底层连接资源
+
+---
+
+## 6. 常见错误
+
+- ❌ 缓存 key 使用用户输入未做校验(注入风险)
+- ❌ `AcquireLock` 返回 `null` 时未处理(锁获取失败应有降级逻辑)
+- ❌ 在循环内逐条 `Get`/`Set`(应使用 `GetAll`/`SetAll` 批量操作)
+- ❌ 过期时间设为 0(0 表示立即过期,应使用 `-1` 表示默认)
Added +108 -0
diff --git a/.github/instructions/configuration.instructions.md b/.github/instructions/configuration.instructions.md
new file mode 100644
index 0000000..c1350aa
--- /dev/null
+++ b/.github/instructions/configuration.instructions.md
@@ -0,0 +1,108 @@
+---
+applyTo: "**/Configuration/**"
+---
+
+# 配置系统模块开发指令
+
+适用于 `NewLife.Configuration` 命名空间下的配置系统开发。
+
+---
+
+## 1. 架构分层
+
+| 层级 | 类型 | 说明 |
+|------|------|------|
+| 统一接口 | `IConfigProvider` | 标准配置操作契约 |
+| 泛型基类 | `Config<T>` | 强类型配置单例 |
+| 本地实现 | `JsonConfigProvider`、`XmlConfigProvider`、`IniConfigProvider` | 文件配置 |
+| 远程实现 | `HttpConfigProvider`、`ApolloConfigProvider` | 配置中心适配 |
+| 命令行 | `CommandParser` | 命令行参数解析 |
+| 节点模型 | `IConfigSection` | 树状配置节点 |
+
+---
+
+## 2. Config\<T\> 使用规范
+
+### 2.1 定义方式
+
+```csharp
+public class MySetting : Config<MySetting>
+{
+    public String Name { get; set; } = "默认值";
+    public Int32 Port { get; set; } = 8080;
+
+    protected override void OnLoaded()
+    {
+        // 加载后校验/修正
+        if (Port <= 0) Port = 8080;
+    }
+}
+```
+
+### 2.2 使用方式
+
+- `MySetting.Current` — 单例访问,首次访问自动从配置文件加载
+- `MySetting.Current.Save()` — 保存修改到文件
+- `IsNew` 属性判断是否首次创建(配置文件不存在时为 `true`)
+
+### 2.3 Provider 覆盖
+
+```csharp
+// 使用 HTTP 配置中心
+MySetting.Provider = new HttpConfigProvider { Server = "http://config-center" };
+```
+
+---
+
+## 3. IConfigProvider 开发规范
+
+### 3.1 核心方法
+
+- `LoadAll()` / `SaveAll()` — 全量加载/保存
+- `Load<T>()` — 加载为强类型对象
+- `Save<T>(model)` — 保存强类型对象
+- `Bind<T>(model, autoReload)` — 绑定对象并自动重载
+- `Changed` 事件 — 配置变更通知
+- 索引器 `this[key]` 支持冒号分隔的多级 key:`"Database:ConnectionString"`
+
+### 3.2 节点操作
+
+- `Root` 属性为根节点(`IConfigSection`)
+- `GetSection(key)` 获取子节点
+- 节点支持树状结构,子节点通过 `Childs` 属性访问
+
+---
+
+## 4. HttpConfigProvider 规范
+
+- `Server` — 配置中心地址
+- `AppId` / `Secret` — 应用标识和密钥
+- `Scope` — 作用域(如环境名)
+- `Period` — 轮询间隔秒数(默认 60)
+- `CacheLevel` — 本地缓存级别(加密/明文/不缓存)
+- `Action` — API 路径(默认 `Config/GetAll`,适配星尘配置中心)
+- 适配 Apollo 时使用 `ApolloConfigProvider`
+
+---
+
+## 5. CommandParser 规范
+
+```csharp
+var parser = new CommandParser { IgnoreCase = true };
+var args = parser.Parse(Environment.GetCommandLineArgs());
+// --port 8080 → args["port"] = "8080"
+// -v → args["v"] = null
+```
+
+- `TrimStart` 默认 `true`,自动去除 `--` / `-` 前缀
+- `TrimQuote` 去除值两端引号
+- `Split` 将命令行字符串分割为参数数组
+
+---
+
+## 6. 常见错误
+
+- ❌ 在构造函数中访问 `Config<T>.Current`(可能触发递归加载)
+- ❌ 手动 `new` Config 对象而非使用 `Current` 单例
+- ❌ `HttpConfigProvider` 未设置 `AppId`(配置中心会拒绝)
+- ❌ `Bind` 后修改对象属性未调用 `Save()`(变更不会持久化)
Added +333 -0
diff --git a/.github/instructions/development.instructions.md b/.github/instructions/development.instructions.md
new file mode 100644
index 0000000..708f6cb
--- /dev/null
+++ b/.github/instructions/development.instructions.md
@@ -0,0 +1,333 @@
+---
+applyTo: "Doc/**"
+---
+
+# AI 辅助开发流程指令
+
+适用于新建应用系统、新增功能模块、需求整理、架构设计等研发全流程任务。
+
+---
+
+## 1. 流程总览
+
+```
+需求整理 → 需求评审与拆分 → 技术方案设计 → 任务分解 → 迭代开发 → 集成验证 → 验收回顾
+```
+
+**核心原则**:大需求必须拆小,每个迭代交付可验证的最小功能单元。禁止"一次性全做完"。
+
+---
+
+## 2. 各阶段规范
+
+### 2.1 需求整理
+
+用户提供原始描述(口语化、列表、草稿均可),AI 整理为以下结构(需求 + 功能清单 + 验收 合为一个文件):
+
+```markdown
+# {项目/模块名}需求
+
+## 1. 背景与目标
+- 为什么做(痛点/动机)
+- 做到什么程度算成功(可衡量目标)
+
+## 2. 用户角色
+| 角色 | 说明 | 核心诉求 |
+|------|------|---------|
+
+## 3. 功能需求
+### 3.1 {功能模块名}
+- **描述**:一句话说明
+- **用户故事**:作为{角色},我希望{操作},以便{价值}
+- **验收条件**(AC):
+  - [ ] 条件 1
+  - [ ] 条件 2
+- **优先级**:Must / Should / Could / Won't
+
+## 4. 非功能需求
+- 性能 / 安全 / 兼容性(三项必填)
+
+## 5. 边界与约束
+- 不做什么(明确排除项)
+- 已知限制 / 技术债务
+
+## 6. 功能清单与迭代计划
+(需求评审拆分后填写,见 2.2)
+
+## 7. 验收记录
+(开发完成后填写,见 2.7)
+
+## 8. 术语表
+| 术语 | 定义 |
+|------|------|
+```
+
+**规则**:每个功能必须有 AC,无 AC 不可进入开发;优先级用 MoSCoW 四级;非功能需求至少覆盖性能、安全、兼容性。
+
+### 2.2 需求评审与拆分
+
+按**纵向切片**(端到端功能,非技术层)拆分,遵循 INVEST 原则,单个功能单元 ≤ 1-2 天工作量,有依赖须标注。
+
+写入需求文档「6. 功能清单与迭代计划」:
+
+```markdown
+## 6. 功能清单与迭代计划
+
+### 迭代 1:{主题}(Must 级别)
+| 编号 | 功能点 | 验收条件 | 前置依赖 | 预估工作量 |
+|------|--------|---------|---------|----------|
+| F001 | xxx | AC1, AC2 | 无 | 0.5d |
+| F002 | xxx | AC1 | F001 | 1d |
+
+### 迭代 2:{主题}(Should 级别)
+...
+```
+
+### 2.3 技术方案设计
+
+```markdown
+# {项目/模块名}架构
+
+## 1. 架构概览
+## 2. 数据模型
+## 3. 接口设计
+| 接口 | 方法 | 路径/签名 | 入参 | 出参 | 说明 |
+|------|------|----------|------|------|------|
+## 4. 技术选型
+| 领域 | 选型 | 理由 |
+|------|------|------|
+## 5. 关键设计决策
+| 决策点 | 方案 | 备选方案 | 选择理由 |
+|--------|------|---------|---------|
+## 6. 任务分解
+(见 2.4)
+## 7. 风险与缓解
+| 风险 | 影响 | 缓解措施 |
+|------|------|---------|
+```
+
+**规则**:优先使用 NewLife 已有组件(XCode、Remoting、Stardust 等);数据模型考虑 XCode 实体规范;接口遵循现有 API 风格。
+
+### 2.4 任务分解
+
+单个任务 = 一次 AI 对话可完成的工作量(编码 + 测试 + 自测通过)。写入技术方案「6. 任务分解」:
+
+```markdown
+### 任务 T001:{动词 + 目标}
+- **对应功能**:F001
+- **输入**:前置条件 / 已有代码
+- **产出**:新增/修改哪些文件
+- **验收**:怎样算完成
+```
+
+**批次编排**(用于自治模式,见第 6 节):按依赖关系编排为批次,每批次 5-8 个任务,同批次内尽量无相互依赖,基础设施任务排在前面,每批次结束设 `[检查点 N]`,标注本批次产出是下批次哪些输入。
+
+### 2.5 迭代开发
+
+流程:`理解任务 → 检索现有实现 → 编码 → 编译通过 → 通知用户测试 → AskQuestions 多选确认满意度 → [需调整则调整重复] → 进入下一项`
+
+- 严格遵守主指令编码规范,每个任务必须编译通过
+- **每完成一个功能项后,必须执行以下步骤**:
+  1. **编译**:运行编译命令,确认无错误后再推进
+  2. **通知测试**:向用户说明本次完成的内容、可测试的入口和测试要点,让用户自行验证
+  3. **满意度确认**:使用 `vscode_askQuestions` 工具,以**多选**方式询问用户反馈,选项示例:
+     - ✅ 满意,继续下一项
+     - 🔧 需要小调整(请说明)
+     - ❌ 需要较大返工
+  4. **按需调整**:用户选择调整时,修改代码并重新编译,循环至用户满意
+  5. **推进下一项**:用户确认满意后,才进入下一功能项开发
+- 常规模式:遇歧义暂停确认;自治模式:检查点后批量询问(见第 6 节)
+- 有依赖按顺序执行,不跳跃
+
+### 2.6 集成验证
+
+全部编译通过 → 单元测试通过 → 端到端主流程走通 → 异常场景覆盖 → 性能符合预期
+
+### 2.7 验收与回顾
+
+对照需求文档逐条验收,写入「7. 验收记录」:
+
+```markdown
+## 7. 验收记录
+
+### 功能验收
+| 编号 | 功能点 | 验收条件 | 状态 | 备注 |
+|------|--------|---------|------|------|
+
+### 遗留问题
+| 问题 | 影响 | 后续计划 |
+|------|------|---------|
+
+### 经验总结
+- 做得好的 / 待改进的
+```
+
+---
+
+## 3. 文档存放规范
+
+全流程仅产出 **2 个文档**,扁平存放在 `Doc/` 下:
+
+| 文档 | 文件名 | 包含内容 |
+|------|--------|--------|
+| 需求文档 | `Doc/{项目名}需求.md` | 背景目标 + 功能需求 + 功能清单 + 验收记录 + 术语表 |
+| 技术方案 | `Doc/{项目名}架构.md` | 架构 + 数据模型 + 接口 + 技术选型 + 任务分解 + 风险 |
+
+UTF-8 无 BOM;已有文件必须先读取再增量修改,禁止覆盖;各阶段产出追加到对应章节,不新建文件。
+
+---
+
+## 4. AI 协作要点
+
+### 4.1 阶段切换
+
+| 用户说 | 进入阶段 |
+|--------|---------|
+| "整理需求"/"写需求" | 2.1 需求整理 |
+| "拆分"/"拆解"/"排优先级" | 2.2 需求评审与拆分 |
+| "技术方案"/"架构设计"/"怎么实现" | 2.3 技术方案设计 |
+| "开始开发"/"写代码"/"实现 F001" | 2.5 迭代开发 |
+| "全部搞完"/"批量开发"/"自治模式"/"一次性做完"/"继续处理"/"接着做" | 第 6 节自治批处理 |
+| "验收"/"检查完成情况" | 2.7 验收与回顾 |
+| 一大段描述未指定阶段 | 默认 2.1 需求整理 |
+
+### 4.2 主动引导
+
+每阶段完成后提示下一步:需求整理完 → 拆分? → 技术方案? → 任务分解 → 开发?
+
+### 4.3 大需求防护
+
+功能点 > 5 / 实体 > 3 / 跨 2 层以上 / 描述 > 500 字 → 必须先拆分再开发。
+
+---
+
+## 5. 常见反模式(禁止)
+
+- ❌ 跳过需求直接编码
+- ❌ 一次性输出所有代码(大需求必须拆迭代或使用自治模式)
+- ❌ 需求文档没有验收条件
+- ❌ 功能拆分按技术层而非用户价值
+- ❌ 任务没有完成标准就开始编码
+- ❌ 完成后不做验收对照
+- ❌ 自治模式下遇阻塞问题死等用户(应记录跳过,继续后续)
+- ❌ 自治模式下做需要人工决策的架构变更(应记录待确认,现有方案兜底)
+- ❌ 跨批次不做编译验证
+
+---
+
+## 6. 自治批处理模式
+
+架构师已确认需求和技术方案后,AI 按任务清单自主执行,最小化人工介入。
+
+### 6.1 进入条件(全部满足)
+
+- [ ] 需求文档已完成且架构师已确认
+- [ ] 技术方案已完成且架构师已确认
+- [ ] 任务已分解并编排为批次
+- [ ] 用户明确触发("全部搞完"/"批量开发"/"自治模式"等)
+
+未满足时提示缺少哪些条件。
+
+### 6.2 计划结构与循环刷新
+
+AI 用 plan 工具创建层次化计划,「前置刷新 + 批次执行」循环:
+
+```
+1. [前置] 读取需求文档与技术方案
+2. [前置] 读取任务清单与进度状态
+3. [前置] 全量编译确认基线
+4. [前置] 识别可并行的批次组
+5. [批次1] 执行 T001-T005(子步骤展开各任务)
+6. [检查点1] 输出批次1报告
+7. [刷新] 重读需求文档与技术方案
+8. [批次2] 执行 T006-T010
+9. [检查点2] 输出批次2报告
+...(循环:刷新 → 批次 → 检查点)
+N-2. [后置] 全量编译与集成验证
+N-1. [后置] 补完被跳过的任务
+N.   [后置] 生成验收报告
+```
+
+**要点**:
+- 主步骤 15-25 个(不超过 30),子步骤展开具体任务仅供参考不单独追踪
+- 刷新步骤穿插在每两个批次之间,`get_file` 重读文档对抗上下文漂移
+- 用 `update_plan_progress` 跟踪主步骤,不为每个子任务调用
+- 无依赖的批次可合并为一个主步骤执行,有依赖的必须顺序执行
+
+### 6.3 执行协议
+
+| 情况 | 处理方式 |
+|------|----------|
+| 任务明确无歧义 | 直接执行:编码 → 编译 → 测试 |
+| 小歧义可合理推断 | 执行并在问题日志记录推断依据 |
+| 重大歧义或多种等价方案 | 标记 `⏸️ 待确认`,跳过 |
+| 前置任务被跳过 | 标记 `⏸️ 依赖阻塞:T0xx`,跳过 |
+| 编译失败短时间无法修复 | 回滚改动,记录并跳过 |
+| 涉及公共 API / 架构变更 | 标记 `⏸️ 需架构师决策`,兜底或跳过 |
+
+### 6.4 检查点报告
+
+每批次完毕后输出:
+
+```markdown
+## 检查点 N 报告
+
+### 完成情况
+| 任务 | 状态 | 说明 |
+|------|------|------|
+| T001 | ✅ 完成 | |
+| T003 | ⏸️ 跳过 | 需确认:xxx |
+
+### 编译状态
+- 全量编译:✅ 通过 / ❌ 失败(错误详情)
+
+### 问题日志
+| 编号 | 类型 | 描述 | 影响任务 | 建议方案 |
+|------|------|------|---------|----------|
+
+### 统计
+- 本批次 N 个,完成 X 个,跳过 Y 个
+- 累计进度:已完成 X / 总计 Z(XX%)
+- 上下文预估:{已处理任务数} / {建议上限}
+```
+
+### 6.5 用户回复与继续
+
+架构师回来后:AI 呈现检查点报告 → 架构师批量回复问题("Q001 OK,Q002 选 A")→ AI 修正推断 + 执行跳过的任务 + 继续下批次 → 循环至完成。
+
+触发词:"继续"/"继续处理"/"回复完了"/"接着做"
+
+### 6.6 质量护栏(自动执行)
+
+编译门禁(失败即修复或回滚)/ 命名与技术方案一致 / 编码规范严格遵守 / 新增代码前搜索现有实现避免重复 / 不擅自引入新 NuGet 包
+
+### 6.7 会话边界处理
+
+每个检查点后、连续完成 15+ 任务后、搜索结果不准确时 → 评估是否需要新会话。
+
+**新会话续接模板**:
+
+```
+我们在做 {项目名} 的自治批处理开发。
+- 需求文档:Doc/{项目名}需求.md
+- 技术方案:Doc/{项目名}架构.md
+- 当前进度:批次 N 已完成,从批次 N+1 的 T0xx 开始继续
+- 待解决问题:{问题编号}
+请读取以上文档,从 T0xx 继续执行,自治模式。
+```
+
+上下文即将耗尽时 AI 主动提醒并生成上述模板。新会话前 4 步仍为前置刷新,已完成批次直接标记完成。
+
+### 6.8 批次大小建议
+
+| 复杂度 | 批次大小 |
+|--------|---------|
+| 简单(CRUD) | 8-10 |
+| 中等(业务逻辑) | 5-7 |
+| 复杂(算法、并发) | 3-5 |
+
+单会话上限:3-4 个批次(约 15-25 个任务)。
+
+---
+
+(完)
Added +573 -0
diff --git a/.github/instructions/net.instructions.md b/.github/instructions/net.instructions.md
new file mode 100644
index 0000000..ba7509b
--- /dev/null
+++ b/.github/instructions/net.instructions.md
@@ -0,0 +1,573 @@
+---
+applyTo: "**/Net/**"
+---
+
+# 网络编程指令
+
+适用于基于 `NewLife.Net` 的网络服务器(`NetServer`)和客户端(`ISocketClient`)开发任务。
+
+---
+
+## 1. 架构概览
+
+NewLife 网络框架分为两层:
+
+| 层级 | 服务端 | 客户端 | 说明 |
+|------|--------|--------|------|
+| **应用层** | `NetServer` / `NetServer<TSession>` | — | 管理监听、会话生命周期、管道 |
+| **传输层** | `TcpServer` / `UdpServer` | `TcpSession` / `UdpServer`(客户端模式) | 底层 Socket 收发 |
+| **会话** | `NetSession` / `NetSession<TServer>` | — | 每个连接对应一个会话,业务逻辑入口 |
+| **管道** | `IPipeline` + `IPipelineHandler` | 同左 | 编解码、粘包拆包、消息匹配 |
+
+**关键接口**:
+- `ISocketClient` — 客户端连接接口(Open/Close/Send/Receive)
+- `ISocketRemote` — 远程通信接口(Send/Receive/SendMessageAsync)
+- `INetSession` — 网络会话接口(服务端每个连接的业务处理单元)
+- `INetHandler` — 网络数据处理器接口(Init/Process)
+
+---
+
+## 2. 服务端开发规范
+
+### 2.1 基本模式
+
+推荐使用泛型 `NetServer<TSession>` + 自定义 `NetSession` 子类:
+
+```csharp
+/// <summary>自定义网络服务器</summary>
+class MyServer : NetServer<MySession> { }
+
+/// <summary>自定义会话,每个客户端连接对应一个实例</summary>
+class MySession : NetSession<MyServer>
+{
+    /// <summary>客户端连接</summary>
+    protected override void OnConnected()
+    {
+        base.OnConnected();
+        WriteLog("客户端已连接 {0}", Remote);
+    }
+
+    /// <summary>收到客户端数据</summary>
+    protected override void OnReceive(ReceivedEventArgs e)
+    {
+        base.OnReceive(e);
+        // 业务处理
+    }
+
+    /// <summary>客户端断开</summary>
+    protected override void OnDisconnected(String reason)
+    {
+        base.OnDisconnected(reason);
+    }
+}
+```
+
+### 2.2 服务器启动配置
+
+```csharp
+var server = new MyServer
+{
+    Port = 8080,                              // 监听端口,0 表示随机
+    ProtocolType = NetType.Tcp,               // Tcp/Udp/Unknown(同时监听)
+    // AddressFamily = AddressFamily.InterNetwork, // 仅IPv4,默认同时IPv4+IPv6
+    ServiceProvider = provider,               // 依赖注入
+    Log = XTrace.Log,                         // 应用日志
+    SessionLog = XTrace.Log,                  // 会话日志
+    Tracer = tracer,                          // APM 追踪
+#if DEBUG
+    SocketLog = XTrace.Log,                   // Socket 层日志(仅调试)
+    LogSend = true,
+    LogReceive = true,
+#endif
+};
+server.Start();
+```
+
+### 2.3 会话生命周期
+
+```
+连接建立 → OnConnected() → OnReceive()... → OnDisconnected(reason) → Dispose()
+```
+
+- **OnConnected**:初始化会话状态、发送欢迎消息
+- **OnReceive**:核心业务处理入口,`e.Packet` 为原始数据,`e.Message` 为管道解码后的消息
+- **OnDisconnected**:清理资源、记录日志,`reason` 包含断开原因
+- 会话内可通过 `ServiceProvider` 获取 Scoped 服务
+
+### 2.4 服务端发送数据
+
+| 方法 | 说明 |
+|------|------|
+| `Send(IPacket)` | 直接发送原始数据,不经过管道 |
+| `Send(String)` | 发送字符串,默认 UTF-8 |
+| `Send(ReadOnlySpan<Byte>)` | 高性能发送 |
+| `SendMessage(Object)` | 通过管道编码后发送,不等待响应 |
+| `SendReply(Object, ReceivedEventArgs)` | 发送响应消息,与请求关联(用于 StandardCodec 等协议) |
+| `SendMessageAsync(Object)` | 通过管道发送并等待响应 |
+
+### 2.5 群发
+
+```csharp
+// 群发数据给所有在线客户端
+await server.SendAllAsync(data);
+
+// 带过滤条件群发
+await server.SendAllAsync(data, session => session.ID > 100);
+
+// 群发管道消息
+server.SendAllMessage(message, session => session["VIP"] is true);
+```
+
+群发要求 `UseSession = true`(默认开启)。
+
+### 2.6 事件模式(简单场景)
+
+不需要自定义会话时,可直接使用事件:
+
+```csharp
+var server = new NetServer { Port = 8080 };
+server.Received += (sender, e) =>
+{
+    if (sender is INetSession session)
+        session.Send(e.Packet);  // Echo
+};
+server.Start();
+```
+
+---
+
+## 3. 客户端开发规范
+
+### 3.1 创建客户端
+
+通过 `NetUri.CreateRemote()` 扩展方法创建:
+
+```csharp
+// TCP 客户端
+var client = new NetUri("tcp://127.0.0.1:8080").CreateRemote();
+
+// UDP 客户端
+var client = new NetUri("udp://127.0.0.1:8080").CreateRemote();
+
+// WebSocket 客户端
+var client = new NetUri("ws://127.0.0.1:8080/path").CreateRemote();
+```
+
+`CreateRemote` 根据协议自动返回 `TcpSession` / `UdpServer` / `WebSocketClient`。
+
+### 3.2 客户端使用
+
+```csharp
+var uri = new NetUri("tcp://127.0.0.1:8080");
+var client = uri.CreateRemote();
+client.Log = XTrace.Log;
+client.Open();
+
+// 发送原始数据(不经过管道)
+client.Send("Hello");
+
+// 事件驱动接收
+client.Received += (sender, e) =>
+{
+    // e.Packet 原始数据,e.Message 管道解码后的消息
+};
+
+// 或同步/异步接收
+using var pk = client.Receive();
+using var pk = await client.ReceiveAsync(cancellationToken);
+
+client.Close("完成");  // 或 client.Dispose()
+```
+
+### 3.3 请求-响应模式(需要管道编解码器)
+
+```csharp
+var client = new NetUri("tcp://127.0.0.1:8080").CreateRemote();
+client.Add<StandardCodec>();
+client.Open();
+
+var response = await client.SendMessageAsync(payload, cancellationToken);  // 等待响应
+client.SendMessage(message);  // 不等待响应
+```
+
+### 3.4 SSL/TLS
+
+```csharp
+// 服务端 SSL
+var server = new NetServer
+{
+    Port = 443,
+    SslProtocol = SslProtocols.Tls12,
+    Certificate = new X509Certificate2("server.pfx", "password"),
+};
+
+// 客户端 SSL(自动根据端口判断,或手动指定)
+var client = new NetUri("tcp://host:443").CreateRemote();
+if (client is TcpSession tcp)
+{
+    tcp.SslProtocol = SslProtocols.Tls12;
+    // tcp.Certificate = cert;  // 客户端证书(如果服务端要求)
+}
+```
+
+---
+
+## 4. 管道与编解码器
+
+### 4.1 管道机制
+
+管道(`IPipeline`)是处理器链,Read/Write 返回值作为下一个处理器的输入,返回 `null` 截断管道:
+
+```
+接收:Socket → [Codec1.Read] → [Codec2.Read] → FireRead → OnReceive
+发送:SendMessage → [Codec2.Write] → [Codec1.Write] → FireWrite → Socket
+```
+
+Open 正序传播,Close 逆序传播。先添加的在底层(靠近 Socket),后添加的在上层(靠近业务)。
+
+### 4.2 内置编解码器
+
+| 编解码器 | 基类 | 说明 | 典型场景 |
+|---------|------|------|---------|
+| `StandardCodec` | `MessageCodec<IMessage>` | 4字节头部(Flag+Seq+Length),支持请求-响应匹配 | 自定义 RPC 协议 |
+| `LengthFieldCodec` | `MessageCodec<IPacket>` | 长度字段头部,可配置偏移和大小 | MQTT、通用二进制协议 |
+| `JsonCodec` | `Handler` | JSON 文本编解码,不处理粘包 | 文本协议(通常与 StandardCodec 级联) |
+| `SplitDataCodec` | `Handler` | 分隔符拆包(默认 `\r\n`) | 文本行协议 |
+| `WebSocketCodec` | `Handler` | WebSocket 帧编解码 | WebSocket 通信 |
+
+### 4.3 添加编解码器
+
+```csharp
+// 服务端添加
+server.Add<StandardCodec>();
+
+// 客户端添加
+client.Add<StandardCodec>();
+
+// 多层管道级联(按添加顺序组成链)
+server.Add<StandardCodec>();  // 底层:粘包拆包 + 请求响应匹配
+server.Add<JsonCodec>();      // 上层:JSON 编解码
+```
+
+### 4.4 StandardCodec 请求-响应
+
+StandardCodec 使用 `DefaultMessage`,包含 Flag(1字节)、Sequence(1字节)、Length(2字节),
+支持自动序列号分配和请求-响应匹配。
+
+```csharp
+// 服务端 Echo 示例
+server.Add<StandardCodec>();
+server.Received += (sender, e) =>
+{
+    if (sender is INetSession session && e.Message is IPacket pk)
+        session.SendReply(pk, e);  // 使用 SendReply 关联请求上下文
+};
+
+// 客户端请求-响应
+client.Add<StandardCodec>();
+var response = await client.SendMessageAsync(payload);
+```
+
+### 4.5 基类选择
+
+| 基类 | 适用场景 | 典型代表 |
+|------|---------|---------|
+| `MessageCodec<T>` | 需要粘包拆包和/或请求-响应匹配(内置 `IMatchQueue`、`Encode`/`Decode`) | `StandardCodec`、`LengthFieldCodec` |
+| `Handler` | 简单转换、帧协议、文本协议(轻量,仅 `Read`/`Write`/`Open`/`Close`) | `JsonCodec`、`SplitDataCodec`、`WebSocketCodec` |
+
+### 4.6 编解码器设计规范
+
+#### 4.6.1 粘包拆包(PacketCodec 模式)
+
+TCP 是字节流协议,必须处理粘包拆包。统一模式(完整实现见 4.7 模板):
+
+1. 每个连接独立的 `PacketCodec` 实例,存储在 `ss["Codec"]` 中
+2. 通过 `GetLength2` 委托告诉 `PacketCodec` 如何计算完整帧长度
+3. `PacketCodec.Parse()` 返回完整帧列表,自动缓存不完整数据
+
+**`GetLength2` 规范**(签名 `Int32 GetLength(ReadOnlySpan<Byte> span)`):返回帧完整长度(含头部),数据不足时返回 `0`。
+
+```csharp
+public static Int32 GetLength(ReadOnlySpan<Byte> span)
+{
+    if (span.Length < 4) return 0;
+    var reader = new SpanReader(span) { IsLittleEndian = true };
+    reader.Advance(2);
+    return 4 + reader.ReadUInt16();  // 头部4字节 + 负载长度
+}
+```
+
+#### 4.6.2 编码与内存管理
+
+- **`ExpandHeader(size)`**:编码时优先复用负载缓冲区前置空间写入头部,零拷贝;空间不足时创建 `OwnerPacket`,原包作为 `Next` 链节点
+- **`SpanWriter`**:配合 `ExpandHeader` 写入头部字段,注意 `IsLittleEndian` 大小端
+- **兜底释放**:`MessageCodec<T>.Write` 基类自动 `TryDispose`;`Handler` 子类需在 `Write` 的 `finally` 中手动调用
+- **对象池**:`DefaultMessage.Rent()` / `DefaultMessage.Return()` 减少 GC 压力
+
+#### 4.6.3 请求-响应匹配
+
+`MessageCodec<T>` 内置 `IMatchQueue`,流程:`Write` → `AddToQueue` 入队 → `Decode` 解码 → `Queue.Match` 按 `IsMatch` 匹配 → 唤醒 `SendMessageAsync` 的 `Task`。
+
+- 重载 `AddToQueue`:控制哪些消息入队(通常只有请求消息)
+- 重载 `IsMatch`:根据序列号等字段匹配请求和响应(见 4.7 模板)
+- `QueueSize`:匹配队列大小,默认 256
+- `Timeout`:等待响应超时,默认 30_000ms
+- `UserPacket`:为 `true` 时向上层传递 `Payload` 而非整个 `IMessage`,用于编码器级联
+
+#### 4.6.4 Close 清理
+
+**必须**在 `Close` 中执行 `ss["Codec"] = null` 清理 `PacketCodec`,否则 `MemoryStream` 缓存泄漏(见 4.7 模板)。
+
+#### 4.6.5 上下文扩展(IExtend)
+
+管道处理器通过 `IExtend` 在会话/上下文上传递元数据:
+
+| 键 | 用途 | 示例 |
+|---|------|------|
+| `"Codec"` | 每连接的 `PacketCodec` 实例 | 编解码器的 `Decode`/`Close` 中读写 |
+| `"Flag"` | 数据类型标记 `DataKinds` | `JsonCodec.Write` 设置 → `StandardCodec.Write` 消费 |
+| `"_raw_message"` | 原始请求消息 | `MessageCodec.Read` 设置 → `Write` 中创建响应时消费 |
+| `"TaskSource"` | `TaskCompletionSource` | 框架内部,`AddToQueue` 消费 |
+
+#### 4.6.6 多层管道级联
+
+- 底层编解码器处理粘包拆包和请求-响应匹配,上层处理数据格式转换
+- `UserPacket = true` 让底层向上层传递 `Payload` 而非整个 `IMessage`
+- 上层通过 `ext["Flag"]` 向底层传递数据类型标记
+
+### 4.7 自定义编解码器模板
+
+#### 方式一:继承 MessageCodec<T>(需要粘包/请求响应匹配)
+
+```csharp
+/// <summary>自定义协议编解码器</summary>
+public class MyCodec : MessageCodec<MyMessage>
+{
+    /// <summary>编码消息为数据包</summary>
+    protected override Object? Encode(IHandlerContext context, MyMessage msg)
+    {
+        return msg.ToPacket();
+    }
+
+    /// <summary>解码数据包为消息</summary>
+    protected override IEnumerable<MyMessage>? Decode(IHandlerContext context, IPacket pk)
+    {
+        if (context.Owner is not IExtend ss) yield break;
+
+        if (ss["Codec"] is not PacketCodec pc)
+        {
+            ss["Codec"] = pc = new PacketCodec
+            {
+                GetLength2 = MyMessage.GetLength,
+                MaxCache = MaxCache,
+                Tracer = (context.Owner as ISocket)?.Tracer
+            };
+        }
+
+        foreach (var item in pc.Parse(pk))
+        {
+            var msg = new MyMessage();
+            if (msg.Read(item)) yield return msg;
+        }
+    }
+
+    /// <summary>是否匹配响应</summary>
+    protected override Boolean IsMatch(Object? request, Object? response) =>
+        request is MyMessage req && response is MyMessage res
+        && req.Sequence == res.Sequence;
+
+    /// <summary>连接关闭时清理</summary>
+    public override Boolean Close(IHandlerContext context, String reason)
+    {
+        if (context.Owner is IExtend ss) ss["Codec"] = null;
+
+        return base.Close(context, reason);
+    }
+}
+```
+
+#### 方式二:继承 Handler(简单转换/帧协议)
+
+```csharp
+/// <summary>自定义帧编解码器</summary>
+public class MyFrameCodec : Handler
+{
+    /// <summary>读取数据(接收时)</summary>
+    public override Object? Read(IHandlerContext context, Object message)
+    {
+        if (message is IPacket pk)
+        {
+            // 解码:二进制 → 业务对象
+            var frame = MyFrame.Parse(pk);
+            message = frame;
+        }
+
+        return base.Read(context, message);
+    }
+
+    /// <summary>写入数据(发送时)</summary>
+    public override Object? Write(IHandlerContext context, Object message)
+    {
+        IPacket? owner = null;
+        if (message is MyFrame frame)
+        {
+            // 编码:业务对象 → 二进制
+            message = owner = frame.ToPacket();
+        }
+
+        try
+        {
+            return base.Write(context, message);
+        }
+        finally
+        {
+            owner.TryDispose();  // 兜底释放
+        }
+    }
+
+    /// <summary>连接关闭时清理缓存</summary>
+    public override Boolean Close(IHandlerContext context, String reason)
+    {
+        if (context.Owner is IExtend ss) ss["Codec"] = null;
+
+        return base.Close(context, reason);
+    }
+}
+```
+
+---
+
+## 5. 常见模式与最佳实践
+
+### 5.1 端口选择
+
+- 测试代码使用端口 `0`(系统自动分配随机端口),避免端口冲突
+- 正式服务指定固定端口
+- 启动后可通过 `server.Port` 获取实际监听端口
+
+### 5.2 协议选择
+
+| 场景 | 推荐 |
+|------|------|
+| 可靠传输、长连接 | `NetType.Tcp` |
+| 低延迟、广播、允许丢包 | `NetType.Udp` |
+| 同时支持(默认) | `NetType.Unknown` |
+| Web 浏览器通信 | `NetType.WebSocket` |
+
+### 5.3 会话管理
+
+- `UseSession = true`(默认):维护会话集合,支持群发、按 ID 查找
+- `UseSession = false`:不维护会话集合,减少内存开销,适合海量短连接
+- `SessionTimeout`:设置会话超时时间(秒),超时无数据自动断开
+- 会话中通过 `Items` 字典存储自定义数据
+
+### 5.4 日志分层
+
+| 属性 | 用途 | 建议 |
+|------|------|------|
+| `Log` | 服务器应用层日志 | 始终设置 |
+| `SessionLog` | 会话级别日志 | 调试时设置 |
+| `SocketLog` | 底层 Socket 日志 | 仅 DEBUG 时设置 |
+| `LogSend` / `LogReceive` | 收发数据内容日志 | 仅 DEBUG 时开启 |
+| `Tracer` | 应用层 APM | 生产环境追踪 |
+| `SocketTracer` | Socket 层 APM | 排查底层问题 |
+
+### 5.5 资源释放
+
+- 服务端:调用 `server.Stop(reason)` 或 `server.Dispose()`
+- 客户端:调用 `client.Close(reason)` 或 `client.Dispose()`
+- 会话自动随连接断开释放,无需手动管理
+- `ISocketClient` 实现 `IDisposable`,推荐 `using` 模式
+
+### 5.6 INetHandler 业务处理器
+
+通过重载 `NetServer.CreateHandler` 注入自定义业务处理器:
+
+```csharp
+class MyServer : NetServer<MySession>
+{
+    /// <summary>为会话创建网络数据处理器</summary>
+    public override INetHandler? CreateHandler(INetSession session) => new MyHandler();
+}
+```
+
+处理器在会话 `Start` 时初始化,`OnReceive` 前调用 `Process`,适合前置协议解析。
+
+---
+
+## 6. 常见错误
+
+- ❌ 在 `OnReceive` 中执行长时间阻塞操作(会影响其他连接的数据接收)
+- ❌ 不加管道编解码器直接调用 `SendMessageAsync`(无法匹配响应)
+- ❌ 混淆 `Send` 与 `SendMessage`:前者直接发原始数据,后者经过管道编码
+- ❌ 混淆 `SendMessage` 与 `SendReply`:响应消息必须用 `SendReply` 关联请求上下文
+- ❌ 忘记调用 `base.OnConnected()` / `base.OnDisconnected(reason)` / `base.OnReceive(e)`
+- ❌ 在会话中使用 `Task.Result` 或 `Task.Wait()`(导致死锁和线程池饥饿)
+- ❌ 使用固定端口编写测试(端口冲突),应使用 `Port = 0`
+- ❌ 服务端 SSL 未指定证书
+
+---
+
+## 7. 完整示例
+
+### 7.1 带 StandardCodec 的 Echo 服务
+
+```csharp
+// 服务端
+var server = new NetServer
+{
+    Port = 8080,
+    ProtocolType = NetType.Tcp,
+    Log = XTrace.Log,
+};
+server.Add<StandardCodec>();
+server.Received += (sender, e) =>
+{
+    if (sender is INetSession session && e.Message is IPacket pk)
+        session.SendReply(pk, e);
+};
+server.Start();
+
+// 客户端
+var client = new NetUri($"tcp://127.0.0.1:{server.Port}").CreateRemote();
+client.Add<StandardCodec>();
+client.Open();
+
+var response = await client.SendMessageAsync(new ArrayPacket("Hello".GetBytes()));
+```
+
+### 7.2 自定义会话服务器
+
+```csharp
+class ChatServer : NetServer<ChatSession> { }
+
+class ChatSession : NetSession<ChatServer>
+{
+    protected override void OnConnected()
+    {
+        base.OnConnected();
+        Send($"欢迎 [{Remote}] 进入聊天室!\r\n");
+    }
+
+    protected override void OnReceive(ReceivedEventArgs e)
+    {
+        base.OnReceive(e);
+        var msg = e.Packet?.ToStr();
+        if (msg.IsNullOrEmpty()) return;
+
+        // 广播给所有在线用户
+        var host = (this as INetSession).Host;
+        host.SendAllMessage($"[{ID}] {msg}");
+    }
+
+    protected override void OnDisconnected(String reason)
+    {
+        base.OnDisconnected(reason);
+        WriteLog("用户离开:{0}", reason);
+    }
+}
+```
+
+---
+
+(完)
Added +115 -0
diff --git a/.github/instructions/remoting.instructions.md b/.github/instructions/remoting.instructions.md
new file mode 100644
index 0000000..7ec55d9
--- /dev/null
+++ b/.github/instructions/remoting.instructions.md
@@ -0,0 +1,115 @@
+---
+applyTo: "**/Remoting/**"
+---
+
+# RPC 远程调用模块开发指令
+
+适用于 `NewLife.Remoting` 命名空间下的 RPC 框架开发。
+
+---
+
+## 1. 架构分层
+
+| 层级 | HTTP | TCP/UDP |
+|------|------|---------|
+| 客户端 | `ApiHttpClient` | `ApiClient` |
+| 服务端 | ASP.NET 集成 | `ApiServer` |
+| 负载均衡 | `ILoadBalancer` | `ILoadBalancer` |
+| 过滤器 | `IHttpFilter` | `IApiHandler` |
+| 传输 | HTTP/HTTPS | 自定义二进制(`StandardCodec`) |
+
+大多数场景使用 `ApiHttpClient`(HTTP)。仅在需要高性能双向通信、自定义协议时使用 `ApiClient`/`ApiServer`(TCP/UDP)。
+
+---
+
+## 2. ApiHttpClient 开发规范
+
+### 2.1 构造与初始化
+
+```csharp
+// 多地址负载均衡,逗号分隔
+var client = new ApiHttpClient("http://api1:8080,http://api2:8080");
+
+// 带权重
+var client = new ApiHttpClient("main=3*http://api1,backup=1*http://api2");
+
+// DI 模式(从配置中心获取地址)
+var client = new ApiHttpClient(serviceProvider, "ServiceName");
+```
+
+### 2.2 请求方法
+
+| 方法 | 说明 |
+|------|------|
+| `GetAsync<T>` / `Get<T>` | GET 请求,args 序列化为 URL 参数 |
+| `PostAsync<T>` / `Post<T>` | POST 请求,args 序列化为 JSON Body |
+| `PutAsync<T>` / `PatchAsync<T>` / `DeleteAsync<T>` | 对应 HTTP 方法 |
+| `InvokeAsync<T>` | 通用方法,可指定 HttpMethod 和自定义请求头 |
+
+### 2.3 关键属性
+
+- `Token` — Bearer 令牌,自动添加到 Authorization 头
+- `Timeout` — 请求超时毫秒(默认 15000)
+- `LoadBalanceMode` — Failover / RoundRobin / Race
+- `ShieldingTime` — 故障节点屏蔽秒数(默认 60)
+- `CodeName` / `DataName` — 响应 JSON 中状态码和数据字段名(用于统一错误处理)
+- `Filter` — 请求过滤器(用于签名、加密等)
+
+### 2.4 过滤器模式
+
+```csharp
+public class MyFilter : IHttpFilter
+{
+    public void OnRequest(ApiHttpClient client, HttpRequestMessage request, Object? args) { }
+    public void OnResponse(ApiHttpClient client, HttpResponseMessage response, Object? result) { }
+    public Boolean OnError(ApiHttpClient client, HttpResponseMessage? response, Exception ex) { return false; }
+}
+client.Filter = new MyFilter();
+```
+
+---
+
+## 3. ApiClient/ApiServer 规范(TCP/UDP RPC)
+
+### 3.1 服务端
+
+```csharp
+var server = new ApiServer(8080);
+server.Register<MyController>();   // 注册控制器(方法自动映射为 Action)
+server.Start();
+```
+
+### 3.2 客户端
+
+```csharp
+var client = new ApiClient("tcp://127.0.0.1:8080");
+client.Open();
+var result = await client.InvokeAsync<String>("Hello/Say", new { name = "test" });
+```
+
+### 3.3 控制器约定
+
+- 方法名即 Action 名:`public String Say(String name)` → 调用 `Hello/Say`
+- 支持异步方法:`public async Task<String> SayAsync(String name)`
+- 参数自动从请求体绑定
+
+---
+
+## 4. 负载均衡
+
+| 模式 | 类 | 行为 |
+|------|-----|------|
+| Failover | `FailoverLoadBalancer` | 优先第一个,失败切换下一个 |
+| RoundRobin | `WeightedRoundRobinLoadBalancer` | 加权轮询 |
+| Race | `RaceLoadBalancer` | 并发请求多个,取最快响应 |
+
+通过 `client.LoadBalanceMode` 或 `client.LoadBalancer` 设置。
+
+---
+
+## 5. 常见错误
+
+- ❌ 每次请求 `new ApiHttpClient()`(应复用,内部管理 HttpClient 连接池)
+- ❌ 未设置 `Timeout`(默认 15 秒,长请求需调大)
+- ❌ TCP RPC 未添加编解码器(`ApiClient` 内置 `StandardCodec`,但自定义协议需手动添加)
+- ❌ 忽略 `InvokeAsync` 返回值中的错误码(需配合 `CodeName` 做统一异常处理)
Added +80 -0
diff --git a/.github/instructions/security.instructions.md b/.github/instructions/security.instructions.md
new file mode 100644
index 0000000..b823def
--- /dev/null
+++ b/.github/instructions/security.instructions.md
@@ -0,0 +1,80 @@
+---
+applyTo: "**/Security/**"
+---
+
+# 安全加密模块开发指令
+
+适用于 `NewLife.Security` 命名空间下的安全加密开发。
+
+---
+
+## 1. 模块结构
+
+| 分类 | 类型 | 说明 |
+|------|------|------|
+| 扩展方法 | `SecurityHelper` | 统一入口,哈希/对称加密/RC4 |
+| 非对称 | `RSAHelper`、`ECDsaHelper` | RSA/ECDSA 加解密与签名 |
+| 国密 | `SM4` | 国密 SM4 对称加密(继承 `SymmetricAlgorithm`) |
+| 流加密 | `RC4` | RC4 流加密 |
+| 校验 | `Crc16`、`Crc32`、`Murmur128` | 数据校验 |
+| 证书 | `Certificate` | X.509 证书操作 |
+| 密码 | `IPasswordProvider` | 密码策略接口(MD5/盐值/SCrypt 等) |
+
+---
+
+## 2. 哈希规范
+
+- **MD5**:`data.MD5()` 返回 `Byte[]`,`str.MD5()` 返回 32 位十六进制字符串
+- **MD5_16**:`str.MD5_16()` 返回 16 位 MD5
+- **SHA 系列**:`data.SHA1(key)`、`data.SHA256(key)`、`data.SHA384(key)`、`data.SHA512(key)`
+  - `key` 参数非空时使用 HMAC 变体(`HMACSHA256` 等)
+  - `key` 为 `null` 时使用普通哈希
+- **Murmur**:`data.Murmur128(seed)` 非加密哈希,适合布隆过滤器等场景
+
+---
+
+## 3. 对称加密规范
+
+所有对称加密通过 `SecurityHelper` 扩展方法操作 `SymmetricAlgorithm`:
+
+```csharp
+// AES 加密
+var encrypted = Aes.Create().Encrypt(data, key, CipherMode.CBC, PaddingMode.PKCS7);
+var decrypted = Aes.Create().Decrypt(encrypted, key, CipherMode.CBC, PaddingMode.PKCS7);
+
+// SM4 国密加密
+var encrypted = SM4.Create().Encrypt(data, key, CipherMode.ECB);
+```
+
+**关键约定**:
+- `pass` 参数为密钥 `Byte[]`,长度必须匹配算法要求(AES: 16/24/32,SM4: 16)
+- `pass` 为 `null` 时使用算法实例已设置的 `Key`
+- CBC 模式需要 IV,ECB 模式不需要
+- 默认 `CipherMode.CBC` + `PaddingMode.PKCS7`
+
+---
+
+## 4. RSA 规范
+
+### 4.1 密钥管理
+
+- `RSAHelper.GenerateKey(keySize)` 返回 `[私钥XML, 公钥XML]`
+- `RSAHelper.Create(key)` 自动识别 XML/PEM/Base64 格式密钥
+- 长期存储用 PEM 格式,运行时传递用 Base64
+
+### 4.2 加解密与签名
+
+- 加密:`RSAHelper.Encrypt(data, pubKey, fOAEP)`,建议 `fOAEP = true`
+- 签名有多种算法:`Sign`(MD5)、`SignSha256`(RS256)、`SignSha384`、`SignSha512`
+- **禁止**用 MD5 签名新代码,推荐 SHA256 及以上
+
+---
+
+## 5. 安全编码要求
+
+- ❌ 硬编码密钥或盐值(应从配置/密钥管理服务获取)
+- ❌ 使用 ECB 模式加密超过一个块的数据(信息泄漏)
+- ❌ MD5 用于密码存储(应使用 `IPasswordProvider` 带盐值策略)
+- ❌ 忽略 `SymmetricAlgorithm` 的 `Dispose`(必须释放)
+- ✅ 密钥/敏感数据用后清零:`Array.Clear(keyBytes, 0, keyBytes.Length)`
+- ✅ 随机数生成使用 `RandomNumberGenerator`,不用 `Random`
Added +87 -0
diff --git a/.github/instructions/serialization.instructions.md b/.github/instructions/serialization.instructions.md
new file mode 100644
index 0000000..8f8a417
--- /dev/null
+++ b/.github/instructions/serialization.instructions.md
@@ -0,0 +1,87 @@
+---
+applyTo: "**/Serialization/**"
+---
+
+# 序列化模块开发指令
+
+适用于 `NewLife.Serialization` 命名空间下的序列化开发。
+
+---
+
+## 1. 架构分层
+
+| 层级 | 说明 |
+|------|------|
+| 扩展方法入口 | `JsonHelper`(`ToJson`/`ToJsonEntity`)、`XmlHelper` |
+| JSON 宿主 | `IJsonHost` → `FastJson`(默认)/ `SystemJson`(可切换) |
+| 二进制序列化 | `Binary` 类,Handler 链式处理 |
+| Span 序列化 | `SpanSerializer`,零分配高性能 |
+| 接口层 | `IFormatterX`(通用)、`IBinary`(二进制)、`IJsonHost`(JSON) |
+
+---
+
+## 2. JSON 序列化规范
+
+### 2.1 统一入口
+
+- **序列化**:`obj.ToJson()` 扩展方法,禁止直接构造 `JsonWriter`
+- **反序列化**:`json.ToJsonEntity<T>()` 或 `json.ToJsonEntity(type)`
+- **格式化**:`JsonHelper.Format(json)` 格式化美化
+
+### 2.2 选项控制
+
+```csharp
+// 通过 JsonOptions 控制行为
+obj.ToJson(new JsonOptions { Indented = true, NullValue = false, CamelCase = true });
+
+// 或快捷参数
+obj.ToJson(indented: true, nullValue: false, camelCase: true);
+```
+
+### 2.3 IJsonHost 切换
+
+- `JsonHelper.Default` 默认为 `FastJson`(NewLife 内置高性能实现)
+- 需要 `System.Text.Json` 兼容性时可切换 `SystemJson`
+- 自定义时实现 `IJsonHost` 接口并赋值给 `JsonHelper.Default`
+
+---
+
+## 3. Binary 序列化规范
+
+### 3.1 核心属性(必须理解)
+
+| 属性 | 默认 | 说明 |
+|------|------|------|
+| `EncodeInt` | `false` | 7位编码压缩整数(变长编码,小值省空间) |
+| `IsLittleEndian` | `true` | 字节序,与硬件通信时注意 |
+| `SizeWidth` | `0` | 集合/字符串长度字段宽度:0/1/2/4 字节 |
+| `TrimZero` | `false` | 字符串是否截断零字节 |
+| `UseRef` | `false` | 引用关系序列化(复杂对象图) |
+| `FullTime` | `false` | DateTime 用 8 字节完整时间还是 4 字节秒数 |
+| `Version` | `null` | 协议版本,影响读写行为 |
+
+### 3.2 Handler 扩展
+
+Binary 使用处理器链,通过 `AddHandler<T>()` 添加自定义处理器:
+- 处理器实现 `IBinaryHandler`,覆盖 `Write`/`TryRead`
+- 优先级数值越小越先执行
+- 内置处理器:`BinaryGeneral`、`BinaryNormal`、`BinaryComposite`、`BinaryList`、`BinaryDictionary`
+
+---
+
+## 4. SpanSerializer 规范(高性能场景)
+
+- 适用于 IoT 协议、网络帧等零分配场景
+- 目标类型实现 `ISpanSerializable` 接口
+- 序列化:`SpanSerializer.Serialize(obj)` 返回 `IOwnerPacket`(需 `Dispose` 归还缓冲区)
+- 反序列化:`SpanSerializer.Deserialize<T>(span)`
+- `SpanWriter`/`SpanReader` 为底层 Span 读写工具
+
+---
+
+## 5. 常见错误
+
+- ❌ JSON 反序列化未处理 `null` 返回值
+- ❌ Binary 序列化双方 `IsLittleEndian`/`SizeWidth` 不一致导致协议不匹配
+- ❌ `IOwnerPacket` 未 `Dispose` 导致 ArrayPool 泄漏
+- ❌ 在热点路径用 `ToJson()` 生成临时字符串(应考虑 `SpanSerializer` 或 `Binary`)
Added +651 -0
diff --git a/.github/instructions/xcode.instructions.md b/.github/instructions/xcode.instructions.md
new file mode 100644
index 0000000..10a8d39
--- /dev/null
+++ b/.github/instructions/xcode.instructions.md
@@ -0,0 +1,651 @@
+# XCode 协作指令
+
+本指令面向新生命团队(NewLife)开源数据中间件 XCode,帮助 Copilot 在 .NET 项目中正确使用 XCode 进行数据建模和实体操作。
+
+---
+
+## 1. XCode 定位与边界
+
+```
+NewLife.Core(基础库)→ copilot-instructions.md
+       ↓
+   NewLife.XCode(数据中间件)← 本指令
+       ↓
+   NewLife.Cube(Web 快速开发框架)→ cube.instructions.md
+```
+
+**本指令覆盖**:数据模型设计(Model.xml)、实体类生成与使用、数据库 CRUD 操作、运行时配置、项目初始化与 XCode 接入。
+**不包含**(由 `cube.instructions.md` 负责):Web 控制器、视图与前端、权限管理、魔方区域深度定制。
+
+### 1.1 支持的数据库
+
+| 常用 | 国产/信创 | 时序/嵌入 |
+|------|----------|----------|
+| SqlServer、MySql、SQLite、PostgreSQL、Oracle | 达梦(DaMeng)、人大金仓(KingBase)、瀚高(HighGo)、VastBase | TDengine、InfluxDB、NovaDb |
+
+> 另支持 DB2、Hana、IRIS、Access 等,完整列表见 `DatabaseType` 枚举。
+
+---
+
+## 2. 使用场景与快速入口
+
+### 2.1 场景一:已有项目接入 XCode
+
+1. 引入 NuGet 包:`dotnet add package NewLife.XCode`
+2. 创建或编辑 `Model.xml` 进行数据建模
+3. 执行 `xcode` 命令生成实体类
+4. 在业务代码中使用实体类进行数据操作
+
+### 2.2 场景二:从零创建新项目
+
+1. 安装模板:`dotnet new install NewLife.Templates`
+2. 创建数据类库:`dotnet new xcode -n {系统名}.Data`
+3. 创建应用项目:
+   - Web 应用:`dotnet new cube -n {系统名}Web`
+   - 控制台应用:`dotnet new nconsole -n {系统名}App`
+4. 编辑 `Model.xml` 进行数据建模
+5. 执行 `xcode` 生成实体类
+
+### 2.3 核心工作流
+
+```
+理解业务需求 → 数据建模(Model.xml) → 生成实体类(xcode) → 编写业务代码
+```
+
+**关键点**:无论哪种场景,核心都是 **充分理解业务需求,在 Model.xml 中设计合理的数据表结构**。
+
+---
+
+## 3. 环境准备
+
+### 3.1 前置要求
+
+```powershell
+# 检查 .NET SDK(要求 8.0+)
+dotnet --version
+
+# 安装全局工具 xcodetool
+dotnet tool install xcodetool -g
+```
+
+### 3.2 模板版本检查
+
+NewLife.Templates 模板会持续更新,使用前需检查版本:
+
+```powershell
+# 查看模板详情
+dotnet new details NewLife.Templates
+```
+
+**判定规则**:输出包含类似 `包版本: 1.1.2025.820-beta1836`
+- 其中 `1.1.2025.820` 表示 v1.1,发布日期为 2025-08-20
+- **要求**:发布日期需 > 2025-08-01(即严格晚于 2025-08-01)
+
+```powershell
+# 若未安装或版本过旧,执行安装/更新
+dotnet new install NewLife.Templates
+```
+
+> **强约束**:仅当未安装或发布日期 ≤ 2025-08-01 时才执行安装;否则保持现状,避免无谓变更。
+
+### 3.3 模板说明
+
+| 模板 | 命令 | 用途 |
+|------|------|------|
+| `xcode` | `dotnet new xcode -n Name.Data` | 数据类库项目 |
+| `cube` | `dotnet new cube -n NameWeb` | Web 管理后台 |
+| `nconsole` | `dotnet new nconsole -n NameApp` | 控制台应用 |
+
+---
+
+## 4. Model.xml 完整参考
+
+### 4.1 文件结构
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
+             xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" 
+             xmlns="https://newlifex.com/Model202509.xsd">
+  <Option>
+    <!-- 全局配置 -->
+  </Option>
+  <Tables>
+    <Table>
+      <Columns>
+        <Column />
+      </Columns>
+      <Indexes>
+        <Index />
+      </Indexes>
+    </Table>
+  </Tables>
+</EntityModel>
+```
+
+### 4.2 Option 配置项
+
+| 配置项 | 说明 | 示例 |
+|--------|------|------|
+| `Namespace` | 命名空间 | `Zero.Data` |
+| `ConnName` | 数据库连接名 | `Zero` |
+| `Output` | 实体类输出目录 | `.\` |
+| `BaseClass` | 实体基类 | `Entity` |
+| `ChineseFileName` | 使用中文文件名 | `True` |
+| `Nullable` | 生成可空引用类型 | `True` |
+| `HasIModel` | 实现 IModel 接口 | `True` |
+| `ModelClass` | 模型类模板 | `{name}Model` |
+| `ModelsOutput` | 模型类输出目录 | `.\Models\` |
+| `ModelInterface` | 模型接口模板 | `I{name}` |
+| `InterfacesOutput` | 接口输出目录 | `.\Interfaces\` |
+| `ClassNameTemplate` | 类名模板 | `{name}Model`/`I{name}Dto` |
+| `DisplayNameTemplate` | 显示名模板 | `{displayName}` |
+| `ModelNameForCopy` | Copy 函数参数类型 | `{name}`/`I{name}` |
+| `ModelNameForToModel` | ToModel 转换目标类型 | `{name}`/`{name}DTO` |
+| `ExtendNameSpace` | 额外引用命名空间(逗号分隔) | `System.Xml.Serialization` |
+| `NameFormat` | 命名格式 | `Default`/`Upper`/`Lower`/`Underline` |
+| `DisplayName` | 魔方区域显示名 | `订单管理` |
+| `CubeOutput` | 魔方控制器输出目录 | `../../Web/Areas/Order` |
+
+### 4.3 Table 属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Name` | 实体类名 | `User` |
+| `TableName` | 数据库表名(可选,默认同 Name) | `sys_user` |
+| `Description` | 表说明 | `用户。用户账号信息` |
+| `ConnName` | 独立连接名(覆盖全局) | `Log` |
+| `BaseType` | 基类(支持实体继承) | `EntityBase` |
+| `InsertOnly` | 仅插入模式(日志表优化) | `True` |
+| `IsView` | 视图标识 | `True` |
+
+### 4.4 Column 属性完整参考
+
+#### 基础属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Name` | 属性名 | `UserName` |
+| `ColumnName` | 数据库列名(可选) | `user_name` |
+| `DataType` | 数据类型 | `Int32`/`Int64`/`String`/`DateTime`/`Boolean`/`Double`/`Decimal` |
+| `Description` | 字段说明 | `用户名。登录账号` |
+| `Length` | 字符串长度 | `50`/`200`/`-1`(大文本) |
+| `Precision` | 数值精度 | `18` |
+| `Scale` | 小数位数 | `2` |
+
+#### 主键与标识
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `PrimaryKey` | 主键 | `True` |
+| `Identity` | 自增标识 | `True` |
+| `Master` | 主字段(业务主要字段) | `True` |
+
+**主键设计约定**:
+- 普通表:`Int32` 自增 → `PrimaryKey="True" Identity="True"`
+- 大数据表:`Int64` 雪花 ID → `PrimaryKey="True" DataScale="time"`(不设 Identity)
+
+#### 约束与默认值
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Nullable` | 允许空 | `False` |
+| `DefaultValue` | 默认值 | `0`/`''`/`getdate()` |
+
+#### 映射关系(Map)
+
+格式:`表名@主键@显示字段@属性名`
+
+| 格式 | 说明 | 示例 |
+|------|------|------|
+| `Table@Id@Name` | 基本映射(三段) | `Role@Id@Name` |
+| `Table@Id@Name@RoleName` | 指定属性名(四段) | `Role@Id@Name@RoleName` |
+| `NS.Table@Id@Path@AreaPath` | 完整命名空间 | `XCode.Membership.Area@Id@Path@AreaPath` |
+
+#### 元素类型(ItemType)
+
+用于魔方前端渲染,常用值:`image`、`file`、`mail`、`mobile`、`url`、`TimeSpan`、`GMK`、`html`、`code`、`json`。详细用法见 `cube.instructions.md`。
+
+#### 显示选项(ShowIn)
+
+控制字段在魔方各区域(List/Detail/AddForm/EditForm/Search)的显示。推荐具名列表语法:
+
+```
+ShowIn="List,Search"          # 仅 List 和 Search 显示
+ShowIn="-EditForm,-Detail"    # 编辑表单和详情隐藏
+ShowIn="All,-Detail"          # 全部显示,详情隐藏
+```
+
+区域别名:`List(L)`、`Detail(D)`、`AddForm(Add/A)`、`EditForm(Edit/E)`、`Search(S)`、`Form(F)`(同时控制 Add 和 Edit)
+
+**语法二:管道分隔**
+```
+ShowIn="Y|Y|N||A"   # List=显示|Detail=显示|Add=隐藏|Edit=自动|Search=自动
+```
+
+**语法三:5字符掩码**
+```
+ShowIn="11110"      # 1=显示, 0=隐藏, A/?/-=自动
+```
+
+#### 分表字段(DataScale)
+
+| 值 | 说明 |
+|----|------|
+| `time` | 大数据单表的时间字段(用于雪花 ID) |
+| `timeShard:yyMMdd` | 分表字段,按日期格式分表 |
+
+#### 其他属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Type` | 枚举类型 | `XCode.Membership.SexKinds` |
+| `Category` | 表单分组 | `登录信息`/`扩展` |
+| `Attribute` | 额外特性 | `XmlIgnore, IgnoreDataMember` |
+| `Model` | 是否包含在模型类中 | `False` |
+| `RawType` | 原始数据库类型 | `varchar(50)` |
+
+### 4.5 Index 属性
+
+| 属性 | 说明 | 示例 |
+|------|------|------|
+| `Columns` | 索引列(逗号分隔) | `Name`/`Category,CreateTime` |
+| `Unique` | 唯一索引 | `True` |
+
+### 4.6 完整示例
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
+             xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" 
+             xmlns="https://newlifex.com/Model202509.xsd">
+  <Option>
+    <Namespace>Order.Data</Namespace>
+    <ConnName>Order</ConnName>
+    <Output>.\</Output>
+    <ChineseFileName>True</ChineseFileName>
+    <Nullable>True</Nullable>
+    <HasIModel>True</HasIModel>
+    <DisplayName>订单管理</DisplayName>
+    <CubeOutput>../../OrderWeb/Areas/Order</CubeOutput>
+  </Option>
+  <Tables>
+    <Table Name="Order" Description="订单。电商订单主表">
+      <Columns>
+        <Column Name="Id" DataType="Int64" PrimaryKey="True" DataScale="time" Description="编号" />
+        <Column Name="OrderNo" DataType="String" Master="True" Length="50" Nullable="False" Description="订单号" />
+        <Column Name="UserId" DataType="Int32" Map="User@Id@Name" Description="用户" />
+        <Column Name="Status" DataType="Int32" Type="Order.Data.OrderStatus" Description="状态" />
+        <Column Name="TotalAmount" DataType="Decimal" Precision="18" Scale="2" Description="总金额" />
+        <Column Name="Remark" DataType="String" Length="500" Description="备注" Category="扩展" />
+        <Column Name="CreateUser" DataType="String" Description="创建者" Model="False" Category="扩展" />
+        <Column Name="CreateTime" DataType="DateTime" Nullable="False" Description="创建时间" Category="扩展" />
+        <Column Name="UpdateTime" DataType="DateTime" Description="更新时间" Model="False" Category="扩展" />
+      </Columns>
+      <Indexes>
+        <Index Columns="OrderNo" Unique="True" />
+        <Index Columns="UserId" />
+        <Index Columns="Status,CreateTime" />
+      </Indexes>
+    </Table>
+  </Tables>
+</EntityModel>
+```
+
+---
+
+## 5. 实体类操作指南
+
+### 5.1 基础 CRUD
+
+```csharp
+// 新增
+var entity = new User { Name = "test", Password = "123456" };
+entity.Insert();
+
+// 查询单个(按主键)
+var user = User.FindByKey(1);
+// 查询单个(按条件)
+var user2 = User.Find(User._.Name == "test");
+
+// 查询列表
+var list = User.FindAll();
+var list2 = User.FindAll(User._.Status == 1, User._.Id.Desc(), null, 0, 10);
+
+// 更新
+user.Name = "newName";
+user.Update();
+
+// 删除
+user.Delete();
+
+// 保存(自动判断 Insert/Update)
+entity.Save();
+```
+
+### 5.2 高级查询
+
+```csharp
+// 分页查询
+var page = new PageParameter { PageIndex = 1, PageSize = 20 };
+var list = User.FindAll(User._.Status == 1, page);
+
+// 条件组合
+var where = new WhereExpression();
+where &= User._.Status == 1;
+where &= User._.CreateTime >= DateTime.Today;
+if (!key.IsNullOrEmpty()) where &= User._.Name.Contains(key);
+var list2 = User.FindAll(where, page);
+
+// 统计
+var count = User.FindCount(User._.Status == 1);
+
+// 查询最大/最小值
+var maxId = User.FindMax(User._.Id, null);
+```
+
+### 5.3 批量操作
+
+```csharp
+// 批量插入
+var list = new List<User>();
+for (var i = 0; i < 100; i++)
+{
+    list.Add(new User { Name = $"user{i}" });
+}
+list.Insert();
+
+// 批量更新(将 Status==1 的记录改为 Status=2)
+User.Update(User._.Status == 2, User._.Status == 1);
+
+// 批量删除
+User.Delete(User._.Status == 0);
+```
+
+### 5.4 异步操作
+
+```csharp
+var user = await User.FindAsync(User._.Id == 1);
+var list = await User.FindAllAsync(User._.Status == 1, page);
+await entity.InsertAsync();
+await entity.SaveAsync();  // 异步保存,用于日志等高频写入
+```
+
+### 5.5 缓存查询
+
+```csharp
+// 实体缓存(适用于小表)
+var list = User.FindAllWithCache();
+
+// 单对象缓存(按主键)
+var user = User.FindByKeyWithCache(1);
+```
+
+### 5.6 Biz 文件数据层逻辑规范
+
+**核心理念**:所有需要人工编写的数据层逻辑代码,一律放在实体类的 Biz 文件(`*.Biz.cs`)中,包括**高级查询**(`#region 高级查询`)与**添删改查重载**等。外部调用方只传语义化参数,不感知 `WhereExpression` 拼接细节。
+
+#### 高级查询封装选择
+
+| 场景 | 方法形式 | 说明 | 示例 |
+|------|---------|------|------|
+| 返回单个对象,参数 ≤2 个 | `FindByXxx` | 未查到时返回 `null` | `FindByUserId(userId)` |
+| 返回列表,参数 ≤2 个,无模糊查询、无分页 | `FindAllByXxx` / `FindAllByXxxAndYyy` | 未查到时返回空列表,**不返回 null** | `FindAllByUserId(userId)` |
+| 参数较多,或含模糊查询,或含分页 | `Search(...)` | 未查到时返回空列表,**不返回 null** | `Search(userId, key, page)` |
+| 实体缓存内过滤(`Meta.Cache.FindAll(...)`) | `FindAllCachedXxx` / `FindCachedXxx` | — | `FindAllCachedEnabled()` / `FindCachedByQuestion(q)` |
+
+**命名约定说明**:
+- `FindByXxx`:返回**单个对象**(`TEntity?`),语义为"按条件查找一条记录",未找到返回 `null`
+- `FindAllByXxx`:返回**对象列表**(`IList<TEntity>`),语义为"按条件查找所有匹配记录",结果为空时返回空列表而非 `null`
+- `Search`:同样返回**对象列表**,结果为空时返回空列表而非 `null`
+
+#### Search 方法签名约定
+
+参数顺序(由左到右,按重要程度):
+
+```
+Search(业务过滤字段..., DateTime start, DateTime end, String? key, PageParameter page)
+```
+
+- 时间区间 `(DateTime start, DateTime end)` 放在 key / page 左边
+- 模糊查询关键词 `String? key` 放在 page 左边(倒数第二)
+- 分页参数 `PageParameter page` 始终最后
+
+#### 表达式简写
+
+在 Biz 文件的静态方法内部,可**省略类名前缀**:
+
+```csharp
+// ✅ 推荐(Biz 文件内部)
+var exp = _.UserId == userId;
+if (!keyword.IsNullOrEmpty()) exp &= _.Title.Contains(keyword.Trim());
+return FindAll(exp, page);
+
+// ❌ 避免(外部业务代码中拼接表达式)
+var exp = Conversation._.UserId == userId;
+if (!keyword.IsNullOrEmpty()) exp &= Conversation._.Title.Contains(keyword.Trim());
+var list = Conversation.FindAll(exp, p);
+```
+
+#### 示例
+
+```csharp
+// Biz 文件内 #region 高级查询
+
+/// <summary>根据用户编号查找最新一条会话</summary>
+/// <param name="userId">用户编号</param>
+/// <returns>会话对象,不存在时返回 null</returns>
+public static Conversation? FindByUserId(Int32 userId) => Find(_.UserId == userId);
+
+/// <summary>根据用户编号查找所有会话</summary>
+/// <param name="userId">用户编号</param>
+/// <returns>会话列表,不存在时返回空列表</returns>
+public static IList<Conversation> FindAllByUserId(Int32 userId) => FindAll(_.UserId == userId);
+
+/// <summary>分页搜索用户会话列表</summary>
+/// <param name="userId">用户编号</param>
+/// <param name="keyword">标题关键字,为空时不过滤</param>
+/// <param name="page">分页参数</param>
+/// <returns>会话列表,不存在时返回空列表</returns>
+public static IList<Conversation> Search(Int32 userId, String? keyword, PageParameter page)
+{
+    var exp = new WhereExpression();
+    exp &= _.UserId == userId;
+    if (!keyword.IsNullOrEmpty()) exp &= _.Title.Contains(keyword.Trim());
+
+    return FindAll(exp, page);
+}
+```
+
+---
+
+## 6. 运行时机制
+
+### 6.1 实体拦截器(自动填充字段)
+
+XCode 内置全局拦截器,实体包含特定命名字段时自动触发,**无需业务代码手动赋值**:
+
+| 拦截器 | 匹配字段名 | 字段类型 | 行为 |
+|--------|-----------|---------|------|
+| `TimeInterceptor` | `CreateTime` | `DateTime` | Insert 时自动填充当前时间 |
+| | `UpdateTime` | `DateTime` | Insert/Update 时自动填充当前时间 |
+| `UserInterceptor` | `CreateUserID` | `Int32`/`Int64` | Insert 时填充当前用户 ID |
+| | `CreateUser` | `String` | Insert 时填充当前用户名 |
+| | `UpdateUserID` | `Int32`/`Int64` | Insert/Update 时填充当前用户 ID |
+| | `UpdateUser` | `String` | Insert/Update 时填充当前用户名 |
+| `IPInterceptor` | `CreateIP` | `String` | Insert 时填充客户端 IP |
+| | `UpdateIP` | `String` | Insert/Update 时填充客户端 IP |
+| `TraceInterceptor` | `TraceId` | `String` | Insert/Update 时填充链路追踪 ID |
+
+**建模约定**:这些自动填充字段通常设置 `Category="扩展"` + `Model="False"`,不暴露到模型类中。
+
+示例(Model.xml 中的扩展字段标准写法):
+```xml
+<Column Name="CreateUser" DataType="String" Description="创建者" Model="False" Category="扩展" />
+<Column Name="CreateUserID" DataType="Int32" Description="创建者" Model="False" Category="扩展" />
+<Column Name="CreateTime" DataType="DateTime" Description="创建时间" Model="False" Category="扩展" />
+<Column Name="CreateIP" DataType="String" Description="创建地址" Model="False" Category="扩展" />
+<Column Name="UpdateUser" DataType="String" Description="更新者" Model="False" Category="扩展" />
+<Column Name="UpdateUserID" DataType="Int32" Description="更新者" Model="False" Category="扩展" />
+<Column Name="UpdateTime" DataType="DateTime" Description="更新时间" Model="False" Category="扩展" />
+<Column Name="UpdateIP" DataType="String" Description="更新地址" Model="False" Category="扩展" />
+<Column Name="TraceId" DataType="String" Description="链路追踪" Model="False" Category="扩展" />
+```
+
+### 6.2 反向工程(自动建表)
+
+XCode 启动时自动对比实体模型与数据库表结构,根据 `Migration` 配置决定行为:
+
+| 模式 | 说明 | 适用场景 |
+|------|------|---------|
+| `Off` | 关闭,不检查不执行 | 生产环境(表结构由 DBA 管理) |
+| `ReadOnly` | 只读,检查差异但不执行 DDL | 生产环境排查 |
+| `On` | 打开,仅新建表/列(默认值) | 开发/测试环境 |
+| `Full` | 完全,可修改列类型、删除列/索引 | 开发初期快速迭代 |
+
+### 6.3 XCodeSetting 配置
+
+通过配置文件 `XCode.json` 或 `appsettings.json` 的 `XCode` 节控制运行时行为:
+
+| 配置项 | 默认值 | 说明 |
+|--------|--------|------|
+| `Debug` | `true` | 是否启用调试日志 |
+| `ShowSQL` | `true` | 是否输出 SQL 语句 |
+| `SQLPath` | `""` | SQL 日志独立目录,生产环境建议设置 |
+| `TraceSQLTime` | `1000` | SQL 慢查询阈值(毫秒) |
+| `UseParameter` | `false` | 参数化添删改查 |
+| `CommandTimeout` | `0` | 命令超时(秒),0 不限制 |
+| `RetryOnFailure` | `0` | 失败重试次数 |
+| `Migration` | `On` | 反向工程模式(见 6.2) |
+| `BatchSize` | `5000` | 批量操作数据量 |
+| `EntityCacheExpire` | `10` | 实体缓存过期时间(秒) |
+| `SingleCacheExpire` | `10` | 单对象缓存过期时间(秒) |
+
+**生产环境建议**:
+```json
+{
+  "XCode": {
+    "Migration": "Off",
+    "ShowSQL": false,
+    "SQLPath": "../SqlLog",
+    "TraceSQLTime": 500
+  }
+}
+```
+
+---
+
+## 7. 多模块项目结构
+
+对于复杂业务系统,建议按模块组织:
+
+```
+Zero.Data/
+├── Order/           # 订单模块
+│   ├── Order.xml    # 订单模型
+│   ├── 订单.cs
+│   └── 订单明细.cs
+├── Product/         # 商品模块
+│   ├── Product.xml  # 商品模型
+│   ├── 商品.cs
+│   └── 分类.cs
+└── Member/          # 会员模块
+    ├── Member.xml   # 会员模型
+    └── 会员.cs
+```
+
+每个模块目录内有独立的 `*.xml` 模型文件,在各自目录执行 `xcode` 命令生成实体类。
+
+---
+
+## 8. xcode 命令参考
+
+```powershell
+# 在模型文件所在目录执行(自动查找所有 *.xml)
+xcode
+
+# 指定模型文件
+xcode Model.xml
+xcode Order.xml
+```
+
+**执行效果**:
+1. 读取 XML 模型文件
+2. 生成实体类(`*.cs`)
+3. 生成模型类(如配置了 `ModelClass`)
+4. 生成接口(如配置了 `ModelInterface`)
+5. 生成数据字典(`*.htm`)
+6. 生成魔方控制器(如配置了 `CubeOutput`)
+
+---
+
+## 9. 常见问题
+
+### 9.1 模型文件命名
+
+- 默认:`Model.xml`
+- 推荐:`{系统英文名}.xml` 或 `{模块名}.xml`
+- 复杂项目:每个模块目录一个模型文件
+
+### 9.2 实体类生成位置
+
+- 实体类生成在 `xcode` 命令执行目录
+- 可通过 `Output` 配置项指定输出目录
+- 魔方控制器通过 `CubeOutput` 指定
+
+### 9.3 数据库连接
+
+在应用配置文件中配置连接字符串:
+
+```json
+{
+  "ConnectionStrings": {
+    "Order": "Server=.;Database=Order;Uid=sa;Pwd=xxx"
+  }
+}
+```
+
+连接名对应 Model.xml 中的 `ConnName`。未配置连接字符串时,默认创建同名 SQLite 数据库。
+
+### 9.4 生成的代码能否手动修改
+
+实体类分为两个文件:
+- `实体名.cs`(如 `订单.cs`):自动生成的数据映射代码,**每次 `xcode` 会覆盖,禁止手动修改**
+- `实体名.Biz.cs`(如 `订单.Biz.cs`):业务扩展代码,仅首次生成,**可自由修改**
+
+需要调整字段、类型、索引时,应修改 `Model.xml` 后重新执行 `xcode`。
+
+### 9.5 如何调试 SQL
+
+配置 `XCodeSetting.ShowSQL = true`(默认开启),所有 SQL 输出到日志。设置 `SQLPath` 可将 SQL 日志独立存放。`TraceSQLTime` 控制慢查询阈值。
+
+### 9.6 与 Cube 的协作
+
+需要生成 Web 管理界面时:在 Model.xml 中配置 `CubeOutput` 指向 Web 项目的 Areas 目录,配置 `DisplayName` 作为区域名称,执行 `xcode` 自动生成控制器。深度定制见 `cube.instructions.md`。
+
+---
+
+## 10. Copilot 行为指引
+
+### 10.1 数据建模时
+
+1. **充分理解业务**:在设计表结构前,确保理解业务场景和数据关系
+2. **合理设计主键**:
+   - 普通表:`Int32` + `PrimaryKey="True" Identity="True"`
+   - 大数据表:`Int64` + `PrimaryKey="True" DataScale="time"`(雪花 ID)
+3. **必要的索引**:为查询条件字段添加索引
+4. **字段长度**:String 类型必须指定合理的 `Length`
+5. **扩展字段**:`CreateTime`/`UpdateTime`/`CreateUser`/`UpdateUser`/`CreateIP`/`UpdateIP` 等由拦截器自动填充(见 6.1),设置 `Model="False" Category="扩展"`
+
+### 10.2 生成代码时
+
+1. 确保在正确目录执行 `xcode`
+2. 生成后检查编译是否通过
+3. 如需修改生成的代码,应修改 Model.xml 后重新生成
+4. 业务逻辑写在 `.Biz.cs` 文件中
+
+### 10.3 边界意识
+
+- 数据模型和实体操作 → 本指令
+- Web 控制器和界面 → `cube.instructions.md`
+- 基础编码规范 → `copilot-instructions.md`
Added +48 -0
diff --git a/.github/prompts/doc-writer.prompt.md b/.github/prompts/doc-writer.prompt.md
new file mode 100644
index 0000000..3eb5220
--- /dev/null
+++ b/.github/prompts/doc-writer.prompt.md
@@ -0,0 +1,48 @@
+# 角色
+你是新生命团队(NewLife)的资深技术文档工程师。
+
+# 任务
+分析给定的 C# 代码文件,为其生成一份高质量的 Markdown 文档。
+
+# 输出格式要求 (严格遵守)
+
+---
+title: {类名/模块名}
+description: {用一句话概括这个类是做什么的}
+tags: [Core, 日志, 网络]
+category: API
+api_version: {从AssemblyInfo或csproj读取版本}
+is_core: true/false
+---
+
+## 概述
+{这里写 2-3 段话,详细介绍功能、设计意图、典型应用场景}
+
+## 快速开始
+\`\`\`csharp
+// 给出最简单的 3-5 行代码示例
+\`\`\`
+
+## API 文档
+
+### 主要属性
+| 属性名 | 类型 | 说明 |
+|--------|------|------|
+| Name | String | 描述 |
+
+### 主要方法
+
+#### `MethodName(param1)`
+**功能说明**:...
+**参数**:
+- `param1`: ...
+**返回值**:...
+**示例**:
+\`\`\`csharp
+\`\`\`
+
+## 最佳实践
+{如果有坑,在这里写。比如:“注意,该方法不是线程安全的”}
+
+## 相关链接
+- [相关类名](链接)
\ No newline at end of file
Added +130 -0
diff --git a/.github/skills/caching/SKILL.md b/.github/skills/caching/SKILL.md
new file mode 100644
index 0000000..0e146c9
--- /dev/null
+++ b/.github/skills/caching/SKILL.md
@@ -0,0 +1,130 @@
+---
+name: caching
+description: 使用 NewLife 统一缓存接口实现内存缓存、分布式缓存、缓存锁和队列
+---
+
+# NewLife 缓存系统使用指南
+
+## 适用场景
+
+- 需要高性能键值缓存(内存或 Redis)
+- 需要分布式锁
+- 需要生产者-消费者队列
+- 需要原子递增/递减计数器
+
+## 核心 API
+
+### 内存缓存
+
+```csharp
+// 全局单例(推荐)
+var cache = MemoryCache.Instance;
+
+// 或自定义实例
+var cache = new MemoryCache { Capacity = 100_000, Expire = 60 };
+```
+
+### 基础操作
+
+```csharp
+ICache cache = MemoryCache.Instance;
+
+// 设置(60秒过期)
+cache.Set("key", "value", 60);
+cache.Set("user:1", new User { Name = "test" }, 300);
+
+// 获取
+var val = cache.Get<String>("key");
+var user = cache.Get<User>("user:1");
+
+// 带默认值的获取
+if (cache.TryGetValue<User>("user:1", out var u)) { /* 命中 */ }
+
+// 删除
+cache.Remove("key");
+cache.Remove("user:*");  // 通配符删除
+
+// 批量操作
+var dict = cache.GetAll<String>(["key1", "key2", "key3"]);
+cache.SetAll(new Dictionary<String, Object> { ["a"] = 1, ["b"] = 2 }, 60);
+```
+
+### GetOrAdd 模式
+
+```csharp
+// 缓存未命中时执行回调加载
+var user = cache.GetOrAdd("user:1", k => LoadUserFromDb(k), 300);
+```
+
+### 原子计数器
+
+```csharp
+// 原子递增,适合计数、限流
+var count = cache.Increment("api:calls", 1);
+var (value, ttl) = cache.IncrementWithTtl("api:calls", 1);  // 同时获取剩余过期时间
+```
+
+### 分布式锁
+
+```csharp
+using var lck = cache.AcquireLock("lock:order:123", 3000);
+if (lck != null)
+{
+    // 获取锁成功,执行业务
+    ProcessOrder(123);
+}
+else
+{
+    // 获取锁失败(超时),降级处理
+}
+```
+
+### 队列
+
+```csharp
+var queue = cache.GetQueue<String>("task:queue");
+queue.Add("task1");
+queue.Add("task2");
+
+// 消费
+if (queue.TryTake(out var task)) { /* 处理 task */ }
+
+// 批量消费
+var tasks = queue.Take(10).ToList();
+```
+
+## ICacheProvider 服务化
+
+```csharp
+// 注册到 DI
+services.AddSingleton<ICacheProvider, CacheProvider>();
+
+// 使用
+public class OrderService(ICacheProvider cacheProvider)
+{
+    public void Process()
+    {
+        var cache = cacheProvider.Cache;     // 跨进程缓存
+        var local = cacheProvider.InnerCache; // 本地缓存
+        using var lck = cacheProvider.AcquireLock("key", 3000);
+    }
+}
+```
+
+## 切换到 Redis
+
+```csharp
+// 安装 NewLife.Redis 包后
+var redis = new FullRedis("server=127.0.0.1:6379;password=pass;db=0");
+
+// ICache 接口完全兼容,业务代码无需修改
+ICache cache = redis;
+cache.Set("key", "value", 60);
+```
+
+## 注意事项
+
+- `MemoryCache.Instance` 是全局单例,整个应用共享
+- `expire = -1` 使用缓存的默认过期时间,`expire = 0` 表示立即过期
+- `Remove` 支持 `*` 通配符,但大量 key 时性能较差
+- Redis 实现在独立包 `NewLife.Redis`,接口完全兼容
Added +174 -0
diff --git a/.github/skills/configuration/SKILL.md b/.github/skills/configuration/SKILL.md
new file mode 100644
index 0000000..9ccbaea
--- /dev/null
+++ b/.github/skills/configuration/SKILL.md
@@ -0,0 +1,174 @@
+---
+name: configuration
+description: 使用 NewLife 配置系统管理应用配置,支持本地文件、配置中心和命令行参数
+---
+
+# NewLife 配置系统使用指南
+
+## 适用场景
+
+- 应用程序配置管理(替代 appsettings.json)
+- 强类型配置绑定
+- 远程配置中心集成(Stardust / Apollo)
+- 配置热更新和变更通知
+- 命令行参数解析
+
+## 强类型配置(Config\<T\>)
+
+### 定义配置类
+
+```csharp
+public class AppConfig : Config<AppConfig>
+{
+    /// <summary>应用名称</summary>
+    public String AppName { get; set; } = "MyApp";
+
+    /// <summary>数据库连接字符串</summary>
+    public String ConnectionString { get; set; } = "Data Source=app.db";
+
+    /// <summary>服务端口</summary>
+    public Int32 Port { get; set; } = 8080;
+
+    /// <summary>启用调试模式</summary>
+    public Boolean Debug { get; set; }
+
+    /// <summary>加载后校验</summary>
+    protected override void OnLoaded()
+    {
+        if (Port <= 0 || Port > 65535) Port = 8080;
+    }
+}
+```
+
+### 使用配置
+
+```csharp
+// 首次访问自动从文件加载(默认 AppConfig.json)
+var config = AppConfig.Current;
+
+var name = config.AppName;
+var port = config.Port;
+
+// 修改并保存
+config.Debug = true;
+config.Save();
+
+// 首次运行生成默认配置文件
+if (config.IsNew)
+    XTrace.WriteLine("已生成默认配置文件,请修改后重启");
+```
+
+## IConfigProvider 直接使用
+
+### JSON 配置文件
+
+```csharp
+var provider = new JsonConfigProvider { FileName = "config.json" };
+provider.LoadAll();
+
+// 读取值(冒号分隔多级 key)
+var connStr = provider["Database:ConnectionString"];
+
+// 绑定到对象
+var dbConfig = provider.Load<DatabaseConfig>("Database");
+
+// 监听变更
+provider.Changed += (s, e) => XTrace.WriteLine("配置已变更");
+```
+
+### XML / INI 配置
+
+```csharp
+// XML
+var provider = new XmlConfigProvider { FileName = "config.xml" };
+
+// INI
+var provider = new IniConfigProvider { FileName = "config.ini" };
+```
+
+## 远程配置中心
+
+### Stardust 配置中心
+
+```csharp
+var provider = new HttpConfigProvider
+{
+    Server = "http://star.newlifex.com:6600",
+    AppId = "MyApp",
+    Secret = "xxx",
+    Scope = "production",    // 环境标识
+    Period = 60,             // 轮询间隔秒数
+};
+provider.LoadAll();
+
+// 替换全局 Config 提供者
+AppConfig.Provider = provider;
+
+// 之后通过 AppConfig.Current 自动从配置中心获取
+```
+
+### Apollo 配置中心
+
+```csharp
+var provider = new ApolloConfigProvider
+{
+    Server = "http://apollo-server:8080",
+    AppId = "MyApp",
+};
+```
+
+## 自动绑定与热更新
+
+```csharp
+var provider = new JsonConfigProvider { FileName = "app.json" };
+provider.LoadAll();
+
+var config = new AppConfig();
+provider.Bind(config, autoReload: true);  // 文件变更时自动更新对象
+
+// 或带变更回调
+provider.Bind(config, "AppConfig", section =>
+{
+    XTrace.WriteLine("配置已更新:{0}", section["AppName"]);
+});
+```
+
+## 命令行参数
+
+```csharp
+var parser = new CommandParser { IgnoreCase = true };
+var args = parser.Parse(Environment.GetCommandLineArgs());
+
+// 命令行: --port 8080 --debug -v
+var port = args["port"].ToInt();     // 8080
+var debug = args.ContainsKey("debug"); // true
+var verbose = args.ContainsKey("v"); // true
+
+// 字符串分割为参数数组
+var parts = CommandParser.Split("--port 8080 --name \"My App\"");
+```
+
+## 内置全局配置
+
+```csharp
+// Setting 类(全局应用设置,对应 Config/Core.config)
+var setting = Setting.Current;
+setting.LogPath = "Logs";
+setting.TempPath = "Temp";
+setting.PluginPath = "Plugins";
+setting.Save();
+
+// SysConfig(系统配置,应用名/版本/显示名等元数据)
+var sys = SysConfig.Current;
+sys.Name = "MyApp";
+sys.DisplayName = "我的应用";
+```
+
+## 注意事项
+
+- `Config<T>.Current` 是线程安全的单例
+- 默认使用 JSON 格式,文件名为 `Config/{类名}.json`
+- `OnLoaded()` 在每次加载后调用,适合做校验和默认值修正
+- `IsNew = true` 表示配置文件首次创建,可提示用户修改
+- `HttpConfigProvider` 会本地缓存(加密),即使配置中心不可用也能启动
+- 不要在静态构造函数中访问 `Config<T>.Current`(可能死锁)
Added +175 -0
diff --git a/.github/skills/dependency-injection/SKILL.md b/.github/skills/dependency-injection/SKILL.md
new file mode 100644
index 0000000..59aee77
--- /dev/null
+++ b/.github/skills/dependency-injection/SKILL.md
@@ -0,0 +1,175 @@
+---
+name: dependency-injection
+description: 使用 NewLife ObjectContainer 实现轻量级依赖注入和应用主机托管
+---
+
+# NewLife 依赖注入与应用主机使用指南
+
+## 适用场景
+
+- 轻量级 IoC/DI 容器(替代 Microsoft.Extensions.DependencyInjection)
+- 后台服务托管(Windows 服务 / Linux Systemd)
+- 插件管理和模块化开发
+- Actor 并发模型
+
+## ObjectContainer(DI 容器)
+
+### 注册服务
+
+```csharp
+var container = ObjectContainer.Current;
+
+// 单例
+container.AddSingleton<ICache, MemoryCache>();
+container.AddSingleton<ICache>(MemoryCache.Instance);
+container.AddSingleton<ICache>(sp => new MemoryCache { Capacity = 50000 });
+
+// 作用域
+container.AddScoped<IUserService, UserService>();
+
+// 瞬态
+container.AddTransient<IOrderService, OrderService>();
+
+// TryAdd 版本(已存在则跳过)
+container.TryAddSingleton<ICache, MemoryCache>();
+```
+
+### 解析服务
+
+```csharp
+// 通过 IServiceProvider
+var provider = ObjectContainer.Provider;
+var cache = provider.GetService<ICache>();
+var service = provider.GetRequiredService<IUserService>();
+
+// 全局静态访问
+var cache = ObjectContainer.Provider.GetService<ICache>();
+```
+
+### 与 .NET Generic Host 集成
+
+```csharp
+var builder = Host.CreateDefaultBuilder(args);
+builder.ConfigureServices(services =>
+{
+    // NewLife 的 ObjectContainer 可与 Microsoft DI 共存
+    var container = ObjectContainer.Current;
+    container.AddSingleton<ICache, MemoryCache>();
+
+    // 将 NewLife 注册桥接到 Microsoft DI
+    ObjectContainer.SetInnerProvider(services.BuildServiceProvider());
+});
+```
+
+## Host(轻量级应用主机)
+
+### 基本用法
+
+```csharp
+// 创建服务容器
+var services = ObjectContainer.Current;
+
+// 注册后台服务
+services.AddSingleton<ICache, MemoryCache>();
+services.AddHostedService<MyBackgroundService>();
+
+// 创建并运行主机
+var host = services.BuildHost();
+host.Run();  // 阻塞运行,Ctrl+C 优雅退出
+```
+
+### 后台服务
+
+```csharp
+public class DataSyncService : IHostedService
+{
+    private readonly ICache _cache;
+    private TimerX? _timer;
+
+    public DataSyncService(ICache cache) => _cache = cache;
+
+    public Task StartAsync(CancellationToken cancellationToken)
+    {
+        _timer = new TimerX(DoSync, null, 1000, 60_000);
+        return Task.CompletedTask;
+    }
+
+    public Task StopAsync(CancellationToken cancellationToken)
+    {
+        _timer.TryDispose();
+        return Task.CompletedTask;
+    }
+
+    private void DoSync(Object? state)
+    {
+        // 定时同步逻辑
+    }
+}
+```
+
+## 插件框架
+
+### 定义插件
+
+```csharp
+public class MyPlugin : IPlugin
+{
+    public void Add(IObjectContainer container)
+    {
+        // 注册插件提供的服务
+        container.AddSingleton<IMyService, MyServiceImpl>();
+    }
+
+    public void Use(IHost host)
+    {
+        // 使用主机服务
+        var svc = host.Services.GetService<IMyService>();
+    }
+}
+```
+
+### 加载插件
+
+```csharp
+// 扫描程序集中的插件
+var manager = new PluginManager();
+manager.LoadPlugins("Plugins", "*.dll");
+manager.Init(container);
+```
+
+## Actor 并发模型
+
+```csharp
+public class OrderActor : Actor
+{
+    protected override async Task ReceiveAsync(ActorContext context)
+    {
+        switch (context.Message)
+        {
+            case CreateOrderCommand cmd:
+                await ProcessCreateOrder(cmd);
+                break;
+            case CancelOrderCommand cmd:
+                await ProcessCancelOrder(cmd);
+                break;
+        }
+    }
+}
+
+// 使用
+var actor = new OrderActor { Name = "OrderProcessor", Tracer = tracer };
+await actor.Start();
+
+// 发送消息(异步处理,线程安全)
+actor.Tell(new CreateOrderCommand { UserId = 1, Amount = 100 });
+actor.Tell(new CancelOrderCommand { OrderId = 123 });
+```
+
+## 注意事项
+
+- `ObjectContainer.Current` 是全局单例容器
+- `ObjectContainer.Provider` 是全局 `IServiceProvider`
+- 注册顺序:先注册基础服务,再注册依赖它们的服务
+- `IHostedService` 兼容 .NET Generic Host 接口
+- Actor 的 `ReceiveAsync` 保证**单线程顺序执行**,无需加锁
+- `BoundedCapacity` 限制 Actor 消息队列上限,满时 `Tell` 返回 0
Added +143 -0
diff --git a/.github/skills/http-client/SKILL.md b/.github/skills/http-client/SKILL.md
new file mode 100644
index 0000000..cc6af8e
--- /dev/null
+++ b/.github/skills/http-client/SKILL.md
@@ -0,0 +1,143 @@
+---
+name: http-client
+description: 使用 NewLife ApiHttpClient 进行 HTTP API 调用,支持负载均衡、故障转移和过滤器
+---
+
+# NewLife HTTP 客户端使用指南
+
+## 适用场景
+
+- 调用 RESTful API
+- 多节点负载均衡和自动故障转移
+- 统一 Token 认证
+- 请求签名和加密
+- 微服务间通信
+
+## 基础用法
+
+### 创建客户端
+
+```csharp
+// 单节点
+var client = new ApiHttpClient("http://api.example.com");
+
+// 多节点负载均衡(逗号分隔)
+var client = new ApiHttpClient("http://api1:8080,http://api2:8080,http://api3:8080");
+
+// 带权重(main 权重 3,backup 权重 1)
+var client = new ApiHttpClient("main=3*http://api1:8080,backup=1*http://api2:8080");
+```
+
+### 发起请求
+
+```csharp
+// GET 请求(args 自动序列化为 URL 参数)
+var users = await client.GetAsync<User[]>("api/users", new { page = 1, size = 20 });
+var user = client.Get<User>("api/users/1");
+
+// POST 请求(args 自动序列化为 JSON Body)
+var result = await client.PostAsync<Int32>("api/users", new { Name = "test", Age = 25 });
+
+// PUT / PATCH / DELETE
+await client.PutAsync<Object>("api/users/1", new { Name = "updated" });
+await client.PatchAsync<Object>("api/users/1", new { Age = 26 });
+await client.DeleteAsync<Boolean>("api/users/1");
+
+// 通用方法(自定义请求头等)
+var result = await client.InvokeAsync<User>(HttpMethod.Get, "api/users/1",
+    onRequest: req => req.Headers.Add("X-Custom", "value"));
+```
+
+## 负载均衡
+
+```csharp
+var client = new ApiHttpClient("http://api1:8080,http://api2:8080");
+
+// 故障转移(默认):优先第一个,失败切换
+client.LoadBalanceMode = LoadBalanceMode.Failover;
+
+// 加权轮询
+client.LoadBalanceMode = LoadBalanceMode.RoundRobin;
+
+// 竞速:并发请求所有节点,取最快响应
+client.LoadBalanceMode = LoadBalanceMode.Race;
+
+// 故障屏蔽时间(秒)
+client.ShieldingTime = 60;
+```
+
+## Token 认证
+
+```csharp
+// 设置 Bearer Token(自动添加到 Authorization 头)
+client.Token = "your-jwt-token";
+
+// 动态刷新 Token(配合过滤器)
+client.Filter = new TokenFilter(client);
+```
+
+## 请求过滤器
+
+```csharp
+public class SignFilter : IHttpFilter
+{
+    public void OnRequest(ApiHttpClient client, HttpRequestMessage request, Object? args)
+    {
+        // 请求前:添加签名
+        var sign = ComputeSign(args);
+        request.Headers.Add("X-Sign", sign);
+    }
+
+    public void OnResponse(ApiHttpClient client, HttpResponseMessage response, Object? result)
+    {
+        // 响应后:记录日志
+    }
+
+    public Boolean OnError(ApiHttpClient client, HttpResponseMessage? response, Exception ex)
+    {
+        // 错误处理,返回 true 表示已处理
+        return false;
+    }
+}
+
+client.Filter = new SignFilter();
+```
+
+## 统一错误处理
+
+```csharp
+// 配置响应格式(当 API 返回 { code: 0, data: {...}, message: "ok" })
+client.CodeName = "code";   // 状态码字段名
+client.DataName = "data";   // 数据字段名
+
+// 自动提取 data 字段,code != 0 时抛 ApiException
+var user = await client.GetAsync<User>("api/users/1");
+```
+
+## DI 集成
+
+```csharp
+// 注册
+services.AddSingleton(sp =>
+{
+    var client = new ApiHttpClient(sp, "UserService");  // 从配置中心获取地址
+    client.Tracer = sp.GetService<ITracer>();
+    client.Log = XTrace.Log;
+    return client;
+});
+
+// 使用
+public class UserClient(ApiHttpClient client)
+{
+    public Task<User?> GetAsync(Int32 id) => client.GetAsync<User>($"api/users/{id}");
+}
+```
+
+## 注意事项
+
+- **复用实例**:`ApiHttpClient` 内部管理 `HttpClient` 连接池,禁止每次请求 new
+- `Timeout` 默认 15 秒,文件上传等长请求需调大
+- 多节点地址变更会自动感知(通过配置中心或手动 `SetServer`)
+- `Tracer` 属性可注入链路追踪,自动记录 HTTP 请求 Span
+- GET 请求的参数对象会序列化为 URL 查询字符串
+- POST 请求的参数对象会序列化为 JSON Body
Added +190 -0
diff --git a/.github/skills/logging-tracing/SKILL.md b/.github/skills/logging-tracing/SKILL.md
new file mode 100644
index 0000000..d968235
--- /dev/null
+++ b/.github/skills/logging-tracing/SKILL.md
@@ -0,0 +1,190 @@
+---
+name: logging-tracing
+description: 使用 NewLife 日志框架和分布式链路追踪 APM,实现结构化日志、多输出和性能追踪
+---
+
+# NewLife 日志与链路追踪使用指南
+
+## 适用场景
+
+- 应用程序日志输出(控制台、文件、网络)
+- 分布式链路追踪和 APM 性能监控
+- 代码执行性能计时
+- 与星尘(Stardust)监控平台集成
+
+## 日志系统
+
+### 快速启动
+
+```csharp
+// 启用控制台 + 文件日志
+XTrace.UseConsole();
+
+// 输出日志
+XTrace.WriteLine("应用启动");
+XTrace.WriteLine("处理用户 {0} 的请求,耗时 {1}ms", userId, elapsed);
+
+// 输出异常
+try { ... }
+catch (Exception ex) { XTrace.WriteException(ex); }
+
+// 输出版本信息(应用启动时调用)
+XTrace.WriteVersion();
+```
+
+### ILog 接口
+
+```csharp
+public class MyService
+{
+    public ILog Log { get; set; } = Logger.Null;
+
+    public void Process()
+    {
+        Log.Info("开始处理");
+        Log.Debug("调试信息:count={0}", count);
+        Log.Warn("注意:队列积压 {0} 条", queue.Count);
+        Log.Error("处理失败:{0}", ex.Message);
+    }
+}
+
+// 注入日志
+var svc = new MyService { Log = XTrace.Log };
+```
+
+### 日志级别
+
+| 级别 | 方法 | 场景 |
+|------|------|------|
+| Debug | `Log.Debug()` | 开发调试信息 |
+| Info | `Log.Info()` | 正常业务流程 |
+| Warn | `Log.Warn()` | 预警但不影响运行 |
+| Error | `Log.Error()` | 错误需要关注 |
+| Fatal | `Log.Fatal()` | 致命错误 |
+
+### 多目标日志
+
+```csharp
+// 组合日志:同时输出到控制台和文件
+var log = new CompositeLog(new ConsoleLog(), new TextFileLog("logs"));
+
+// 文本文件日志
+var fileLog = new TextFileLog("logs") { MaxBytes = 10 * 1024 * 1024 }; // 10MB 滚动
+
+// 网络日志
+var netLog = new NetworkLog("udp://log-server:514");
+```
+
+## 链路追踪(ITracer)
+
+### 基本埋点
+
+```csharp
+public class OrderService
+{
+    public ITracer? Tracer { get; set; }
+
+    public void CreateOrder(Order order)
+    {
+        // 创建追踪 Span(自动计时,自动记录异常)
+        using var span = Tracer?.NewSpan("CreateOrder", new { order.UserId, order.Amount });
+
+        try
+        {
+            ValidateOrder(order);
+            SaveToDb(order);
+            SendNotification(order);
+        }
+        catch (Exception ex)
+        {
+            span?.SetError(ex, null);  // 记录异常到 Span
+            throw;
+        }
+    }
+}
+```
+
+### 配置追踪器
+
+```csharp
+// 本地追踪器
+var tracer = new DefaultTracer
+{
+    Period = 15,          // 采样周期秒
+    MaxSamples = 1,       // 正常采样数
+    MaxErrors = 10,       // 异常采样数
+    Timeout = 15000,      // 超时强制采样(毫秒)
+    Log = XTrace.Log,
+};
+DefaultTracer.Instance = tracer;
+
+// 星尘追踪器(需要 Stardust 包)
+// var tracer = new StarTracer("http://star.newlifex.com:6600") { ... };
+```
+
+### Span 嵌套
+
+```csharp
+public async Task ProcessAsync()
+{
+    using var span = Tracer?.NewSpan("Process");
+
+    // 子 Span 自动关联父 Span
+    using var span2 = Tracer?.NewSpan("Step1");
+    await Step1Async();
+    span2?.Dispose();
+
+    using var span3 = Tracer?.NewSpan("Step2", new { key = "value" });
+    await Step2Async();
+}
+```
+
+### 附加标签
+
+```csharp
+using var span = Tracer?.NewSpan("HttpCall");
+span?.AppendTag($"url={url}");
+span?.AppendTag($"status={response.StatusCode}");
+```
+
+## 代码计时器
+
+```csharp
+// 快速性能测试
+var timer = new CodeTimer();
+timer.ShowHeader();
+timer.Show("字符串拼接", () =>
+{
+    var s = "";
+    for (var i = 0; i < 1000; i++) s += i;
+});
+timer.Show("StringBuilder", () =>
+{
+    var sb = Pool.StringBuilder.Get();
+    for (var i = 0; i < 1000; i++) sb.Append(i);
+    sb.Put();
+});
+```
+
+## 在 NetServer/NetSession 中使用
+
+```csharp
+class MySession : NetSession<MyServer>
+{
+    protected override void OnReceive(ReceivedEventArgs e)
+    {
+        // NetSession 内置 Log 和 Tracer
+        WriteLog("收到数据 {0} 字节", e.Packet?.Total);
+        using var span = Session?.Tracer?.NewSpan("OnReceive");
+        // ...
+    }
+}
+```
+
+## 注意事项
+
+- `Tracer?.NewSpan()` 使用 null 条件运算符,未配置追踪器时零开销
+- `using var span = ...` 确保 Span 结束时自动上报
+- `span?.SetError(ex, null)` 在 catch 中调用,不影响异常传播
+- 热点路径(每秒万次以上调用)的 Span 名称应固定,不含变量
+- `XTrace.Log` 是全局日志入口,`XTrace.UseConsole()` 初始化控制台输出
Added +176 -0
diff --git a/.github/skills/networking/SKILL.md b/.github/skills/networking/SKILL.md
new file mode 100644
index 0000000..2a7ef9c
--- /dev/null
+++ b/.github/skills/networking/SKILL.md
@@ -0,0 +1,176 @@
+---
+name: networking
+description: 使用 NewLife.Net 构建高性能 TCP/UDP/WebSocket 网络服务和客户端
+---
+
+# NewLife 网络编程使用指南
+
+## 适用场景
+
+- 构建高性能 TCP/UDP 网络服务器(实测 2266 万 tps)
+- 自定义二进制协议通信
+- WebSocket 服务端和客户端
+- IoT 设备接入网关
+- 粘包拆包处理
+
+## 服务端开发
+
+### 基本模式(推荐)
+
+```csharp
+// 自定义服务器
+class MyServer : NetServer<MySession> { }
+
+// 自定义会话(每个连接一个实例)
+class MySession : NetSession<MyServer>
+{
+    protected override void OnConnected()
+    {
+        base.OnConnected();
+        WriteLog("客户端连接 {0}", Remote);
+    }
+
+    protected override void OnReceive(ReceivedEventArgs e)
+    {
+        base.OnReceive(e);
+        var data = e.Packet;
+        // 业务处理...
+
+        // 回复
+        Send(data);
+    }
+
+    protected override void OnDisconnected(String reason)
+    {
+        base.OnDisconnected(reason);
+    }
+}
+
+// 启动
+var server = new MyServer
+{
+    Port = 8080,
+    Log = XTrace.Log,
+    Tracer = tracer,
+#if DEBUG
+    LogSend = true,
+    LogReceive = true,
+#endif
+};
+server.Start();
+```
+
+### 事件模式(简单场景)
+
+```csharp
+var server = new NetServer { Port = 8080 };
+server.Received += (sender, e) =>
+{
+    if (sender is INetSession session)
+        session.Send(e.Packet);  // Echo
+};
+server.Start();
+```
+
+### 群发
+
+```csharp
+// 群发给所有在线客户端
+await server.SendAllAsync(data);
+
+// 带条件群发
+await server.SendAllAsync(data, s => s["VIP"] is true);
+```
+
+## 客户端开发
+
+### 创建客户端
+
+```csharp
+// TCP 客户端
+var client = new NetUri("tcp://127.0.0.1:8080").CreateRemote();
+client.Log = XTrace.Log;
+client.Open();
+
+// 发送
+client.Send("Hello");
+
+// 事件接收
+client.Received += (sender, e) => { var data = e.Packet; };
+
+// 同步接收
+using var pk = client.Receive();
+
+// 异步接收
+using var pk = await client.ReceiveAsync(cancellationToken);
+
+client.Close("完成");
+```
+
+### 请求-响应模式
+
+```csharp
+var client = new NetUri("tcp://127.0.0.1:8080").CreateRemote();
+client.Add<StandardCodec>();  // 添加编解码器
+client.Open();
+
+// 发送并等待响应
+var response = await client.SendMessageAsync(payload, cancellationToken);
+```
+
+## 编解码器(粘包拆包)
+
+### 内置编解码器
+
+| 编解码器 | 场景 |
+| --------- | ------ |
+| `StandardCodec` | 4 字节头部(Flag+Seq+Length),请求响应匹配 |
+| `LengthFieldCodec` | 长度字段头部,可配置偏移和大小 |
+| `SplitDataCodec` | 分隔符拆包(默认 `\r\n`) |
+| `WebSocketCodec` | WebSocket 帧 |
+| `JsonCodec` | JSON 编解码(通常与其他 Codec 级联) |
+
+### 添加编解码器
+
+```csharp
+// 服务端
+server.Add<StandardCodec>();
+
+// 多层级联(顺序:底层先添加)
+server.Add<StandardCodec>();  // 底层:粘包拆包
+server.Add<JsonCodec>();      // 上层:JSON 编解码
+```
+
+### 管道数据流向
+
+```text
+接收:Socket → Codec1.Read → Codec2.Read → OnReceive
+发送:SendMessage → Codec2.Write → Codec1.Write → Socket
+```
+
+## SSL/TLS
+
+```csharp
+// 服务端
+var server = new NetServer
+{
+    Port = 443,
+    SslProtocol = SslProtocols.Tls12,
+    Certificate = new X509Certificate2("server.pfx", "password"),
+};
+
+// 客户端
+var client = new NetUri("tcp://host:443").CreateRemote();
+if (client is TcpSession tcp)
+    tcp.SslProtocol = SslProtocols.Tls12;
+```
+
+## 注意事项
+
+- 端口号 `0` 表示随机端口(测试时推荐)
+- `NetServer` 默认同时监听 IPv4 + IPv6
+- 会话内通过 `ServiceProvider` 获取 DI 服务
+- `CreateRemote()` 根据 URI 协议自动返回 `TcpSession`/`UdpServer`/`WebSocketClient`
+- 编解码器先添加的靠近 Socket 层,后添加的靠近业务层
+- `SendMessage` 通过管道编码,`Send` 直接发送原始数据
+- `SendMessageAsync` 发送并等待响应,需要匹配编解码器(如 `StandardCodec`)
Added +202 -0
diff --git a/.github/skills/security/SKILL.md b/.github/skills/security/SKILL.md
new file mode 100644
index 0000000..73f9ddb
--- /dev/null
+++ b/.github/skills/security/SKILL.md
@@ -0,0 +1,202 @@
+---
+name: security
+description: 使用 NewLife 安全模块进行哈希、AES/SM4 加密、RSA 签名和 JWT 令牌操作
+---
+
+# NewLife 安全加密使用指南
+
+## 适用场景
+
+- 数据哈希校验(MD5/SHA/CRC)
+- 对称加密(AES/SM4 国密)
+- 非对称加密与签名(RSA/ECDSA)
+- JWT 令牌生成与验证
+- 分布式令牌签名
+
+## 哈希
+
+### MD5
+
+```csharp
+// 字符串 MD5(返回 32 位十六进制字符串)
+var hash = "hello".MD5();
+
+// 16 位 MD5
+var hash16 = "hello".MD5_16();
+
+// 字节数组 MD5
+var hashBytes = data.MD5();
+
+// 文件 MD5
+var fileHash = new FileInfo("test.bin").MD5();
+```
+
+### SHA 系列
+
+```csharp
+// 普通 SHA
+var sha1 = data.SHA1(null);
+var sha256 = data.SHA256();
+var sha512 = data.SHA512(null);
+
+// HMAC 变体(传入 key)
+var hmac = data.SHA256(keyBytes);
+```
+
+### CRC 校验
+
+```csharp
+var crc32 = data.Crc();     // UInt32
+var crc16 = data.Crc16();   // UInt16
+```
+
+## 对称加密(AES)
+
+```csharp
+// AES-CBC 加密(默认 PKCS7 填充)
+var key = "1234567890123456".GetBytes();  // 16 字节 = AES-128
+var encrypted = Aes.Create().Encrypt(data, key);
+var decrypted = Aes.Create().Decrypt(encrypted, key);
+
+// 指定模式
+var encrypted = Aes.Create().Encrypt(data, key, CipherMode.ECB, PaddingMode.Zeros);
+```
+
+## 国密 SM4
+
+```csharp
+// SM4 加密(API 与 AES 完全一致)
+var key = "1234567890123456".GetBytes();  // 固定 16 字节
+var encrypted = SM4.Create().Encrypt(data, key, CipherMode.ECB);
+var decrypted = SM4.Create().Decrypt(encrypted, key, CipherMode.ECB);
+```
+
+## RSA
+
+### 密钥管理
+
+```csharp
+// 生成 RSA 密钥对
+var keys = RSAHelper.GenerateKey(2048);
+var privateKey = keys[0];  // XML 格式私钥
+var publicKey = keys[1];   // XML 格式公钥
+
+// 从 PEM/Base64/XML 自动识别加载
+var rsa = RSAHelper.Create(pemOrXmlOrBase64);
+```
+
+### 加解密
+
+```csharp
+var encrypted = RSAHelper.Encrypt(data, publicKey, fOAEP: true);
+var decrypted = RSAHelper.Decrypt(encrypted, privateKey, fOAEP: true);
+```
+
+### 签名与验签
+
+```csharp
+// SHA256 签名(推荐)
+var signature = data.SignSha256(privateKey);
+var valid = data.VerifySha256(publicKey, signature);
+
+// SHA512 签名
+var signature = data.SignSha512(privateKey);
+var valid = data.VerifySha512(publicKey, signature);
+```
+
+## JWT 令牌
+
+### 生成 JWT
+
+```csharp
+var builder = new JwtBuilder
+{
+    Algorithm = "HS256",
+    Secret = "your-secret-key-at-least-32-bytes-long!!",
+    Expire = DateTime.Now.AddHours(2),
+};
+
+// 添加声明
+builder.Subject = "user123";
+builder.Id = Guid.NewGuid().ToString();
+builder["role"] = "admin";
+builder["name"] = "张三";
+
+var token = builder.Encode(null);
+```
+
+### 解码验证 JWT
+
+```csharp
+var builder = new JwtBuilder
+{
+    Algorithm = "HS256",
+    Secret = "your-secret-key-at-least-32-bytes-long!!",
+};
+
+if (builder.TryDecode(token, out var msg))
+{
+    var subject = builder.Subject;
+    var role = builder["role"] as String;
+    var exp = builder.Expire;
+}
+else
+{
+    XTrace.WriteLine("JWT 验证失败:{0}", msg);
+}
+```
+
+### 使用 RSA 签名
+
+```csharp
+var builder = new JwtBuilder
+{
+    Algorithm = "RS256",
+    Secret = rsaPrivateKey,  // 签名用私钥
+};
+var token = builder.Encode(null);
+
+// 验证用公钥
+builder.Secret = rsaPublicKey;
+var valid = builder.TryDecode(token, out var msg);
+```
+
+## 分布式令牌(TokenProvider)
+
+```csharp
+var provider = new TokenProvider
+{
+    Key = "shared-secret-key",
+};
+
+// 生成令牌
+var token = provider.Encode("user123", DateTime.Now.AddHours(1));
+
+// 验证令牌
+if (provider.TryDecode(token, out var name, out var expire))
+    XTrace.WriteLine("用户 {0},过期 {1}", name, expire);
+```
+
+## 密码策略
+
+```csharp
+// MD5 密码提供者(默认)
+IPasswordProvider pp = new MD5PasswordProvider();
+var hash = pp.Hash("password");
+var valid = pp.Verify("password", hash);
+
+// 盐值密码提供者(更安全)
+IPasswordProvider pp = new SaltPasswordProvider();
+var hash = pp.Hash("password");
+var valid = pp.Verify("password", hash);
+```
+
+## 注意事项
+
+- **密钥管理**:禁止硬编码密钥,从配置或密钥管理服务获取
+- **ECB 模式**:仅适合单块数据,多块数据必须用 CBC/GCM
+- **MD5 不安全**:不适合密码存储,仅用于数据摘要/校验
+- **RSA 密钥长度**:新系统至少 2048 位
+- **JWT Secret**:HS256 至少 32 字节,过短会降低安全性
+- SM4 密钥固定 16 字节(128 位)
+- `SymmetricAlgorithm` 必须 Dispose,推荐 `using` 或局部使用
Added +183 -0
diff --git a/.github/skills/serialization/SKILL.md b/.github/skills/serialization/SKILL.md
new file mode 100644
index 0000000..dfd94c9
--- /dev/null
+++ b/.github/skills/serialization/SKILL.md
@@ -0,0 +1,183 @@
+---
+name: serialization
+description: 使用 NewLife 进行 JSON/XML/Binary/CSV 多格式序列化和反序列化
+---
+
+# NewLife 序列化使用指南
+
+## 适用场景
+
+- JSON 序列化/反序列化(API 通信、配置文件)
+- 二进制序列化(自定义协议、IoT 数据帧)
+- XML 序列化(配置/数据交换)
+- CSV 数据导入导出
+- 高性能零分配序列化(Span 序列化)
+
+## JSON 序列化
+
+### 基础用法
+
+```csharp
+// 序列化
+var json = user.ToJson();
+var json = user.ToJson(indented: true);  // 美化输出
+var json = user.ToJson(indented: false, nullValue: false, camelCase: true);
+
+// 反序列化
+var user = json.ToJsonEntity<User>();
+var obj = json.ToJsonEntity(typeof(User));
+
+// 解析为字典(不需要类型)
+var dict = json.DecodeJson();
+
+// 格式化美化
+var pretty = JsonHelper.Format(json);
+```
+
+### JsonOptions 精细控制
+
+```csharp
+var options = new JsonOptions
+{
+    Indented = true,
+    NullValue = false,      // 不输出 null 字段
+    CamelCase = true,       // 驼峰命名
+    EnumString = true,      // 枚举输出字符串
+    IgnoreDefault = true,   // 忽略默认值
+};
+var json = user.ToJson(options);
+```
+
+### 切换 JSON 引擎
+
+```csharp
+// 默认使用 FastJson(NewLife 内置)
+// 切换为 System.Text.Json
+JsonHelper.Default = new SystemJson();
+```
+
+## Binary 序列化
+
+### 读写操作
+
+```csharp
+// 序列化到流
+var bn = new Binary();
+bn.Write(myObj);
+var data = bn.GetBytes();
+
+// 从流反序列化
+var bn = new Binary(new MemoryStream(data));
+var obj = bn.Read<MyClass>();
+```
+
+### 协议配置
+
+```csharp
+var bn = new Binary
+{
+    IsLittleEndian = false,  // 大端(网络字节序)
+    EncodeInt = true,        // 7位变长编码整数
+    SizeWidth = 2,           // 集合长度用 2 字节
+    FullTime = true,         // DateTime 完整 8 字节
+};
+```
+
+### 自定义处理器
+
+```csharp
+var bn = new Binary();
+bn.AddHandler<MyCustomHandler>(priority: 10);
+```
+
+## Span 序列化(零分配)
+
+适用于 IoT 协议帧等需要零分配的高性能场景。
+
+### 定义可序列化类型
+
+```csharp
+public class MyFrame : ISpanSerializable
+{
+    public Byte Command { get; set; }
+    public UInt16 Length { get; set; }
+    public Byte[] Data { get; set; }
+
+    public Int32 Read(ReadOnlySpan<Byte> buffer)
+    {
+        var reader = new SpanReader(buffer);
+        Command = reader.ReadByte();
+        Length = reader.ReadUInt16();
+        Data = reader.ReadBytes(Length);
+        return reader.Position;
+    }
+
+    public Int32 Write(Span<Byte> buffer)
+    {
+        var writer = new SpanWriter(buffer);
+        writer.WriteByte(Command);
+        writer.WriteUInt16((UInt16)Data.Length);
+        writer.Write(Data);
+        return writer.Position;
+    }
+}
+```
+
+### 使用
+
+```csharp
+// 序列化
+using var pk = SpanSerializer.Serialize(frame);
+var bytes = pk.GetSpan().ToArray();
+
+// 反序列化
+var frame = SpanSerializer.Deserialize<MyFrame>(data);
+
+// 或直接用扩展方法
+using var pk = frame.ToPacket();
+frame.FromSpan(data);
+```
+
+## CSV 读写
+
+```csharp
+// 写入 CSV
+var csv = new CsvFile(filePath, true);
+csv.WriteLine("Name", "Age", "City");
+csv.WriteLine("张三", "25", "北京");
+csv.Dispose();
+
+// 读取 CSV
+var csv = new CsvFile(filePath, false);
+while (csv.ReadLine() is String[] line)
+{
+    var name = line[0];
+    var age = line[1].ToInt();
+}
+
+// CSV 数据库(增删改查)
+var db = new CsvDb<User>("users.csv");
+db.Add(new User { Name = "test" });
+var users = db.FindAll();
+```
+
+## Excel 读写
+
+```csharp
+// 读取 Excel(无需 Office)
+using var reader = new ExcelReader(filePath);
+var table = reader.ReadAll();  // 返回 DbTable
+
+// 写入 Excel
+using var writer = new ExcelWriter(filePath);
+writer.WriteHeader("Name", "Age");
+writer.WriteRow("张三", 25);
+```
+
+## 注意事项
+
+- `ToJson()` 默认不美化、包含 null、PascalCase
+- `ToJsonEntity<T>()` 返回可空,务必检查 null
+- Binary 序列化双方必须统一 `IsLittleEndian`/`SizeWidth`/`EncodeInt`
+- `SpanSerializer.Serialize` 返回 `IOwnerPacket`,**必须 Dispose** 归还缓冲区
+- CSV/Excel 读写器实现 `IDisposable`,配合 `using` 使用
Added +187 -0
diff --git a/.github/skills/timer-scheduling/SKILL.md b/.github/skills/timer-scheduling/SKILL.md
new file mode 100644
index 0000000..ae0372c
--- /dev/null
+++ b/.github/skills/timer-scheduling/SKILL.md
@@ -0,0 +1,187 @@
+---
+name: timer-scheduling
+description: 使用 NewLife TimerX 和 Cron 实现高精度定时任务和 Cron 调度
+---
+
+# NewLife 定时任务与调度使用指南
+
+## 适用场景
+
+- 周期性后台任务
+- Cron 表达式定时调度
+- 延迟执行一次性任务
+- 高精度定时器
+- 替代 System.Threading.Timer
+
+## TimerX 基本用法
+
+### 周期定时器
+
+```csharp
+// 同步回调:延迟 1 秒启动,每 60 秒执行一次
+var timer = new TimerX(DoWork, null, 1_000, 60_000);
+
+void DoWork(Object? state)
+{
+    // 定时执行的逻辑
+}
+
+// 异步回调
+var timer = new TimerX(async state =>
+{
+    await SyncDataAsync();
+}, null, 1_000, 60_000);
+
+// 释放定时器
+timer.Dispose();
+```
+
+### 延迟执行(一次性)
+
+```csharp
+// 延迟 5 秒执行一次(period = 0 表示不重复)
+var timer = new TimerX(state =>
+{
+    SendNotification();
+}, null, 5_000, 0);
+```
+
+### 绝对时间触发
+
+```csharp
+// 从明天凌晨 2 点开始,每 24 小时执行一次
+var startTime = DateTime.Today.AddDays(1).AddHours(2);
+var timer = new TimerX(DailyCleanup, null, startTime, 24 * 3600 * 1000);
+```
+
+## Cron 表达式调度
+
+### 表达式格式
+
+```text
+秒 分 时 天 月 星期 [年]
+```
+
+| 位置 | 字段 | 范围 | 特殊字符 |
+| ---- | ---- | ---- | -------- |
+| 1 | 秒 | 0-59 | , - * / |
+| 2 | 分 | 0-59 | , - * / |
+| 3 | 时 | 0-23 | , - * / |
+| 4 | 天 | 1-31 | , - * / |
+| 5 | 月 | 1-12 | , - * / |
+| 6 | 星期 | 0-6 | , - * / |
+
+### 常用示例
+
+```csharp
+// 每分钟执行
+var timer = new TimerX(DoWork, null, "0 * * * * *");
+
+// 每天凌晨 3 点
+var timer = new TimerX(DoWork, null, "0 0 3 * * *");
+
+// 每小时第 30 分钟
+var timer = new TimerX(DoWork, null, "0 30 * * * *");
+
+// 每周一和周五 9 点
+var timer = new TimerX(DoWork, null, "0 0 9 * * 1,5");
+
+// 每 5 分钟
+var timer = new TimerX(DoWork, null, "0 */5 * * * *");
+
+// 工作日 9-18 点每小时
+var timer = new TimerX(DoWork, null, "0 0 9-18 * * 1-5");
+
+// 多个 Cron 表达式(分号分隔)
+var timer = new TimerX(DoWork, null, "0 0 9 * * *;0 0 18 * * *");
+```
+
+### Cron 类直接使用
+
+```csharp
+var cron = new Cron("0 0 3 * * *");
+
+// 判断当前时间是否匹配
+if (cron.IsTime(DateTime.Now)) { /* 执行 */ }
+
+// 获取下一次执行时间
+var next = cron.GetNext(DateTime.Now);
+XTrace.WriteLine("下次执行:{0}", next);
+```
+
+## 在 IHostedService 中使用
+
+```csharp
+public class ScheduleService : IHostedService
+{
+    private TimerX? _syncTimer;
+    private TimerX? _cleanupTimer;
+
+    public Task StartAsync(CancellationToken cancellationToken)
+    {
+        // 每 30 秒同步数据
+        _syncTimer = new TimerX(SyncData, null, 1_000, 30_000);
+
+        // 每天凌晨 2 点清理
+        _cleanupTimer = new TimerX(Cleanup, null, "0 0 2 * * *");
+
+        return Task.CompletedTask;
+    }
+
+    public Task StopAsync(CancellationToken cancellationToken)
+    {
+        _syncTimer.TryDispose();
+        _cleanupTimer.TryDispose();
+        return Task.CompletedTask;
+    }
+
+    private void SyncData(Object? state) { /* ... */ }
+    private void Cleanup(Object? state) { /* ... */ }
+}
+```
+
+## 高级特性
+
+### 异步执行
+
+```csharp
+// Async = true 时回调在线程池中异步执行,不阻塞定时器调度
+var timer = new TimerX(DoWork, null, 1_000, 60_000) { Async = true };
+```
+
+### 绝对时间模式
+
+```csharp
+// Absolutely = true 时基于绝对时间计算下次执行,不受实际执行耗时影响
+var timer = new TimerX(DoWork, null, 1_000, 60_000) { Absolutely = true };
+```
+
+### 链路追踪
+
+```csharp
+var timer = new TimerX(DoWork, null, 1_000, 60_000)
+{
+    Tracer = tracer,
+    TracerName = "DataSync",  // Span 名称
+};
+```
+
+### 状态查询
+
+```csharp
+timer.NextTime    // 下次执行时间
+timer.Timers      // 已执行次数
+timer.Cost        // 最近执行耗时(毫秒)
+timer.Calling     // 是否正在执行
+timer.Period      // 执行间隔(可动态调整)
+```
+
+## 注意事项
+
+- TimerX 默认**同步串行**执行,上次未完成则跳过本次
+- 设置 `Async = true` 允许异步并发执行
+- `Period = 0` 表示只执行一次
+- Cron 支持秒级调度(标准 cron 只支持分钟级)
+- 多个 Cron 表达式用分号分隔
+- 定时器回调中的异常会被捕获并记录日志,不会中断定时器
+- 务必在 `StopAsync` 或 `Dispose` 中释放定时器
Added +157 -0
diff --git a/.github/skills/type-conversion/SKILL.md b/.github/skills/type-conversion/SKILL.md
new file mode 100644
index 0000000..5ac2e45
--- /dev/null
+++ b/.github/skills/type-conversion/SKILL.md
@@ -0,0 +1,157 @@
+---
+name: type-conversion
+description: 使用 NewLife 类型转换扩展方法进行安全高效的类型转换
+---
+
+# NewLife 类型转换与基础工具使用指南
+
+## 适用场景
+
+- 字符串转数值/日期等基础类型转换
+- 安全的类型转换(不抛异常,返回默认值)
+- 字符串操作与格式化
+- 池化 StringBuilder
+- 时间戳与运行时信息
+
+## 类型转换扩展
+
+### 核心方法
+
+```csharp
+// 字符串 → 数值(转换失败返回 0)
+var n = "123".ToInt();             // 123
+var n = "abc".ToInt();             // 0
+var n = "abc".ToInt(-1);           // -1(指定默认值)
+
+// 字符串 → 布尔
+var b = "true".ToBoolean();        // true
+var b = "1".ToBoolean();           // true
+var b = "yes".ToBoolean();         // true
+
+// 字符串 → 浮点
+var d = "3.14".ToDouble();         // 3.14
+
+// 字符串 → Int64
+var l = "9999999999".ToLong();     // 9999999999L
+
+// 字符串 → DateTime
+var dt = "2026-03-19".ToDateTime();
+var dt = "2026-03-19 10:30:00".ToDateTime();
+
+// 字符串 → 十六进制字节数组
+var bytes = "48656C6C6F".ToHex();
+
+// 字节数组 → 十六进制字符串
+var hex = bytes.ToHex();
+var hex = bytes.ToHex("-");        // 带分隔符
+```
+
+### 对象转换
+
+```csharp
+// 通用转换
+var val = obj.ChangeType<Int32>();
+var val = obj.ChangeType(typeof(Int32));
+
+// 枚举转换
+var level = "Info".ToEnum<LogLevel>();
+```
+
+### 与标准库对比
+
+| NewLife | 标准库 | 区别 |
+| ------ | ------ | ---- |
+| `"123".ToInt()` | `Int32.Parse("123")` | 不抛异常,返回默认值 |
+| `"abc".ToInt(0)` | `Int32.TryParse(...)` | 更简洁 |
+| `"true".ToBoolean()` | `Boolean.Parse("true")` | 支持 "1"/"yes"/"on" |
+| `obj.ChangeType<T>()` | `Convert.ChangeType()` | 更安全,支持更多类型 |
+
+## 字符串工具
+
+### 常用扩展
+
+```csharp
+// 空值判断
+if (str.IsNullOrEmpty()) { }
+if (str.IsNullOrWhiteSpace()) { }
+
+// 截取
+var first10 = str.Cut(10);          // 截取前 10 字符
+var sub = str.Substring(5, 10);
+
+// 编码
+var base64 = str.ToBase64();
+var original = base64.FromBase64();
+
+// URL 编码
+var encoded = str.UrlEncode();
+var decoded = encoded.UrlDecode();
+
+// 格式化(F 扩展方法)
+var msg = "Hello {0}, you are {1}".F("test", 25);
+
+// HTML 编码
+var safe = str.HtmlEncode();
+```
+
+## Pool.StringBuilder
+
+```csharp
+// NewLife 池化 StringBuilder(替代 new StringBuilder())
+var sb = Pool.StringBuilder.Get();
+sb.Append("Hello ");
+sb.Append("World");
+var result = sb.Put(true);  // 返回字符串并归还到池
+
+// 也可手动归还
+var sb = Pool.StringBuilder.Get();
+try
+{
+    sb.Append("...");
+    return sb.ToString();
+}
+finally
+{
+    sb.Put();  // 归还(不取字符串)
+}
+```
+
+## 时间戳
+
+```csharp
+// 高精度时间戳(兼容 .NET 4.5,替代 Environment.TickCount64)
+var tick = Runtime.TickCount64;
+
+// 计算耗时
+var start = Runtime.TickCount64;
+DoWork();
+var elapsed = Runtime.TickCount64 - start;
+XTrace.WriteLine("耗时 {0}ms", elapsed);
+```
+
+## 运行时信息
+
+```csharp
+// 机器信息
+var mi = MachineInfo.Current;
+mi.CpuID         // CPU 标识
+mi.Memory        // 总内存(字节)
+mi.AvailableMemory // 可用内存
+mi.CpuRate       // CPU 使用率
+mi.Temperature   // CPU 温度
+mi.Board         // 主板信息
+
+// 运行时
+Runtime.IsWindows   // 是否 Windows
+Runtime.IsLinux     // 是否 Linux
+Runtime.ProcessId   // 当前进程 ID
+Runtime.CachePath   // 缓存目录
+```
+
+## 注意事项
+
+- 所有 `ToXxx()` 扩展方法**不会抛异常**,转换失败返回默认值
+- `ToInt()` / `ToLong()` / `ToDouble()` 第一个参数为失败时的默认值
+- `Pool.StringBuilder.Get()` 获取的 StringBuilder 必须调用 `Put()` 归还
+- `Runtime.TickCount64` 在所有 .NET 版本可用,`Environment.TickCount64` 仅 .NET 5+
+- 这些扩展方法定义在 `NewLife` 命名空间,引用 NewLife.Core 后自动可用
Renamed +0 -0
docs/newlife-core-analysis-roadmap.md → docs/newlife-analysis-roadmap.md
diff --git a/docs/newlife-core-analysis-roadmap.md b/docs/newlife-analysis-roadmap.md
similarity index 100%
rename from docs/newlife-core-analysis-roadmap.md
rename to docs/newlife-analysis-roadmap.md
Renamed +0 -0
docs/newlife-core-source-map.md → docs/newlife-source-map.md
diff --git a/docs/newlife-core-source-map.md b/docs/newlife-source-map.md
similarity index 100%
rename from docs/newlife-core-source-map.md
rename to docs/newlife-source-map.md
Modified +117 -55
diff --git a/README.md b/README.md
index 1ded7e3..75932aa 100644
--- a/README.md
+++ b/README.md
@@ -1,72 +1,134 @@
 # NewLife Skills
 
-这个仓库用于沉淀 **NewLife 团队与个人长期可复用的技能资产**,包括:知识、方法、规范、模板,以及后续可扩展的脚本与自动化流程。
+**NewLife Copilot 资产统一管理库**——集中管理 NewLife 系列项目所有可复用的 Copilot 资产:技能、指令、提示词、智能体。
 
-## 目标
+克隆到任意机器后,执行一条脚本即可将全部资产安装到 VS Code 用户数据目录,**无需在每个项目里各放一份 `.github`**。
 
-- 让技能可以被 Git 管理、版本化、跨设备同步。
-- 让技能既适合人类阅读维护,也尽量兼容 Copilot 直接加载。
-- 让“经验捕获 → 知识融合 → 再发布”形成闭环。
+---
 
-## 推荐结构
+## 快速开始
 
-```text
-.github/
-  skills/                    # 直接给 Copilot 使用的运行态技能
-    benchmark-testing/
-    coding-standards/
-    compatibility-checks/
-    capture-conventions/
-    development-workflow/
-    merge-skill-knowledge/
-    write-tech-docs/
-docs/
-  newlife-core-analysis-roadmap.md
-  newlife-core-source-map.md
-  skill-system-design.md     # 技能体系设计说明
-scripts/
-  sync-skills-to-user.ps1    # 同步到用户级 Copilot 技能目录
+### 安装到本机(Win10/Win11 + VS Code + GitHub Copilot)
+
+```powershell
+# 克隆此仓库
+git clone https://github.com/NewLifeX/NewLife.Skills.git
+cd NewLife.Skills
+
+# 安装全部 Copilot 资产到用户级目录
+.\scripts\install-copilot-assets.ps1
 ```
 
-## 设计原则
+安装完成后**重启 VS Code**,所有项目即可使用以下资产,无需在每个项目中放 `.github` 目录。
+
+---
+
+## 资产清单
+
+### Skills(技能)
+
+存放于 `.github/skills/`,每个技能一个子目录,含 `SKILL.md` 详细指南。共 59 个技能文件夹。
+
+**快速使用指南(usage 类)**——按需快速上手,代码示例为主:
+
+| 技能目录 | 覆盖领域 |
+|---------|---------|
+| `caching` | ICache/MemoryCache/Redis 统一缓存接口 |
+| `logging-tracing` | ILog/XTrace 日志与 ITracer/DefaultTracer 链路追踪 |
+| `networking` | NetServer/NetSession TCP/UDP/WebSocket 网络编程 |
+| `serialization` | JSON/Binary/Span/CSV 序列化 |
+| `configuration` | Config&lt;T&gt;/IConfigProvider/HttpConfigProvider 配置管理 |
+| `http-client` | ApiHttpClient 多节点 HTTP 客户端与负载均衡 |
+| `dependency-injection` | ObjectContainer/Host/Plugin/Actor 依赖注入与宿主 |
+| `timer-scheduling` | TimerX/Cron 高级定时调度 |
+| `security` | Hash/AES/SM4/RSA/JWT/TokenProvider 安全与加密 |
+| `type-conversion` | ToInt/ToBoolean/StringHelper/Pool.StringBuilder 类型转换与工具 |
+
+**深度设计指南(architecture 类)**——涵盖 XCode/Cube/Redis/MQTT/Net/序列化/安全/定时器等所有领域,共 49 个技能文件夹。代表性技能:
+
+| 技能目录 | 覆盖领域 |
+|---------|---------|
+| `xcode-entity-orm` | NewLife.XCode 实体 CRUD 开发 |
+| `xcode-data-modeling` | XCode Model.xml 数据建模 |
+| `cube-mvc-backend` | NewLife.Cube MVC 后台管理系统 |
+| `redis-client` | NewLife.Redis 高性能 Redis 客户端 |
+| `network-server-sessions` | NetServer/NetSession 高性能网络服务器 |
+| `cache-provider-architecture` | ICache 统一缓存接口与分布式锁 |
+| `security-crypto-patterns` | Hash/AES/RSA/JWT 加密安全 |
+| `stardust-platform` | 星尘分布式服务平台接入 |
+| `agent-service` | NewLife.Agent 跨平台系统服务 |
+| `benchmark-testing` | BenchmarkDotNet 性能基准测试 |
+
+### Instructions(指令)
 
-1. **运行态扁平,知识态分层**
-   - Copilot 直接识别的技能目录建议放在 `.github/skills/<skill-name>/`,保持扁平。
-   - 更细的知识分层、分类、归档,放在 `docs/` 或未来扩展的知识目录中。
+存放于 `.github/instructions/`,触发关键词时 Copilot 自动加载:
 
-2. **路径英文,内容中文优先**
-   - 目录名、技能名、脚本名优先使用英文 kebab-case,便于兼容性与跨平台。
-   - `SKILL.md` 正文、说明文档、示例内容,完全可以使用中文。
+| 文件 | 触发场景 |
+|------|---------|
+| `xcode.instructions.md` | XCode / 数据库 / Model.xml |
+| `net.instructions.md` | NetServer / 网络编程 |
+| `benchmark.instructions.md` | 性能测试 / BenchmarkDotNet |
+| `development.instructions.md` | 新建系统 / 需求分析 / 架构设计 |
+| `caching.instructions.md` | ICache / MemoryCache / Redis 缓存 |
+| `serialization.instructions.md` | JSON / Binary 序列化 |
+| `security.instructions.md` | 加密 / Hash / JWT / RSA |
+| `remoting.instructions.md` | ApiHttpClient / RPC / 负载均衡 |
+| `configuration.instructions.md` | Config / IConfigProvider / 配置中心 |
+
+### Prompts(提示词)
+
+存放于 `.github/prompts/`:
+
+| 文件 | 用途 |
+|------|------|
+| `doc-writer.prompt.md` | 为 C# 代码生成高质量 Markdown 文档 |
+
+### Agents(智能体)
+
+存放于 `.github/agents/`:
+
+| 文件 | 用途 |
+|------|------|
+| `newlife-expert.agent.md` | NewLife 全生态技术专家 |
+| `code-review.agent.md` | NewLife 代码审查(8维度检查) |
+| `project-init.agent.md` | NewLife 新项目初始化助手 |
+| `release-prep.agent.md` | 开源库月度发版准备(ChangeLog/版本号/README) |
+
+---
+
+## 仓库结构
+
+```text
+.github/
+  copilot-instructions.md      # NewLife 全局 Copilot 协作规范(含编码规范)
+  agents/                      # 智能体定义 (*.agent.md)  → chatmodes/
+  instructions/                # 场景指令 (*.instructions.md)  → prompts/
+  prompts/                     # 提示词模板 (*.prompt.md)  → prompts/
+  skills/                      # 技能文件夹,全部为 <name>/SKILL.md 格式 → prompts/skills/
+docs/                          # 分析文档、设计说明
+scripts/
+  install-copilot-assets.ps1   # 安装脚本(主入口)
+  sync-skills-to-user.ps1      # 旧名称兼容包装器
+```
 
-3. **技能分三层**
-   - 捕获型:从代码、目录、提交、问答中提炼稳定规律。
-   - 融合型:把新发现与已有知识合并,避免重复和冲突。
-   - 生产型:在写代码、写文档、做评审时直接调用。
+---
 
-## 推荐工作流
+## 安装说明
 
-1. 在仓库或目录上运行“捕获型技能”。
-2. 生成候选知识条目。
-3. 调用“融合型技能”与已有技能文件合并。
-4. 产出新的稳定技能文件并提交 Git。
-5. 通过脚本同步到用户级 Copilot 技能目录。
+`install-copilot-assets.ps1` 将资产复制到以下 VS Code 用户数据目录:
 
-## 与 Copilot 的关系
+| 资产类型 | 目标路径 |
+|---------|---------|
+| Skills (`<name>/SKILL.md` 文件夹) | `%APPDATA%\Code\User\prompts\skills\` |
+| Instructions (`*.instructions.md`) | `%APPDATA%\Code\User\prompts\` |
+| Prompts (`*.prompt.md`) | `%APPDATA%\Code\User\prompts\` |
+| Agents (`*.agent.md`) | `%APPDATA%\Code\User\chatmodes\` |
+| 全局指令 (`copilot-instructions.md`) | `%APPDATA%\Code\User\prompts\newlife-global.instructions.md` |
 
-- 当前仓库中的 `.github/skills/` 适合在**打开本仓库时**直接被 Copilot 使用。
-- 如果希望跨项目全局复用,建议把技能同步到用户级技能目录。
-- `scripts/sync-skills-to-user.ps1` 提供了一个起点,后续可接入计划任务、登录脚本或你自己的工具链。
+---
 
-## 下一步建议
+## 维护说明
 
-- 先沉淀 10~20 个高价值技能,而不是一次铺满所有类别。
-- 优先顺序建议:
-  1. `capture-conventions`
-  2. `merge-skill-knowledge`
-  3. `write-tech-docs`
-  4. `coding-standards`
-  5. `compatibility-checks`
-  6. `development-workflow`
-  7. `benchmark-testing`
-  8. 语言/框架专项技能(如 `csharp-style`, `xcode-repo-analysis`)
-  9. 发布、评审、问题定位等流程型技能
+1. 从其他 NewLife 仓库(如 `.github/` 目录)学到新规范后,在此库中统一更新。
+2. 更新后重新运行 `install-copilot-assets.ps1` 即可覆盖更新本机资产。
+3. 提交到 Git,其他机器 `git pull` 后再次运行脚本即可同步。
\ No newline at end of file
Added +171 -0
diff --git a/scripts/install-copilot-assets.ps1 b/scripts/install-copilot-assets.ps1
new file mode 100644
index 0000000..84503c0
--- /dev/null
+++ b/scripts/install-copilot-assets.ps1
@@ -0,0 +1,171 @@
+<#
+.SYNOPSIS
+    安装 NewLife Copilot 资产到 VSCode 用户数据目录,使其对本机所有项目生效。
+
+.DESCRIPTION
+    将 .github/ 下的 skills/instructions/prompts/agents 安装到 VSCode 用户数据目录:
+      Skills        → %APPDATA%\Code\User\prompts\skills\
+      Instructions  → %APPDATA%\Code\User\prompts\
+      Prompts       → %APPDATA%\Code\User\prompts\
+      Agents        → %APPDATA%\Code\User\chatmodes\
+
+    安装后无需在每个项目都放 .github 目录,Copilot 即可使用全部资产。
+
+    支持平台:Win10 / Win11 + VS Code + GitHub Copilot Chat
+
+.PARAMETER RepoRoot
+    仓库根目录,默认为脚本目录的父目录。
+
+.PARAMETER Clean
+    安装前清空对应目标目录(慎用,会删除其他来源的同名文件)。
+
+.EXAMPLE
+    .\install-copilot-assets.ps1
+    .\install-copilot-assets.ps1 -Clean
+#>
+param(
+    [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path,
+    [switch]$Clean
+)
+
+$ErrorActionPreference = "Stop"
+Set-StrictMode -Version Latest
+
+$githubDir   = Join-Path $RepoRoot ".github"
+$userDataDir = Join-Path $env:APPDATA "Code\User"
+
+# ── Source ────────────────────────────────────────────────────────────────────
+$skillsSrc      = Join-Path $githubDir "skills"
+$instructionsSrc = Join-Path $githubDir "instructions"
+$promptsSrc     = Join-Path $githubDir "prompts"
+$agentsSrc      = Join-Path $githubDir "agents"
+$globalInstrSrc = Join-Path $githubDir "copilot-instructions.md"
+
+# ── Destination ───────────────────────────────────────────────────────────────
+$skillsDst  = Join-Path $userDataDir "prompts\skills"
+$promptsDst = Join-Path $userDataDir "prompts"
+$agentsDst  = Join-Path $userDataDir "chatmodes"
+
+# ── Helpers ───────────────────────────────────────────────────────────────────
+function EnsureDir ([string]$Path) {
+    if (-not (Test-Path $Path)) {
+        New-Item -ItemType Directory -Path $Path -Force | Out-Null
+    }
+}
+
+function WriteStep ([string]$Msg) {
+    Write-Host "    $Msg" -ForegroundColor DarkCyan
+}
+
+# ── Banner ────────────────────────────────────────────────────────────────────
+Write-Host ""
+Write-Host "=== NewLife Copilot 资产安装 ===" -ForegroundColor Green
+Write-Host "  仓库: $RepoRoot"
+Write-Host "  目标: $userDataDir"
+Write-Host ""
+
+if (-not (Test-Path $githubDir)) {
+    Write-Error "未找到 .github 目录: $githubDir"
+    exit 1
+}
+
+$installed = 0
+
+# ─── 1. Skills ────────────────────────────────────────────────────────────────
+# 所有 Skills 均为 <name>/SKILL.md 文件夹格式 → prompts\skills\<name>\
+Write-Host "[1/5] Skills" -ForegroundColor Yellow
+EnsureDir $skillsDst
+EnsureDir $promptsDst  # 后续步骤(Instructions/Prompts)也需要此目录,提前创建
+
+if (Test-Path $skillsSrc) {
+    # 所有 Skills 均为 <name>/SKILL.md 文件夹格式
+    $folders = Get-ChildItem -Path $skillsSrc -Directory
+    foreach ($folder in $folders) {
+        $dst = Join-Path $skillsDst $folder.Name
+        if ($Clean -and (Test-Path $dst)) { Remove-Item -Path $dst -Recurse -Force }
+        EnsureDir $dst
+        Copy-Item -Path (Join-Path $folder.FullName "*") -Destination $dst -Recurse -Force
+        WriteStep "skill: $($folder.Name)"
+        $installed++
+    }
+} else {
+    Write-Host "    (跳过:$skillsSrc 不存在)" -ForegroundColor DarkGray
+}
+
+# ─── 2. Instructions ──────────────────────────────────────────────────────────
+Write-Host "[2/5] Instructions" -ForegroundColor Yellow
+
+if (Test-Path $instructionsSrc) {
+    $files = Get-ChildItem -Path $instructionsSrc -Filter "*.instructions.md" -File
+    if ($Clean) {
+        Get-ChildItem -Path $promptsDst -Filter "*.instructions.md" -File | Remove-Item -Force
+    }
+    foreach ($f in $files) {
+        Copy-Item -Path $f.FullName -Destination $promptsDst -Force
+        WriteStep "$($f.Name)"
+        $installed++
+    }
+} else {
+    Write-Host "    (跳过:$instructionsSrc 不存在)" -ForegroundColor DarkGray
+}
+
+# ─── 3. Prompts ───────────────────────────────────────────────────────────────
+Write-Host "[3/5] Prompts" -ForegroundColor Yellow
+
+if (Test-Path $promptsSrc) {
+    $files = Get-ChildItem -Path $promptsSrc -Filter "*.prompt.md" -File
+    foreach ($f in $files) {
+        Copy-Item -Path $f.FullName -Destination $promptsDst -Force
+        WriteStep "$($f.Name)"
+        $installed++
+    }
+} else {
+    Write-Host "    (跳过:$promptsSrc 不存在)" -ForegroundColor DarkGray
+}
+
+# ─── 4. Agents / Chat Modes ───────────────────────────────────────────────────
+Write-Host "[4/5] Agents" -ForegroundColor Yellow
+EnsureDir $agentsDst
+
+if (Test-Path $agentsSrc) {
+    if ($Clean) {
+        Get-ChildItem -Path $agentsDst -Filter "*.agent.md" -File | Remove-Item -Force
+    }
+    $files = Get-ChildItem -Path $agentsSrc -Filter "*.agent.md" -File
+    foreach ($f in $files) {
+        Copy-Item -Path $f.FullName -Destination $agentsDst -Force
+        WriteStep "$($f.Name)"
+        $installed++
+    }
+} else {
+    Write-Host "    (跳过:$agentsSrc 不存在)" -ForegroundColor DarkGray
+}
+
+# ─── 5. 全局 Copilot 指令 ─────────────────────────────────────────────────────
+# copilot-instructions.md 是仓库级文件格式(无 front-matter),
+# 复制时注入 applyTo: "**" 头部,使其作为用户级 .instructions.md 对所有工作区生效
+Write-Host "[5/5] 全局 Copilot 指令" -ForegroundColor Yellow
+
+if (Test-Path $globalInstrSrc) {
+    $content = Get-Content -Path $globalInstrSrc -Raw -Encoding UTF8
+    $wrapped = "---`napplyTo: `"**`"`n---`n" + $content
+    $dstFile = Join-Path $promptsDst "newlife-global.instructions.md"
+    [System.IO.File]::WriteAllText($dstFile, $wrapped, [System.Text.UTF8Encoding]::new($false))
+    WriteStep "newlife-global.instructions.md"
+    $installed++
+} else {
+    Write-Host "    (跳过:$globalInstrSrc 不存在)" -ForegroundColor DarkGray
+}
+
+# ─── 完成 ─────────────────────────────────────────────────────────────────────
+Write-Host ""
+Write-Host "=== 安装完成,共 $installed 项 ===" -ForegroundColor Green
+Write-Host ""
+Write-Host "安装路径:" -ForegroundColor White
+Write-Host "  Skills      : $skillsDst"
+Write-Host "  Instructions: $promptsDst  (*.instructions.md)"
+Write-Host "  Prompts     : $promptsDst  (*.prompt.md)"
+Write-Host "  Agents      : $agentsDst"
+Write-Host ""
+Write-Host "重启 VS Code 后即可在所有项目中使用以上资产。" -ForegroundColor Gray
+Write-Host ""
Modified +9 -33
diff --git a/scripts/sync-skills-to-user.ps1 b/scripts/sync-skills-to-user.ps1
index 2099e62..aae58e3 100644
--- a/scripts/sync-skills-to-user.ps1
+++ b/scripts/sync-skills-to-user.ps1
@@ -1,34 +1,10 @@
-param(
-    [string]$Source = (Join-Path $PSScriptRoot "..\.github\skills"),
-    [string]$Destination = (Join-Path $HOME ".copilot\skills"),
-    [switch]$Clean
-)
-
-$sourcePath = (Resolve-Path $Source).Path
-
-if (-not (Test-Path $sourcePath)) {
-    throw "Source skills folder not found: $Source"
-}
-
-if (-not (Test-Path $Destination)) {
-    New-Item -ItemType Directory -Path $Destination -Force | Out-Null
+# 此脚本已改名为 install-copilot-assets.ps1,本文件保留为兼容入口。
+# This script has been renamed to install-copilot-assets.ps1.
+param([switch]$Clean)
+
+$newScript = Join-Path $PSScriptRoot "install-copilot-assets.ps1"
+if (Test-Path $newScript) {
+    & $newScript @PSBoundParameters
+} else {
+    Write-Error "未找到新脚本: $newScript"
 }
-
-$skillFolders = Get-ChildItem -Path $sourcePath -Directory
-
-foreach ($folder in $skillFolders) {
-    $target = Join-Path $Destination $folder.Name
-
-    if ($Clean -and (Test-Path $target)) {
-        Remove-Item -Path $target -Recurse -Force
-    }
-
-    if (-not (Test-Path $target)) {
-        New-Item -ItemType Directory -Path $target -Force | Out-Null
-    }
-
-    Copy-Item -Path (Join-Path $folder.FullName "*") -Destination $target -Recurse -Force
-    Write-Host "Synced skill: $($folder.Name) -> $target"
-}
-
-Write-Host "Done. Skills synced to $Destination"