diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/BootstrapBlazor.LLMsDocs.Cli.csproj b/tools/BootstrapBlazor.LLMsDocs.Cli/BootstrapBlazor.LLMsDocs.Cli.csproj
index bccd1ad0..2bd3ea16 100644
--- a/tools/BootstrapBlazor.LLMsDocs.Cli/BootstrapBlazor.LLMsDocs.Cli.csproj
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/BootstrapBlazor.LLMsDocs.Cli.csproj
@@ -1,7 +1,7 @@
- 10.0.1
+ 10.0.2
Exe
net10.0
false
@@ -28,4 +28,10 @@
+
+
+
+
+
+
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/CommandFactory.cs b/tools/BootstrapBlazor.LLMsDocs.Cli/CommandFactory.cs
index 23ace0fa..b578d5c4 100644
--- a/tools/BootstrapBlazor.LLMsDocs.Cli/CommandFactory.cs
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/CommandFactory.cs
@@ -153,11 +153,11 @@ private static Command BuildInstructionsCommand()
private static Command BuildInstallCommand()
{
- var client = new Option("--client") { Description = "Target client: claude | cursor | all (default all)." };
+ var client = new Option("--client") { Description = "Target client: claude | cursor | trae | codex | all (default all)." };
var scope = new Option("--scope") { Description = "Where to write: project (cwd, default) or user (home)." };
var target = new Option("--target") { Description = "Override base directory to write into." };
var force = new Option("--force") { Description = "Overwrite existing files." };
- var cmd = new Command("install", "Install agent discovery artifacts (Claude Code skill / Cursor rules).")
+ var cmd = new Command("install", "Install agent discovery artifacts (Claude Code skill / Cursor rules / Trae skill / Codex AGENTS.md).")
{
client, scope, target, force
};
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/README.md b/tools/BootstrapBlazor.LLMsDocs.Cli/README.md
index 4261db40..54ea7ae8 100644
--- a/tools/BootstrapBlazor.LLMsDocs.Cli/README.md
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/README.md
@@ -2,7 +2,7 @@
一个轻量命令行工具,用于从 [www.blazor.zone/llms](https://www.blazor.zone/llms)
拉取 BootstrapBlazor 组件的**官方 API 文档**(参数、事件回调、公开方法、源码链接),
-供 AI agent(Claude Code / Cursor 等经 Bash 调用)和开发者查询。
+供 AI agent(Claude Code / Cursor / Trae / Codex 等经 Bash 调用)和开发者查询。
组件文档由官网的 `BootstrapBlazor.LLMsDocsGenerator`(生产者,CI 侧用 Roslyn 生成并发布)产出,
本工具是**消费者**:只负责按需 HTTP 拉取已生成的 `.txt` 文档并本地缓存,
@@ -132,24 +132,34 @@ bb-llms get Button --base-url ./wwwroot/llms
bb-llms instructions # 打印可粘贴进 CLAUDE.md / AGENTS.md 的通用片段
bb-llms install --client claude # 写 .claude/skills/bootstrapblazor/SKILL.md
bb-llms install --client cursor # 写 .cursor/rules/bootstrapblazor.mdc
-bb-llms install --client all # 两者都写(默认)
+bb-llms install --client trae # 写 .trae/skills/bootstrapblazor/SKILL.md
+bb-llms install --client codex # 写 AGENTS.md(user scope 为 ~/.codex/AGENTS.md)
+bb-llms install --client all # 四者都写(默认)
```
`install` 选项:
```
---client claude|cursor|all 目标客户端(默认 all)
+--client claude|cursor|trae|codex|all 目标客户端(默认 all)
--scope project|user project=当前目录(默认),user=用户主目录
--target 覆盖写入的根目录
--force 覆盖已存在的文件(默认存在则跳过)
```
-三套生态接入方式:
+五套生态接入方式:
- **Claude Code**:`bb-llms install --client claude` 写入一个 skill,Claude Code 会根据其
`description` 在任务涉及 BootstrapBlazor 组件时**自动加载**并调用 `bb-llms`,
等效于 MCP server 的自动发现。
- **Cursor**:`bb-llms install --client cursor` 写入项目规则(匹配 `*.razor` / `*.razor.cs`)。
+- **Trae**:`bb-llms install --client trae` 写入一个 skill(`.trae/skills/bootstrapblazor/SKILL.md`)。
+ Trae 的 skill 与 Claude 同构(同样的 `SKILL.md` + name/description frontmatter,按描述**自动匹配**),
+ 因此复用同一套模板。
+- **Codex**:`bb-llms install --client codex` 写入 `AGENTS.md`(project scope 为仓库根目录的
+ `AGENTS.md`,user scope 为 `~/.codex/AGENTS.md`)。Codex 没有独立的 skill/规则机制,统一读 `AGENTS.md`,
+ 因此复用 `instructions` 的通用片段。
+ > ⚠️ `AGENTS.md` 是手工维护的共享文件,**默认存在则跳过**;`--force` 会整文件覆盖,原有内容会丢失。
+ > 已有 `AGENTS.md` 时,建议改用 `bb-llms instructions` 把片段手动粘进去。
- **通用 / 其他 agent**:把 `bb-llms instructions` 的输出粘进项目的 `CLAUDE.md` / `AGENTS.md`。
典型流程(在你的 Blazor 项目根目录):
@@ -180,6 +190,18 @@ dotnet tool install -g --add-source ./bin/Release BootstrapBlazor.LLMsDocs.Cli
bb-llms get Table
```
+### 修改发现层模板
+
+`instructions` / `install` 输出的模板正文是 `Templates/` 下的独立文件,**直接编辑这些文件即可**,无需改 C# 代码:
+
+| 文件 | 对应命令 |
+|---|---|
+| `Templates/instructions.md` | `bb-llms instructions`(粘进 CLAUDE.md / AGENTS.md 的片段)、`bb-llms install --client codex`(写 AGENTS.md) |
+| `Templates/SKILL.md` | `bb-llms install --client claude` / `--client trae`(Claude / Trae skill) |
+| `Templates/bootstrapblazor.mdc` | `bb-llms install --client cursor`(Cursor 规则) |
+
+这些文件以**嵌入资源**编入程序集(见 `.csproj`),因此全局安装后工具仍能在运行时读取到,无需依赖项目源码目录。改完重新 `dotnet build` / `dotnet pack` 即生效。
+
---
## 设计说明:运行时 vs 数据
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/Scaffolder.cs b/tools/BootstrapBlazor.LLMsDocs.Cli/Scaffolder.cs
index 3a2ea2a3..5f36b29b 100644
--- a/tools/BootstrapBlazor.LLMsDocs.Cli/Scaffolder.cs
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/Scaffolder.cs
@@ -1,3 +1,6 @@
+using System.Reflection;
+using System.Text;
+
namespace BootstrapBlazor.LLMsDocs.Cli;
///
@@ -5,83 +8,32 @@ namespace BootstrapBlazor.LLMsDocs.Cli;
/// bb-llms CLI exists and when to use it. A plain CLI on PATH is
/// invisible to an agent unless an instruction file points at it; these
/// templates recover the auto-discovery that an MCP server would provide.
+///
+/// The template bodies are maintained as editable Markdown files under
+/// Templates/ and embedded into the assembly (see the .csproj), so they
+/// can be edited like normal docs instead of inline C# string literals while
+/// still being available to the globally-installed tool at runtime.
///
internal static class Scaffolder
{
/// Snippet to paste into a project's CLAUDE.md / AGENTS.md.
- public const string GenericSnippet = """
-## BootstrapBlazor 组件文档
-
-需要 BootstrapBlazor 组件的参数 / 事件 / 公开方法时,使用 `bb-llms` CLI 获取官方文档,不要凭记忆臆造 API:
-
-- 查找组件名:`bb-llms search <关键词>`
-- 获取组件文档:`bb-llms get `(例:`bb-llms get Table`)
-- 列出全部组件:`bb-llms list`
-
-文档源默认 https://www.blazor.zone/llms ,按需联网拉取并本地缓存;可用环境变量 `BB_LLMS_BASE_URL` 或 `--base-url` 指向自建/本地源。
-""";
-
- /// Claude Code skill (.claude/skills/bootstrapblazor/SKILL.md).
- public const string SkillMarkdown = """
----
-name: bootstrapblazor
-description: 涉及 BootstrapBlazor 组件(参数、事件回调、公开方法、用法)时使用,通过 bb-llms CLI 获取官方组件 API 文档,避免臆造参数。
----
-
-# BootstrapBlazor 组件文档查询
-
-当任务涉及 BootstrapBlazor 组件(编写或修改 .razor、配置组件参数、调用组件方法等)时,优先用 `bb-llms` 获取**权威**组件 API。
-
-## 用法
-
-1. 不确定组件名时先搜索:
- ```bash
- bb-llms search <关键词>
- ```
-2. 获取某组件的参数 / 事件 / 方法文档:
- ```bash
- bb-llms get # 例:bb-llms get Table
- ```
-3. 浏览全部组件:
- ```bash
- bb-llms list
- ```
-
-输出为 Markdown(参数表、事件回调、公开方法、GitHub 源码链接)。文档源默认 https://www.blazor.zone/llms ,自动本地缓存;可用环境变量 `BB_LLMS_BASE_URL` 或 `--base-url` 指向自建/本地源。
+ public static string GenericSnippet => ReadTemplate("instructions.md");
-## 前置条件
-
-需已安装该工具(命令名 `bb-llms`):
-
-```bash
-dotnet tool install -g BootstrapBlazor.LLMsDocs.Cli
-```
-""";
+ ///
+ /// Skill manifest shared by Claude Code (.claude/skills/bootstrapblazor/SKILL.md)
+ /// and Trae (.trae/skills/bootstrapblazor/SKILL.md): both use the same SKILL.md
+ /// layout with name/description frontmatter, auto-matched by description.
+ ///
+ public static string SkillMarkdown => ReadTemplate("SKILL.md");
/// Cursor project rule (.cursor/rules/bootstrapblazor.mdc).
- public const string CursorRule = """
----
-description: 涉及 BootstrapBlazor 组件时,用 bb-llms CLI 获取官方组件 API 文档
-globs: ["**/*.razor", "**/*.razor.cs"]
-alwaysApply: false
----
-
-# BootstrapBlazor 组件文档
-
-编写或修改 BootstrapBlazor 组件代码时,用 `bb-llms` 获取权威组件 API,避免臆造参数:
-
-- 搜索组件:`bb-llms search <关键词>`
-- 获取文档:`bb-llms get `(例:`bb-llms get Table`)
-- 列出全部:`bb-llms list`
-
-文档源默认 https://www.blazor.zone/llms ,可用 `BB_LLMS_BASE_URL` / `--base-url` 覆盖。
-安装:`dotnet tool install -g BootstrapBlazor.LLMsDocs.Cli`。
-""";
+ public static string CursorRule => ReadTemplate("bootstrapblazor.mdc");
/// Print the generic snippet to stdout.
public static int Instructions()
{
- Console.WriteLine(GenericSnippet);
+ // The template is normalized to end with a single newline, so use Write.
+ Console.Write(GenericSnippet);
return 0;
}
@@ -90,10 +42,12 @@ public static int Install(string client, string scope, string? target, bool forc
{
var clients = client.ToLowerInvariant() switch
{
- "all" => new[] { "claude", "cursor" },
+ "all" => new[] { "claude", "cursor", "trae", "codex" },
"claude" => ["claude"],
"cursor" => ["cursor"],
- _ => throw new ArgumentException($"Unknown client: {client} (expected claude|cursor|all)")
+ "trae" => ["trae"],
+ "codex" => ["codex"],
+ _ => throw new ArgumentException($"Unknown client: {client} (expected claude|cursor|trae|codex|all)")
};
var scopeKey = scope.ToLowerInvariant();
@@ -110,9 +64,23 @@ public static int Install(string client, string scope, string? target, bool forc
var written = 0;
foreach (var c in clients)
{
- var (path, content) = c == "claude"
- ? (Path.Combine(baseDir, ".claude", "skills", "bootstrapblazor", "SKILL.md"), SkillMarkdown)
- : (Path.Combine(baseDir, ".cursor", "rules", "bootstrapblazor.mdc"), CursorRule);
+ var (path, content) = c switch
+ {
+ "claude" => (Path.Combine(baseDir, ".claude", "skills", "bootstrapblazor", "SKILL.md"), SkillMarkdown),
+ "cursor" => (Path.Combine(baseDir, ".cursor", "rules", "bootstrapblazor.mdc"), CursorRule),
+ // Trae skills mirror Claude skills (.trae/skills//SKILL.md, same
+ // name/description frontmatter, auto-matched by description), so the
+ // Claude skill template is reused verbatim.
+ "trae" => (Path.Combine(baseDir, ".trae", "skills", "bootstrapblazor", "SKILL.md"), SkillMarkdown),
+ // Codex has no dedicated skill/rule format — it reads AGENTS.md: the
+ // repo-root AGENTS.md for project scope, ~/.codex/AGENTS.md for user scope.
+ // It reuses the generic snippet (same content as `bb-llms instructions`).
+ // NOTE: AGENTS.md is a shared, hand-maintained file, so this only creates it
+ // when absent; --force overwrites it wholesale (existing content is lost).
+ _ => (scopeKey == "user"
+ ? Path.Combine(baseDir, ".codex", "AGENTS.md")
+ : Path.Combine(baseDir, "AGENTS.md"), GenericSnippet)
+ };
if (File.Exists(path) && !force)
{
@@ -128,4 +96,18 @@ public static int Install(string client, string scope, string? target, bool forc
return written > 0 ? 0 : 1;
}
+
+ ///
+ /// Read an embedded template by its LogicalName (see the .csproj).
+ /// Trailing whitespace/newlines are normalized to a single trailing newline
+ /// so output stays stable regardless of how the source file was saved.
+ ///
+ private static string ReadTemplate(string logicalName)
+ {
+ var assembly = typeof(Scaffolder).Assembly;
+ using var stream = assembly.GetManifestResourceStream(logicalName)
+ ?? throw new InvalidOperationException($"Embedded template not found: {logicalName}");
+ using var reader = new StreamReader(stream, Encoding.UTF8);
+ return reader.ReadToEnd().TrimEnd() + "\n";
+ }
}
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/SKILL.md b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/SKILL.md
new file mode 100644
index 00000000..fa7e6494
--- /dev/null
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/SKILL.md
@@ -0,0 +1,35 @@
+---
+name: bootstrapblazor
+description: 涉及 BootstrapBlazor(简称 BB / bb,如“BB 组件”“bb 的 Table”“用 bb 写表格”)的组件参数、事件回调、公开方法、用法时使用,通过 bb-llms CLI 获取官方组件 API 文档,避免臆造参数。
+---
+
+# BootstrapBlazor 组件文档查询
+
+当任务涉及 BootstrapBlazor(简称 **BB** / **bb**,下同)组件(编写或修改 .razor、配置组件参数、调用组件方法等)时,优先用 `bb-llms` 获取**权威**组件 API。
+
+> 用户说“BB 组件”“bb 的 Table”“用 bb 写个表格”等时,BB / bb 均指 BootstrapBlazor,按本流程查询。
+
+## 用法
+
+1. 不确定组件名时先搜索:
+ ```bash
+ bb-llms search <关键词>
+ ```
+2. 获取某组件的参数 / 事件 / 方法文档:
+ ```bash
+ bb-llms get # 例:bb-llms get Table
+ ```
+3. 浏览全部组件:
+ ```bash
+ bb-llms list
+ ```
+
+输出为 Markdown(参数表、事件回调、公开方法、GitHub 源码链接)。文档源默认 https://www.blazor.zone/llms ,自动本地缓存;可用环境变量 `BB_LLMS_BASE_URL` 或 `--base-url` 指向自建/本地源。
+
+## 前置条件
+
+需已安装该工具(命令名 `bb-llms`):
+
+```bash
+dotnet tool install -g BootstrapBlazor.LLMsDocs.Cli
+```
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/bootstrapblazor.mdc b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/bootstrapblazor.mdc
new file mode 100644
index 00000000..be4d4c5b
--- /dev/null
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/bootstrapblazor.mdc
@@ -0,0 +1,16 @@
+---
+description: 涉及 BootstrapBlazor(简称 BB / bb)组件时,用 bb-llms CLI 获取官方组件 API 文档
+globs: ["**/*.razor", "**/*.razor.cs"]
+alwaysApply: false
+---
+
+# BootstrapBlazor 组件文档
+
+编写或修改 BootstrapBlazor(简称 BB / bb)组件代码时,用 `bb-llms` 获取权威组件 API,避免臆造参数:
+
+- 搜索组件:`bb-llms search <关键词>`
+- 获取文档:`bb-llms get `(例:`bb-llms get Table`)
+- 列出全部:`bb-llms list`
+
+文档源默认 https://www.blazor.zone/llms ,可用 `BB_LLMS_BASE_URL` / `--base-url` 覆盖。
+安装:`dotnet tool install -g BootstrapBlazor.LLMsDocs.Cli`。
diff --git a/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/instructions.md b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/instructions.md
new file mode 100644
index 00000000..1dfd14dd
--- /dev/null
+++ b/tools/BootstrapBlazor.LLMsDocs.Cli/Templates/instructions.md
@@ -0,0 +1,9 @@
+## BootstrapBlazor 组件文档
+
+需要 BootstrapBlazor(简称 BB / bb)组件的参数 / 事件 / 公开方法时,使用 `bb-llms` CLI 获取官方文档,不要凭记忆臆造 API:
+
+- 查找组件名:`bb-llms search <关键词>`
+- 获取组件文档:`bb-llms get `(例:`bb-llms get Table`)
+- 列出全部组件:`bb-llms list`
+
+文档源默认 https://www.blazor.zone/llms ,按需联网拉取并本地缓存;可用环境变量 `BB_LLMS_BASE_URL` 或 `--base-url` 指向自建/本地源。