@reglow/reui-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,273 @@
1
+ /**
2
+ * AI 工具的集成规格(Trae / CodeBuddy / Qoder 等)
3
+ *
4
+ * 数据来自各工具官方文档(2026-09 核对),用于:
5
+ * - `reui-setup` 一键写入 MCP 配置 + 安装 Skills;
6
+ * - `reui-skills` 的 `--list` 展示;
7
+ * - 文档与错误提示中的「手动步骤」说明。
8
+ *
9
+ * 参考:
10
+ * - Trae:https://docs.trae.cn/ide/add-mcp-servers (项目级 `.trae/mcp.json`,需在设置中开启「启用项目级 MCP」)
11
+ * - CodeBuddy:https://www.codebuddy.ai/docs/cli/mcp (项目级 `.mcp.json`,支持 JSONC)
12
+ * https://www.codebuddy.ai/docs/zh/cli/skills (`.codebuddy/skills/`)
13
+ * - Qoder:https://docs.qoder.com/zh/cli/mcp-reference (项目级 `.mcp.json` / `.qoder/settings.json`,需批准)
14
+ * https://docs.qoder.com/cli/Skills (`.qoder/skills/`)
15
+ */
16
+
17
+ /** MCP 服务器名(写入 mcpServers 的 key) */
18
+ export const DEFAULT_SERVER_NAME = "reui-mcp";
19
+
20
+ /** npm 包名(npx 启动用) */
21
+ export const MCP_PACKAGE = "@reglow/reui-mcp";
22
+
23
+ /** 默认的 stdio 启动参数 */
24
+ export const DEFAULT_ARGS = ["-y", MCP_PACKAGE];
25
+
26
+ /** 本 MCP 服务器在配置中的描述 */
27
+ const SERVER_DESCRIPTION =
28
+ "ReUI 组件库文档 / 示例 / 源码 / 函数查询(@reglow/reui-mcp)";
29
+
30
+ /**
31
+ * 各工具集成规格
32
+ *
33
+ * - `skills.projectDir`:项目级 Skills 目录(相对项目根)
34
+ * - `skills.userDir`:用户级 Skills 目录(`~` 表示用户主目录)
35
+ * - `mcp.projectFile`:项目级 MCP 配置文件(相对项目根)
36
+ * - `mcp.userFile`:用户级 MCP 配置文件(可按平台覆盖)
37
+ * - `mcp.jsonc`:配置文件是否允许注释 / 尾逗号(合并时会先做 JSONC 解析)
38
+ * - `mcp.explicitType`:写入条目时是否带 `type: "stdio"`
39
+ * - `mcp.manualSteps`:一键写入后仍需人工完成的步骤
40
+ */
41
+ export const TOOL_INTEGRATIONS = {
42
+ trae: {
43
+ label: "Trae",
44
+ docsUrl: "https://docs.trae.cn/ide/add-mcp-servers",
45
+ skills: { projectDir: ".trae/skills", userDir: "~/.trae/skills" },
46
+ mcp: {
47
+ projectFile: ".trae/mcp.json",
48
+ userFile: {
49
+ win32: "%APPDATA%/Trae/User/mcp.json",
50
+ darwin: "~/Library/Application Support/Trae/User/mcp.json",
51
+ linux: "~/.config/Trae/User/mcp.json",
52
+ },
53
+ explicitType: false,
54
+ manualSteps: [
55
+ "Trae 设置 → MCP:打开「启用项目级 MCP」开关(首次使用项目级配置必须开启)",
56
+ "若改用用户级配置:设置 → MCP → 添加 → 手动添加,或直接编辑上述用户级 mcp.json",
57
+ ],
58
+ notes: [
59
+ "stdio 配置中 command 不能包含空格",
60
+ "支持 ${workspaceFolder} 变量与 START_MCP_TIMEOUT_MS / RUN_MCP_TIMEOUT_MS 超时环境变量",
61
+ ],
62
+ },
63
+ },
64
+ codebuddy: {
65
+ label: "CodeBuddy",
66
+ docsUrl: "https://www.codebuddy.ai/docs/cli/mcp",
67
+ skills: { projectDir: ".codebuddy/skills", userDir: "~/.codebuddy/skills" },
68
+ mcp: {
69
+ projectFile: ".mcp.json",
70
+ userFile: "~/.codebuddy/.mcp.json",
71
+ jsonc: true,
72
+ explicitType: true,
73
+ manualSteps: [
74
+ "IDE:对话面板右上 CodeBuddy Settings → MCP → Add MCP,把 .mcp.json 里的 reui-mcp 条目粘贴进去(IDE 不走项目文件)",
75
+ "CLI:项目级 `.mcp.json` 直接生效,可用 `/mcp` 查看连接状态",
76
+ ],
77
+ notes: [
78
+ "项目级优先读 `.mcp.json`,其次 `mcp.json`(已弃用)",
79
+ "支持 JSONC(注释 / 尾逗号);同名服务器优先级 local > project > user",
80
+ '如需免确认,可在 settings.json 配 permissions.allow: ["mcp__reui-mcp__*"]',
81
+ ],
82
+ },
83
+ },
84
+ qoder: {
85
+ label: "Qoder",
86
+ docsUrl: "https://docs.qoder.com/zh/cli/mcp-reference",
87
+ skills: { projectDir: ".qoder/skills", userDir: "~/.qoder/skills" },
88
+ mcp: {
89
+ projectFile: ".mcp.json",
90
+ alternativeProjectFile: ".qoder/settings.json",
91
+ userFile: "~/.qoder/settings.json",
92
+ explicitType: true,
93
+ manualSteps: [
94
+ "项目级 MCP 默认需要批准:首次调用时确认,或在 settings.json 中设置 mcp.enableAllProjectMcpServers: true",
95
+ "CLI 也可直接执行:qoder mcp add reui-mcp -s project -- npx -y @reglow/reui-mcp",
96
+ "修改后如 CLI 正在运行,执行 /mcp reload 重新发现",
97
+ ],
98
+ notes: [
99
+ "同名服务器覆盖顺序:用户级 → 项目级 settings.json → 项目级 .mcp.json → 本地级 → CLI 参数",
100
+ "可选用 trust / alwaysAllow / includeTools / excludeTools 控制权限",
101
+ ],
102
+ },
103
+ },
104
+ cursor: {
105
+ label: "Cursor",
106
+ docsUrl: "https://docs.cursor.com/context/model-context-protocol",
107
+ skills: { projectDir: ".cursor/skills", userDir: "~/.cursor/skills" },
108
+ mcp: {
109
+ projectFile: ".cursor/mcp.json",
110
+ userFile: "~/.cursor/mcp.json",
111
+ explicitType: false,
112
+ manualSteps: ["Cursor 设置 → MCP 中确认 reui-mcp 已启用"],
113
+ notes: [],
114
+ },
115
+ },
116
+ claude: {
117
+ label: "Claude Code",
118
+ docsUrl: "https://docs.claude.com/en/docs/claude-code/mcp",
119
+ skills: { projectDir: ".claude/skills", userDir: "~/.claude/skills" },
120
+ mcp: {
121
+ projectFile: ".mcp.json",
122
+ userFile: {
123
+ win32: "%APPDATA%/Claude/claude_desktop_config.json",
124
+ darwin:
125
+ "~/Library/Application Support/Claude/claude_desktop_config.json",
126
+ linux: "~/.config/Claude/claude_desktop_config.json",
127
+ },
128
+ explicitType: false,
129
+ manualSteps: [
130
+ "也可执行:claude mcp add reui-mcp -- npx -y @reglow/reui-mcp",
131
+ ],
132
+ notes: [],
133
+ },
134
+ },
135
+ generic: {
136
+ label: "通用 .skills 目录",
137
+ docsUrl: "https://modelcontextprotocol.io/",
138
+ skills: { projectDir: ".skills", userDir: null },
139
+ mcp: {
140
+ projectFile: ".mcp.json",
141
+ userFile: null,
142
+ explicitType: true,
143
+ manualSteps: [
144
+ "按你所用的 MCP 客户端文档,把 .mcp.json 中的 mcpServers.reui-mcp 条目加入其配置",
145
+ ],
146
+ notes: [],
147
+ },
148
+ },
149
+ };
150
+
151
+ /** 默认一键配置的目标(用户重点关注的三个工具) */
152
+ export const DEFAULT_SETUP_TOOLS = ["trae", "codebuddy", "qoder"];
153
+
154
+ /** 全部可配置工具(`--setup all`) */
155
+ export const ALL_TOOLS = Object.keys(TOOL_INTEGRATIONS);
156
+
157
+ /** 工具名归一化(大小写 / 别名) */
158
+ export function normalizeTool(name) {
159
+ const key = String(name ?? "")
160
+ .trim()
161
+ .toLowerCase();
162
+ if (key === "trae" || key === "trae-ide" || key === "traecli") return "trae";
163
+ if (
164
+ key === "codebuddy" ||
165
+ key === "code-buddy" ||
166
+ key === "tencent-codebuddy"
167
+ )
168
+ return "codebuddy";
169
+ if (key === "qoder" || key === "qoder-cli") return "qoder";
170
+ if (key === "claude" || key === "claude-code" || key === "claude-desktop")
171
+ return "claude";
172
+ if (key === "cursor") return "cursor";
173
+ if (key === "generic" || key === "mcp" || key === "all-mcp") return "generic";
174
+ return key;
175
+ }
176
+
177
+ /** 解析工具清单字符串(`trae,codebuddy,qoder` / `all`) */
178
+ export function parseTools(input) {
179
+ if (!input) return [...DEFAULT_SETUP_TOOLS];
180
+ const raw = String(input)
181
+ .split(/[,\s]+/)
182
+ .map((item) => item.trim())
183
+ .filter(Boolean);
184
+ if (raw.length === 0) return [...DEFAULT_SETUP_TOOLS];
185
+ const expanded = raw.includes("all") ? ALL_TOOLS : raw;
186
+ const tools = [];
187
+ for (const item of expanded) {
188
+ const tool = normalizeTool(item);
189
+ if (!TOOL_INTEGRATIONS[tool]) {
190
+ throw new Error(`未知工具「${item}」,可选:${ALL_TOOLS.join(" / ")}`);
191
+ }
192
+ if (!tools.includes(tool)) tools.push(tool);
193
+ }
194
+ return tools;
195
+ }
196
+
197
+ /** 展开 `~` 与 `%VAR%` / `$VAR`,得到绝对路径(统一使用 `/` 分隔,Windows 下 Node 同样接受) */
198
+ export function expandPath(
199
+ target,
200
+ { cwd = process.cwd(), env = process.env, platform = process.platform } = {},
201
+ ) {
202
+ let value = String(target ?? "");
203
+ value = value.replace(/%([^%]+)%/g, (_m, name) => env[name] ?? `%${name}%`);
204
+ if (value.startsWith("~/") || value === "~") {
205
+ const home = env.USERPROFILE || env.HOME || cwd;
206
+ value = value.replace(/^~/, home);
207
+ }
208
+ if (!value) return null;
209
+ const combined = /^([a-zA-Z]:[\\/]|[\\/]{1,2})/.test(value)
210
+ ? value
211
+ : `${cwd}/${value}`;
212
+ return combined
213
+ .replace(/\\/g, "/")
214
+ .replace(/\/{2,}/g, "/")
215
+ .replace(/^([a-zA-Z]):\//, "$1:/");
216
+ }
217
+
218
+ /** 取某工具在指定 scope 下的配置文件绝对路径 */
219
+ export function resolveConfigPath(tool, scope = "project", options = {}) {
220
+ const spec = TOOL_INTEGRATIONS[tool];
221
+ if (!spec) throw new Error(`未知工具「${tool}」`);
222
+ const cwd = options.cwd ?? process.cwd();
223
+ const platform = options.platform ?? process.platform;
224
+ if (scope === "user") {
225
+ const userFile = spec.mcp.userFile;
226
+ if (!userFile) return null;
227
+ const raw = typeof userFile === "string" ? userFile : userFile[platform];
228
+ if (!raw) return null;
229
+ return expandPath(raw, { ...options, cwd });
230
+ }
231
+ return expandPath(spec.mcp.projectFile, { ...options, cwd });
232
+ }
233
+
234
+ /** 取某工具在指定 scope 下的 Skills 目录绝对路径 */
235
+ export function resolveSkillsDir(tool, scope = "project", options = {}) {
236
+ const spec = TOOL_INTEGRATIONS[tool];
237
+ if (!spec) throw new Error(`未知工具「${tool}」`);
238
+ const cwd = options.cwd ?? process.cwd();
239
+ const dir = scope === "user" ? spec.skills.userDir : spec.skills.projectDir;
240
+ if (!dir) return null;
241
+ return expandPath(dir, { ...options, cwd });
242
+ }
243
+
244
+ /**
245
+ * 构造写入 mcpServers 的服务器条目
246
+ *
247
+ * @param {string} tool 工具名
248
+ * @param {{ serverName?: string, args?: string[], env?: Record<string, string> }} [options]
249
+ */
250
+ export function buildMcpEntry(tool, options = {}) {
251
+ const spec = TOOL_INTEGRATIONS[tool];
252
+ if (!spec) throw new Error(`未知工具「${tool}」`);
253
+ const entry = {
254
+ command: "npx",
255
+ args: [...(options.args ?? DEFAULT_ARGS)],
256
+ };
257
+ if (spec.mcp.explicitType) {
258
+ entry.type = "stdio";
259
+ entry.description = SERVER_DESCRIPTION;
260
+ }
261
+ if (options.env && Object.keys(options.env).length > 0)
262
+ entry.env = { ...options.env };
263
+ return entry;
264
+ }
265
+
266
+ /** `reui-skills --list` 用的目标表(兼容旧行为:预设名 → 目录) */
267
+ export function skillTargetsFromIntegrations() {
268
+ const targets = {};
269
+ for (const [tool, spec] of Object.entries(TOOL_INTEGRATIONS)) {
270
+ targets[tool] = { dir: spec.skills.projectDir, label: spec.label };
271
+ }
272
+ return targets;
273
+ }