@zqagent/core 0.2.20 → 0.3.6

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.
Files changed (238) hide show
  1. package/README.md +1 -1
  2. package/README.oss.en.md +3 -3
  3. package/README.oss.md +8 -3
  4. package/README.oss.zh-TW.md +3 -3
  5. package/dist/McpClient-CEQBUPuC.d.cts +145 -0
  6. package/dist/McpClient-CEQBUPuC.d.ts +145 -0
  7. package/dist/{ToolRegistry-C3pTFiaJ.d.cts → ToolRegistry-Cy0fQxrb.d.ts} +2 -111
  8. package/dist/{ToolRegistry-C3pTFiaJ.d.ts → ToolRegistry-DouDvn9E.d.cts} +2 -111
  9. package/dist/{explore-RtZtb-V6.d.ts → TurnEngine-BPKhWuSI.d.cts} +108 -73
  10. package/dist/{explore-BgRhj6SP.d.cts → TurnEngine-DtGEuVLT.d.ts} +108 -73
  11. package/dist/conflictGuard-BBOOIxxK.d.cts +42 -0
  12. package/dist/conflictGuard-BBOOIxxK.d.ts +42 -0
  13. package/dist/index.cjs +5418 -1096
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +577 -195
  16. package/dist/index.d.ts +577 -195
  17. package/dist/index.js +5299 -1011
  18. package/dist/index.js.map +1 -1
  19. package/dist/internal/crypto/secrets.cjs +25 -0
  20. package/dist/internal/crypto/secrets.cjs.map +1 -0
  21. package/dist/internal/crypto/secrets.d.cts +2 -0
  22. package/dist/internal/crypto/secrets.d.ts +2 -0
  23. package/dist/internal/crypto/secrets.js +3 -0
  24. package/dist/internal/crypto/secrets.js.map +1 -0
  25. package/dist/internal/engine/FileLogHook.cjs +179 -0
  26. package/dist/internal/engine/FileLogHook.cjs.map +1 -0
  27. package/dist/internal/engine/FileLogHook.d.cts +67 -0
  28. package/dist/internal/engine/FileLogHook.d.ts +67 -0
  29. package/dist/internal/engine/FileLogHook.js +144 -0
  30. package/dist/internal/engine/FileLogHook.js.map +1 -0
  31. package/dist/internal/engine/approvalView.cjs +25 -0
  32. package/dist/internal/engine/approvalView.cjs.map +1 -0
  33. package/dist/internal/engine/approvalView.d.cts +1 -0
  34. package/dist/internal/engine/approvalView.d.ts +1 -0
  35. package/dist/internal/engine/approvalView.js +3 -0
  36. package/dist/internal/engine/approvalView.js.map +1 -0
  37. package/dist/internal/engine/limits.cjs +59 -0
  38. package/dist/internal/engine/limits.cjs.map +1 -0
  39. package/dist/internal/engine/limits.d.cts +32 -0
  40. package/dist/internal/engine/limits.d.ts +32 -0
  41. package/dist/internal/engine/limits.js +31 -0
  42. package/dist/internal/engine/limits.js.map +1 -0
  43. package/dist/internal/engine/sessionNaming.cjs +47 -0
  44. package/dist/internal/engine/sessionNaming.cjs.map +1 -0
  45. package/dist/internal/engine/sessionNaming.d.cts +25 -0
  46. package/dist/internal/engine/sessionNaming.d.ts +25 -0
  47. package/dist/internal/engine/sessionNaming.js +20 -0
  48. package/dist/internal/engine/sessionNaming.js.map +1 -0
  49. package/dist/internal/llmConfig.cjs +561 -0
  50. package/dist/internal/llmConfig.cjs.map +1 -0
  51. package/dist/internal/llmConfig.d.cts +75 -0
  52. package/dist/internal/llmConfig.d.ts +75 -0
  53. package/dist/internal/llmConfig.js +535 -0
  54. package/dist/internal/llmConfig.js.map +1 -0
  55. package/dist/internal/mcp/builtin/index.cjs +685 -0
  56. package/dist/internal/mcp/builtin/index.cjs.map +1 -0
  57. package/dist/internal/mcp/builtin/index.d.cts +21 -0
  58. package/dist/internal/mcp/builtin/index.d.ts +21 -0
  59. package/dist/internal/mcp/builtin/index.js +652 -0
  60. package/dist/internal/mcp/builtin/index.js.map +1 -0
  61. package/dist/internal/mcp/config.cjs +278 -0
  62. package/dist/internal/mcp/config.cjs.map +1 -0
  63. package/dist/internal/mcp/config.d.cts +61 -0
  64. package/dist/internal/mcp/config.d.ts +61 -0
  65. package/dist/internal/mcp/config.js +235 -0
  66. package/dist/internal/mcp/config.js.map +1 -0
  67. package/dist/internal/mcp/presets.cjs +184 -0
  68. package/dist/internal/mcp/presets.cjs.map +1 -0
  69. package/dist/internal/mcp/presets.d.cts +39 -0
  70. package/dist/internal/mcp/presets.d.ts +39 -0
  71. package/dist/internal/mcp/presets.js +158 -0
  72. package/dist/internal/mcp/presets.js.map +1 -0
  73. package/dist/internal/node-name.cjs +45 -0
  74. package/dist/internal/node-name.cjs.map +1 -0
  75. package/dist/internal/node-name.d.cts +3 -0
  76. package/dist/internal/node-name.d.ts +3 -0
  77. package/dist/internal/node-name.js +10 -0
  78. package/dist/internal/node-name.js.map +1 -0
  79. package/dist/internal/paths.cjs +63 -0
  80. package/dist/internal/paths.cjs.map +1 -0
  81. package/dist/internal/paths.d.cts +17 -0
  82. package/dist/internal/paths.d.ts +17 -0
  83. package/dist/internal/paths.js +25 -0
  84. package/dist/internal/paths.js.map +1 -0
  85. package/dist/internal/providers/diagnostics.cjs +288 -0
  86. package/dist/internal/providers/diagnostics.cjs.map +1 -0
  87. package/dist/internal/providers/diagnostics.d.cts +103 -0
  88. package/dist/internal/providers/diagnostics.d.ts +103 -0
  89. package/dist/internal/providers/diagnostics.js +250 -0
  90. package/dist/internal/providers/diagnostics.js.map +1 -0
  91. package/dist/internal/providers/models.cjs +699 -0
  92. package/dist/internal/providers/models.cjs.map +1 -0
  93. package/dist/internal/providers/models.d.cts +136 -0
  94. package/dist/internal/providers/models.d.ts +136 -0
  95. package/dist/internal/providers/models.js +654 -0
  96. package/dist/internal/providers/models.js.map +1 -0
  97. package/dist/internal/terminal.cjs +161 -0
  98. package/dist/internal/terminal.cjs.map +1 -0
  99. package/dist/internal/terminal.d.cts +58 -0
  100. package/dist/internal/terminal.d.ts +58 -0
  101. package/dist/internal/terminal.js +128 -0
  102. package/dist/internal/terminal.js.map +1 -0
  103. package/dist/internal/tools/execAsync.cjs +187 -0
  104. package/dist/internal/tools/execAsync.cjs.map +1 -0
  105. package/dist/internal/tools/execAsync.d.cts +30 -0
  106. package/dist/internal/tools/execAsync.d.ts +30 -0
  107. package/dist/internal/tools/execAsync.js +162 -0
  108. package/dist/internal/tools/execAsync.js.map +1 -0
  109. package/dist/internal/tools/git.cjs +935 -0
  110. package/dist/internal/tools/git.cjs.map +1 -0
  111. package/dist/internal/tools/git.d.cts +206 -0
  112. package/dist/internal/tools/git.d.ts +206 -0
  113. package/dist/internal/tools/git.js +883 -0
  114. package/dist/internal/tools/git.js.map +1 -0
  115. package/dist/internal/tools/pathSafety.cjs +99 -0
  116. package/dist/internal/tools/pathSafety.cjs.map +1 -0
  117. package/dist/internal/tools/pathSafety.d.cts +44 -0
  118. package/dist/internal/tools/pathSafety.d.ts +44 -0
  119. package/dist/internal/tools/pathSafety.js +61 -0
  120. package/dist/internal/tools/pathSafety.js.map +1 -0
  121. package/dist/internal/tools/plan.cjs +146 -0
  122. package/dist/internal/tools/plan.cjs.map +1 -0
  123. package/dist/internal/tools/plan.d.cts +48 -0
  124. package/dist/internal/tools/plan.d.ts +48 -0
  125. package/dist/internal/tools/plan.js +117 -0
  126. package/dist/internal/tools/plan.js.map +1 -0
  127. package/dist/internal/tools/ripgrep.cjs +118 -0
  128. package/dist/internal/tools/ripgrep.cjs.map +1 -0
  129. package/dist/internal/tools/ripgrep.d.cts +6 -0
  130. package/dist/internal/tools/ripgrep.d.ts +6 -0
  131. package/dist/internal/tools/ripgrep.js +89 -0
  132. package/dist/internal/tools/ripgrep.js.map +1 -0
  133. package/dist/internal/tools/sandbox.cjs +253 -0
  134. package/dist/internal/tools/sandbox.cjs.map +1 -0
  135. package/dist/internal/tools/sandbox.d.cts +67 -0
  136. package/dist/internal/tools/sandbox.d.ts +67 -0
  137. package/dist/internal/tools/sandbox.js +213 -0
  138. package/dist/internal/tools/sandbox.js.map +1 -0
  139. package/dist/internal/tools/shell.cjs +771 -0
  140. package/dist/internal/tools/shell.cjs.map +1 -0
  141. package/dist/internal/tools/shell.d.cts +47 -0
  142. package/dist/internal/tools/shell.d.ts +47 -0
  143. package/dist/internal/tools/shell.js +731 -0
  144. package/dist/internal/tools/shell.js.map +1 -0
  145. package/dist/internal/tools/shellRuntime.cjs +220 -0
  146. package/dist/internal/tools/shellRuntime.cjs.map +1 -0
  147. package/dist/internal/tools/shellRuntime.d.cts +67 -0
  148. package/dist/internal/tools/shellRuntime.d.ts +67 -0
  149. package/dist/internal/tools/shellRuntime.js +181 -0
  150. package/dist/internal/tools/shellRuntime.js.map +1 -0
  151. package/dist/internal/update/controller.cjs +1035 -0
  152. package/dist/internal/update/controller.cjs.map +1 -0
  153. package/dist/internal/update/controller.d.cts +150 -0
  154. package/dist/internal/update/controller.d.ts +150 -0
  155. package/dist/internal/update/controller.js +991 -0
  156. package/dist/internal/update/controller.js.map +1 -0
  157. package/dist/internal/update/platform.cjs +234 -0
  158. package/dist/internal/update/platform.cjs.map +1 -0
  159. package/dist/internal/update/platform.d.cts +77 -0
  160. package/dist/internal/update/platform.d.ts +77 -0
  161. package/dist/internal/update/platform.js +184 -0
  162. package/dist/internal/update/platform.js.map +1 -0
  163. package/dist/tools/ask.d.cts +3 -1
  164. package/dist/tools/ask.d.ts +3 -1
  165. package/dist/tools/diff.cjs +17 -6
  166. package/dist/tools/diff.cjs.map +1 -1
  167. package/dist/tools/diff.d.cts +5 -2
  168. package/dist/tools/diff.d.ts +5 -2
  169. package/dist/tools/diff.js +17 -6
  170. package/dist/tools/diff.js.map +1 -1
  171. package/dist/tools/directories.d.cts +3 -1
  172. package/dist/tools/directories.d.ts +3 -1
  173. package/dist/tools/explore.cjs +1778 -204
  174. package/dist/tools/explore.cjs.map +1 -1
  175. package/dist/tools/explore.d.cts +82 -2
  176. package/dist/tools/explore.d.ts +82 -2
  177. package/dist/tools/explore.js +1780 -204
  178. package/dist/tools/explore.js.map +1 -1
  179. package/dist/tools/files.cjs +56 -21
  180. package/dist/tools/files.cjs.map +1 -1
  181. package/dist/tools/files.d.cts +6 -3
  182. package/dist/tools/files.d.ts +6 -3
  183. package/dist/tools/files.js +56 -21
  184. package/dist/tools/files.js.map +1 -1
  185. package/dist/tools/git.cjs +34 -25
  186. package/dist/tools/git.cjs.map +1 -1
  187. package/dist/tools/git.d.cts +4 -204
  188. package/dist/tools/git.d.ts +4 -204
  189. package/dist/tools/git.js +34 -25
  190. package/dist/tools/git.js.map +1 -1
  191. package/dist/tools/media.cjs +280 -3
  192. package/dist/tools/media.cjs.map +1 -1
  193. package/dist/tools/media.d.cts +3 -1
  194. package/dist/tools/media.d.ts +3 -1
  195. package/dist/tools/media.js +278 -1
  196. package/dist/tools/media.js.map +1 -1
  197. package/dist/tools/plan.cjs +62 -0
  198. package/dist/tools/plan.cjs.map +1 -1
  199. package/dist/tools/plan.d.cts +4 -17
  200. package/dist/tools/plan.d.ts +4 -17
  201. package/dist/tools/plan.js +59 -0
  202. package/dist/tools/plan.js.map +1 -1
  203. package/dist/tools/search.cjs +3 -0
  204. package/dist/tools/search.cjs.map +1 -1
  205. package/dist/tools/search.d.cts +3 -1
  206. package/dist/tools/search.d.ts +3 -1
  207. package/dist/tools/search.js +3 -0
  208. package/dist/tools/search.js.map +1 -1
  209. package/dist/tools/shell.cjs +76 -11
  210. package/dist/tools/shell.cjs.map +1 -1
  211. package/dist/tools/shell.d.cts +5 -39
  212. package/dist/tools/shell.d.ts +5 -39
  213. package/dist/tools/shell.js +75 -11
  214. package/dist/tools/shell.js.map +1 -1
  215. package/dist/tools/todo.d.cts +3 -1
  216. package/dist/tools/todo.d.ts +3 -1
  217. package/dist/tools/web.cjs +279 -5
  218. package/dist/tools/web.cjs.map +1 -1
  219. package/dist/tools/web.d.cts +3 -1
  220. package/dist/tools/web.d.ts +3 -1
  221. package/dist/tools/web.js +275 -3
  222. package/dist/tools/web.js.map +1 -1
  223. package/dist/types-BYyXWWPW.d.cts +237 -0
  224. package/dist/types-BYyXWWPW.d.ts +237 -0
  225. package/package.json +26 -37
  226. package/bin/zqagent +0 -2
  227. package/dist/cli/index.cjs +0 -25218
  228. package/dist/cli/index.cjs.map +0 -1
  229. package/dist/cli/index.d.cts +0 -2
  230. package/dist/cli/index.d.ts +0 -2
  231. package/dist/cli/index.js +0 -25201
  232. package/dist/cli/index.js.map +0 -1
  233. package/dist/server/index.cjs +0 -20510
  234. package/dist/server/index.cjs.map +0 -1
  235. package/dist/server/index.d.cts +0 -2
  236. package/dist/server/index.d.ts +0 -2
  237. package/dist/server/index.js +0 -20493
  238. package/dist/server/index.js.map +0 -1
@@ -0,0 +1,235 @@
1
+ // src/mcp/config.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ var TRANSPORT_TYPES = /* @__PURE__ */ new Set([
5
+ "stdio",
6
+ "http",
7
+ "sse",
8
+ "builtin"
9
+ ]);
10
+ var BUILTIN_MCP_CONFIGS = [
11
+ { name: "ocr", type: "builtin", builtin: "ocr", enabled: true }
12
+ ];
13
+ function defaultMcpConfigPath(workspace) {
14
+ return path.join(workspace, ".agent", "mcp.json");
15
+ }
16
+ function splitCommandLine(input) {
17
+ const out = [];
18
+ let cur = "";
19
+ let quote = null;
20
+ let escaped = false;
21
+ for (const ch of input) {
22
+ if (escaped) {
23
+ cur += ch;
24
+ escaped = false;
25
+ continue;
26
+ }
27
+ if (ch === "\\" && quote !== "'") {
28
+ escaped = true;
29
+ continue;
30
+ }
31
+ if (quote) {
32
+ if (ch === quote) quote = null;
33
+ else cur += ch;
34
+ continue;
35
+ }
36
+ if (ch === '"' || ch === "'") {
37
+ quote = ch;
38
+ continue;
39
+ }
40
+ if (/\s/.test(ch)) {
41
+ if (cur) {
42
+ out.push(cur);
43
+ cur = "";
44
+ }
45
+ continue;
46
+ }
47
+ cur += ch;
48
+ }
49
+ if (escaped) cur += "\\";
50
+ if (cur) out.push(cur);
51
+ return out;
52
+ }
53
+ function expandEnv(value, env, name, warnings) {
54
+ return value.replace(
55
+ /\$\{(?:env:)?([A-Za-z_][A-Za-z0-9_]*)\}/g,
56
+ (_m, key) => {
57
+ const v = env[key];
58
+ if (v === void 0) {
59
+ warnings.push(`"${name}" \u5F15\u7528\u4E86\u672A\u5B9A\u4E49\u7684\u73AF\u5883\u53D8\u91CF \${${key}}`);
60
+ return "";
61
+ }
62
+ return v;
63
+ }
64
+ );
65
+ }
66
+ function toStringMap(raw, field, name, env, warnings) {
67
+ if (raw === void 0 || raw === null) return void 0;
68
+ if (typeof raw !== "object" || Array.isArray(raw)) {
69
+ warnings.push(`"${name}".${field} \u5E94\u4E3A\u5BF9\u8C61\uFF0C\u5DF2\u5FFD\u7565`);
70
+ return void 0;
71
+ }
72
+ const out = {};
73
+ for (const [k, v] of Object.entries(raw)) {
74
+ if (v === void 0 || v === null) continue;
75
+ if (typeof v === "string") out[k] = expandEnv(v, env, name, warnings);
76
+ else if (typeof v === "number" || typeof v === "boolean")
77
+ out[k] = String(v);
78
+ else warnings.push(`"${name}".${field}.${k} \u4E0D\u662F\u5B57\u7B26\u4E32\uFF0C\u5DF2\u5FFD\u7565`);
79
+ }
80
+ return Object.keys(out).length > 0 ? out : void 0;
81
+ }
82
+ function normalizeMcpConfig(raw, fallbackName, opts = {}, warnings = []) {
83
+ const env = opts.env ?? process.env;
84
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
85
+ warnings.push(`MCP \u914D\u7F6E\u6761\u76EE${fallbackName ? ` "${fallbackName}"` : ""} \u4E0D\u662F\u5BF9\u8C61\uFF0C\u5DF2\u8DF3\u8FC7`);
86
+ return null;
87
+ }
88
+ const o = raw;
89
+ const name = typeof o.name === "string" && o.name.trim() ? o.name.trim() : fallbackName?.trim();
90
+ if (!name) {
91
+ warnings.push("MCP \u914D\u7F6E\u7F3A\u5C11 name\uFF0C\u5DF2\u8DF3\u8FC7");
92
+ return null;
93
+ }
94
+ const rawType = typeof o.type === "string" ? o.type.toLowerCase() : "";
95
+ let type;
96
+ if (TRANSPORT_TYPES.has(rawType)) type = rawType;
97
+ else if (rawType === "streamable-http" || rawType === "streamablehttp")
98
+ type = "http";
99
+ else if (typeof o.builtin === "string") type = "builtin";
100
+ else if (typeof o.url === "string")
101
+ type = /\/sse(?:[?#]|$)/i.test(o.url) ? "sse" : "http";
102
+ else if (o.command !== void 0) type = "stdio";
103
+ if (!type) {
104
+ warnings.push(`MCP "${name}" \u65E0\u6CD5\u63A8\u65AD\u4F20\u8F93\u7C7B\u578B\uFF08\u9700\u8981 builtin/command/url\uFF09`);
105
+ return null;
106
+ }
107
+ const enabled = o.enabled === false || o.disabled === true ? false : true;
108
+ const config = { name, type, enabled };
109
+ if (type === "stdio") {
110
+ const command = [];
111
+ if (Array.isArray(o.command)) {
112
+ for (const part of o.command) {
113
+ if (typeof part === "string") command.push(part);
114
+ else warnings.push(`MCP "${name}" \u7684 command \u542B\u975E\u5B57\u7B26\u4E32\u9879\uFF0C\u5DF2\u5FFD\u7565`);
115
+ }
116
+ } else if (typeof o.command === "string") {
117
+ command.push(...splitCommandLine(o.command));
118
+ }
119
+ if (Array.isArray(o.args)) {
120
+ for (const part of o.args) {
121
+ if (typeof part === "string") command.push(part);
122
+ else warnings.push(`MCP "${name}" \u7684 args \u542B\u975E\u5B57\u7B26\u4E32\u9879\uFF0C\u5DF2\u5FFD\u7565`);
123
+ }
124
+ } else if (typeof o.args === "string") {
125
+ command.push(...splitCommandLine(o.args));
126
+ }
127
+ if (command.length === 0) {
128
+ warnings.push(`MCP "${name}" \u7F3A\u5C11 command\uFF0C\u5DF2\u8DF3\u8FC7`);
129
+ return null;
130
+ }
131
+ config.command = command.map((c) => expandEnv(c, env, name, warnings));
132
+ if (typeof o.cwd === "string" && o.cwd.trim())
133
+ config.cwd = expandEnv(o.cwd, env, name, warnings);
134
+ const stdioEnv = toStringMap(o.env, "env", name, env, warnings);
135
+ if (stdioEnv) config.env = stdioEnv;
136
+ } else if (type === "builtin") {
137
+ config.builtin = typeof o.builtin === "string" && o.builtin.trim() ? o.builtin.trim() : name;
138
+ } else {
139
+ if (typeof o.url !== "string" || !o.url.trim()) {
140
+ warnings.push(`MCP "${name}" \u7F3A\u5C11 url\uFF0C\u5DF2\u8DF3\u8FC7`);
141
+ return null;
142
+ }
143
+ config.url = expandEnv(o.url.trim(), env, name, warnings);
144
+ const headers = toStringMap(o.headers, "headers", name, env, warnings);
145
+ if (headers) config.headers = headers;
146
+ }
147
+ return config;
148
+ }
149
+ function normalizeMcpConfigs(raw, opts = {}) {
150
+ const warnings = [];
151
+ const configs = [];
152
+ const add = (item, fallbackName) => {
153
+ const cfg = normalizeMcpConfig(item, fallbackName, opts, warnings);
154
+ if (!cfg) return;
155
+ const idx = configs.findIndex((c) => c.name === cfg.name);
156
+ if (idx >= 0) {
157
+ warnings.push(`MCP "${cfg.name}" \u91CD\u590D\u51FA\u73B0\uFF0C\u540E\u8005\u8986\u76D6\u524D\u8005`);
158
+ configs[idx] = cfg;
159
+ } else {
160
+ configs.push(cfg);
161
+ }
162
+ };
163
+ if (Array.isArray(raw)) {
164
+ for (const item of raw) add(item);
165
+ } else if (raw && typeof raw === "object") {
166
+ const o = raw;
167
+ const objectMap = (value) => {
168
+ if (!value || typeof value !== "object" || Array.isArray(value))
169
+ return false;
170
+ for (const [k, v] of Object.entries(value))
171
+ add(v, k);
172
+ return true;
173
+ };
174
+ if (Array.isArray(o.servers)) {
175
+ for (const item of o.servers) add(item);
176
+ } else if (Array.isArray(o.mcpServers)) {
177
+ for (const item of o.mcpServers) add(item);
178
+ } else if (objectMap(o.mcpServers)) {
179
+ } else if (objectMap(o.servers)) {
180
+ } else {
181
+ add(o);
182
+ }
183
+ } else {
184
+ warnings.push("MCP \u914D\u7F6E\u5FC5\u987B\u662F JSON \u5BF9\u8C61\u6216\u6570\u7EC4");
185
+ }
186
+ return { configs, warnings };
187
+ }
188
+ function readMcpConfigFile(file, opts = {}) {
189
+ if (!file) return { configs: [], warnings: [] };
190
+ try {
191
+ if (!fs.existsSync(file)) return { configs: [], warnings: [] };
192
+ const raw = JSON.parse(fs.readFileSync(file, "utf8"));
193
+ return normalizeMcpConfigs(raw, opts);
194
+ } catch (err) {
195
+ return {
196
+ configs: [],
197
+ warnings: [`\u8BFB\u53D6 MCP \u914D\u7F6E\u5931\u8D25 ${file}: ${err.message}`]
198
+ };
199
+ }
200
+ }
201
+ function saveMcpConfigFile(file, configs) {
202
+ fs.mkdirSync(path.dirname(file), { recursive: true });
203
+ fs.writeFileSync(
204
+ file,
205
+ JSON.stringify(
206
+ configs.map((c) => JSON.parse(JSON.stringify(c))),
207
+ null,
208
+ 2
209
+ ) + "\n",
210
+ "utf8"
211
+ );
212
+ }
213
+ function withBuiltinMcpConfigs(configs) {
214
+ const existing = new Set(configs.map((c) => c.name));
215
+ const builtin = BUILTIN_MCP_CONFIGS.filter((c) => !existing.has(c.name)).map(
216
+ (c) => ({ ...c })
217
+ );
218
+ return [...configs, ...builtin];
219
+ }
220
+ function loadMcpConfigFile(file, opts = {}) {
221
+ const result = readMcpConfigFile(file, opts);
222
+ return { configs: withBuiltinMcpConfigs(result.configs), warnings: result.warnings };
223
+ }
224
+ export {
225
+ BUILTIN_MCP_CONFIGS,
226
+ defaultMcpConfigPath,
227
+ loadMcpConfigFile,
228
+ normalizeMcpConfig,
229
+ normalizeMcpConfigs,
230
+ readMcpConfigFile,
231
+ saveMcpConfigFile,
232
+ splitCommandLine,
233
+ withBuiltinMcpConfigs
234
+ };
235
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/mcp/config.ts"],"sourcesContent":["/**\n * MCP 配置解析与持久化(CLI / server 共用)\n *\n * 支持多种来源格式,避免「拷一份别人的配置进来却静默失效」:\n * - 裸数组:[{ name, type, command|url, ... }]\n * - { servers: [...] } / { servers: { name: {...} } }\n * - { mcpServers: [...] } / { mcpServers: { name: {...} } }(Claude Desktop / Cursor)\n *\n * 单条配置容错:\n * - 省略 type 时按 builtin / url / command 推断\n * - Claude 风格 command(string) + args(string[]) 合并为 command: string[]\n * - env/headers 值允许数字与布尔(转字符串)\n * - 字符串中的 ${VAR} / ${env:VAR} 用进程环境变量展开\n *\n * 内置服务器(如 OCR)默认追加:用户配置中存在同名条目时以用户条目为准,\n * 因此可以用 { name: \"ocr\", enabled: false } 关闭内置能力。\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { McpServerConfig, McpTransportType } from \"./McpClient.js\";\n\n/** 归一化结果 */\nexport interface McpConfigNormalizeResult {\n configs: McpServerConfig[];\n warnings: string[];\n}\n\n/** 归一化选项 */\nexport interface McpConfigNormalizeOptions {\n /** 环境变量(默认 process.env),用于 ${VAR} 展开 */\n env?: NodeJS.ProcessEnv;\n}\n\nconst TRANSPORT_TYPES: ReadonlySet<string> = new Set([\n \"stdio\",\n \"http\",\n \"sse\",\n \"builtin\",\n]);\n\n/** 内置 MCP 服务器默认配置(用户同名配置优先) */\nexport const BUILTIN_MCP_CONFIGS: ReadonlyArray<McpServerConfig> = [\n { name: \"ocr\", type: \"builtin\", builtin: \"ocr\", enabled: true },\n];\n\n/** 工作区默认配置文件路径 */\nexport function defaultMcpConfigPath(workspace: string): string {\n return path.join(workspace, \".agent\", \"mcp.json\");\n}\n\n/**\n * 拆分 shell 风格命令行(支持单/双引号与反斜杠转义)。\n * 用于兼容 `command: \"npx -y some-server\"` 这类单字符串写法。\n */\nexport function splitCommandLine(input: string): string[] {\n const out: string[] = [];\n let cur = \"\";\n let quote: '\"' | \"'\" | null = null;\n let escaped = false;\n for (const ch of input) {\n if (escaped) {\n cur += ch;\n escaped = false;\n continue;\n }\n if (ch === \"\\\\\" && quote !== \"'\") {\n escaped = true;\n continue;\n }\n if (quote) {\n if (ch === quote) quote = null;\n else cur += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n continue;\n }\n if (/\\s/.test(ch)) {\n if (cur) {\n out.push(cur);\n cur = \"\";\n }\n continue;\n }\n cur += ch;\n }\n if (escaped) cur += \"\\\\\";\n if (cur) out.push(cur);\n return out;\n}\n\nfunction expandEnv(\n value: string,\n env: NodeJS.ProcessEnv,\n name: string,\n warnings: string[],\n): string {\n return value.replace(\n /\\$\\{(?:env:)?([A-Za-z_][A-Za-z0-9_]*)\\}/g,\n (_m, key: string) => {\n const v = env[key];\n if (v === undefined) {\n warnings.push(`\"${name}\" 引用了未定义的环境变量 \\${${key}}`);\n return \"\";\n }\n return v;\n },\n );\n}\n\nfunction toStringMap(\n raw: unknown,\n field: string,\n name: string,\n env: NodeJS.ProcessEnv,\n warnings: string[],\n): Record<string, string> | undefined {\n if (raw === undefined || raw === null) return undefined;\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n warnings.push(`\"${name}\".${field} 应为对象,已忽略`);\n return undefined;\n }\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(raw as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n if (typeof v === \"string\") out[k] = expandEnv(v, env, name, warnings);\n else if (typeof v === \"number\" || typeof v === \"boolean\")\n out[k] = String(v);\n else warnings.push(`\"${name}\".${field}.${k} 不是字符串,已忽略`);\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * 归一化单条 MCP 配置。\n * @param raw 原始条目(数组元素或 mcpServers 映射的值)\n * @param fallbackName mcpServers 映射的键名\n * @returns 合法配置;无法解析时返回 null(原因写入 warnings)\n */\nexport function normalizeMcpConfig(\n raw: unknown,\n fallbackName?: string,\n opts: McpConfigNormalizeOptions = {},\n warnings: string[] = [],\n): McpServerConfig | null {\n const env = opts.env ?? process.env;\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n warnings.push(`MCP 配置条目${fallbackName ? ` \"${fallbackName}\"` : \"\"} 不是对象,已跳过`);\n return null;\n }\n const o = raw as Record<string, unknown>;\n const name =\n typeof o.name === \"string\" && o.name.trim()\n ? o.name.trim()\n : fallbackName?.trim();\n if (!name) {\n warnings.push(\"MCP 配置缺少 name,已跳过\");\n return null;\n }\n\n const rawType = typeof o.type === \"string\" ? o.type.toLowerCase() : \"\";\n let type: McpTransportType | undefined;\n if (TRANSPORT_TYPES.has(rawType)) type = rawType as McpTransportType;\n else if (rawType === \"streamable-http\" || rawType === \"streamablehttp\")\n type = \"http\";\n else if (typeof o.builtin === \"string\") type = \"builtin\";\n else if (typeof o.url === \"string\")\n type = /\\/sse(?:[?#]|$)/i.test(o.url) ? \"sse\" : \"http\";\n else if (o.command !== undefined) type = \"stdio\";\n\n if (!type) {\n warnings.push(`MCP \"${name}\" 无法推断传输类型(需要 builtin/command/url)`);\n return null;\n }\n\n const enabled =\n o.enabled === false || o.disabled === true ? false : true;\n const config: McpServerConfig = { name, type, enabled };\n\n if (type === \"stdio\") {\n const command: string[] = [];\n if (Array.isArray(o.command)) {\n for (const part of o.command) {\n if (typeof part === \"string\") command.push(part);\n else warnings.push(`MCP \"${name}\" 的 command 含非字符串项,已忽略`);\n }\n } else if (typeof o.command === \"string\") {\n command.push(...splitCommandLine(o.command));\n }\n if (Array.isArray(o.args)) {\n for (const part of o.args) {\n if (typeof part === \"string\") command.push(part);\n else warnings.push(`MCP \"${name}\" 的 args 含非字符串项,已忽略`);\n }\n } else if (typeof o.args === \"string\") {\n command.push(...splitCommandLine(o.args));\n }\n if (command.length === 0) {\n warnings.push(`MCP \"${name}\" 缺少 command,已跳过`);\n return null;\n }\n config.command = command.map((c) => expandEnv(c, env, name, warnings));\n if (typeof o.cwd === \"string\" && o.cwd.trim())\n config.cwd = expandEnv(o.cwd, env, name, warnings);\n const stdioEnv = toStringMap(o.env, \"env\", name, env, warnings);\n if (stdioEnv) config.env = stdioEnv;\n } else if (type === \"builtin\") {\n config.builtin =\n typeof o.builtin === \"string\" && o.builtin.trim()\n ? o.builtin.trim()\n : name;\n } else {\n if (typeof o.url !== \"string\" || !o.url.trim()) {\n warnings.push(`MCP \"${name}\" 缺少 url,已跳过`);\n return null;\n }\n config.url = expandEnv(o.url.trim(), env, name, warnings);\n const headers = toStringMap(o.headers, \"headers\", name, env, warnings);\n if (headers) config.headers = headers;\n }\n\n return config;\n}\n\n/** 归一化任意受支持的配置形状 */\nexport function normalizeMcpConfigs(\n raw: unknown,\n opts: McpConfigNormalizeOptions = {},\n): McpConfigNormalizeResult {\n const warnings: string[] = [];\n const configs: McpServerConfig[] = [];\n\n const add = (item: unknown, fallbackName?: string): void => {\n const cfg = normalizeMcpConfig(item, fallbackName, opts, warnings);\n if (!cfg) return;\n const idx = configs.findIndex((c) => c.name === cfg.name);\n if (idx >= 0) {\n warnings.push(`MCP \"${cfg.name}\" 重复出现,后者覆盖前者`);\n configs[idx] = cfg;\n } else {\n configs.push(cfg);\n }\n };\n\n if (Array.isArray(raw)) {\n for (const item of raw) add(item);\n } else if (raw && typeof raw === \"object\") {\n const o = raw as Record<string, unknown>;\n const objectMap = (value: unknown): boolean => {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return false;\n for (const [k, v] of Object.entries(value as Record<string, unknown>))\n add(v, k);\n return true;\n };\n if (Array.isArray(o.servers)) {\n for (const item of o.servers) add(item);\n } else if (Array.isArray(o.mcpServers)) {\n for (const item of o.mcpServers) add(item);\n } else if (objectMap(o.mcpServers)) {\n // Claude Desktop / Cursor: { mcpServers: { name: { command, args } } }\n } else if (objectMap(o.servers)) {\n // { servers: { name: {...} } }\n } else {\n // 单条配置对象\n add(o);\n }\n } else {\n warnings.push(\"MCP 配置必须是 JSON 对象或数组\");\n }\n\n return { configs, warnings };\n}\n\n/**\n * 读取配置文件并归一化。文件不存在时返回空结果(不视为错误)。\n * @param file 配置文件路径;未提供时返回空结果\n */\nexport function readMcpConfigFile(\n file: string | undefined,\n opts: McpConfigNormalizeOptions = {},\n): McpConfigNormalizeResult {\n if (!file) return { configs: [], warnings: [] };\n try {\n if (!fs.existsSync(file)) return { configs: [], warnings: [] };\n const raw: unknown = JSON.parse(fs.readFileSync(file, \"utf8\"));\n return normalizeMcpConfigs(raw, opts);\n } catch (err) {\n return {\n configs: [],\n warnings: [`读取 MCP 配置失败 ${file}: ${(err as Error).message}`],\n };\n }\n}\n\n/** 保存配置(统一写为数组格式,自动创建目录) */\nexport function saveMcpConfigFile(\n file: string,\n configs: McpServerConfig[],\n): void {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(\n file,\n JSON.stringify(\n configs.map((c) => JSON.parse(JSON.stringify(c)) as McpServerConfig),\n null,\n 2,\n ) + \"\\n\",\n \"utf8\",\n );\n}\n\n/** 追加内置默认配置(同名用户配置优先) */\nexport function withBuiltinMcpConfigs(\n configs: McpServerConfig[],\n): McpServerConfig[] {\n const existing = new Set(configs.map((c) => c.name));\n const builtin = BUILTIN_MCP_CONFIGS.filter((c) => !existing.has(c.name)).map(\n (c) => ({ ...c }),\n );\n return [...configs, ...builtin];\n}\n\n/** 读取配置文件并追加内置默认配置 */\nexport function loadMcpConfigFile(\n file: string | undefined,\n opts: McpConfigNormalizeOptions = {},\n): McpConfigNormalizeResult {\n const result = readMcpConfigFile(file, opts);\n return { configs: withBuiltinMcpConfigs(result.configs), warnings: result.warnings };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/mcp/presets.ts
21
+ var presets_exports = {};
22
+ __export(presets_exports, {
23
+ MCP_PRESETS: () => MCP_PRESETS,
24
+ applyMcpPreset: () => applyMcpPreset
25
+ });
26
+ module.exports = __toCommonJS(presets_exports);
27
+ var MCP_PRESETS = [
28
+ {
29
+ id: "filesystem",
30
+ title: "Filesystem\uFF08\u672C\u5730\u6587\u4EF6\uFF09",
31
+ description: "\u8BA9 MCP \u8BFB\u5199\u6307\u5B9A\u76EE\u5F55\uFF0Cnpx \u81EA\u52A8\u62C9\u53D6\u5B98\u65B9 server",
32
+ config: {
33
+ name: "filesystem",
34
+ type: "stdio",
35
+ command: [
36
+ "npx",
37
+ "-y",
38
+ "@modelcontextprotocol/server-filesystem",
39
+ "{{dir}}"
40
+ ],
41
+ enabled: true
42
+ },
43
+ fields: [
44
+ {
45
+ key: "dir",
46
+ label: "\u5141\u8BB8\u8BBF\u95EE\u7684\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09",
47
+ required: true
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ id: "memory",
53
+ title: "Memory\uFF08\u77E5\u8BC6\u56FE\u8C31\u8BB0\u5FC6\uFF09",
54
+ description: "\u5B98\u65B9 memory server\uFF0C\u63D0\u4F9B\u5B9E\u4F53/\u5173\u7CFB\u8BB0\u5FC6",
55
+ config: {
56
+ name: "memory",
57
+ type: "stdio",
58
+ command: ["npx", "-y", "@modelcontextprotocol/server-memory"],
59
+ enabled: true
60
+ }
61
+ },
62
+ {
63
+ id: "sequential-thinking",
64
+ title: "Sequential Thinking\uFF08\u5206\u6B65\u63A8\u7406\uFF09",
65
+ description: "\u5B98\u65B9\u5206\u6B65\u601D\u8003 server",
66
+ config: {
67
+ name: "sequential-thinking",
68
+ type: "stdio",
69
+ command: [
70
+ "npx",
71
+ "-y",
72
+ "@modelcontextprotocol/server-sequential-thinking"
73
+ ],
74
+ enabled: true
75
+ }
76
+ },
77
+ {
78
+ id: "github",
79
+ title: "GitHub",
80
+ description: "\u5B98\u65B9 GitHub server\uFF08\u9700\u8981 Personal Access Token\uFF09",
81
+ config: {
82
+ name: "github",
83
+ type: "stdio",
84
+ command: ["npx", "-y", "@modelcontextprotocol/server-github"],
85
+ env: { GITHUB_PERSONAL_ACCESS_TOKEN: "{{token}}" },
86
+ enabled: true
87
+ },
88
+ fields: [
89
+ {
90
+ key: "token",
91
+ label: "GitHub Personal Access Token",
92
+ required: true,
93
+ secret: true
94
+ }
95
+ ]
96
+ },
97
+ {
98
+ id: "fetch",
99
+ title: "Fetch\uFF08\u7F51\u9875\u6293\u53D6\uFF09",
100
+ description: "\u5B98\u65B9 Python server\uFF0C\u9700\u8981 uvx\uFF08pip install uv\uFF09",
101
+ config: {
102
+ name: "fetch",
103
+ type: "stdio",
104
+ command: ["uvx", "mcp-server-fetch"],
105
+ enabled: true
106
+ }
107
+ },
108
+ {
109
+ id: "postgres",
110
+ title: "PostgreSQL\uFF08\u53EA\u8BFB\u67E5\u8BE2\uFF09",
111
+ description: "\u5B98\u65B9 postgres server\uFF08\u9700\u8981\u8FDE\u63A5\u4E32\uFF09",
112
+ config: {
113
+ name: "postgres",
114
+ type: "stdio",
115
+ command: [
116
+ "npx",
117
+ "-y",
118
+ "@modelcontextprotocol/server-postgres",
119
+ "{{dsn}}"
120
+ ],
121
+ enabled: true
122
+ },
123
+ fields: [
124
+ {
125
+ key: "dsn",
126
+ label: "\u8FDE\u63A5\u4E32\uFF08postgresql://user:pass@host/db\uFF09",
127
+ required: true,
128
+ secret: true
129
+ }
130
+ ]
131
+ },
132
+ {
133
+ id: "ocr",
134
+ title: "OCR\uFF08\u5185\u7F6E\uFF0C\u5F00\u7BB1\u5373\u7528\uFF09",
135
+ description: "\u8FDB\u7A0B\u5185 OCR\uFF1AmacOS Vision / tesseract / \u591A\u6A21\u6001\u6A21\u578B\u81EA\u52A8\u964D\u7EA7\uFF0C\u65E0\u9700\u5B89\u88C5",
136
+ config: {
137
+ name: "ocr",
138
+ type: "builtin",
139
+ builtin: "ocr",
140
+ enabled: true
141
+ }
142
+ }
143
+ ];
144
+ function replacePlaceholders(value, values) {
145
+ return value.replace(/\{\{([A-Za-z0-9_]+)\}\}/g, (_m, key) => {
146
+ return values[key] ?? "";
147
+ });
148
+ }
149
+ function applyMcpPreset(preset, values) {
150
+ const base = preset.config;
151
+ const config = {
152
+ ...base,
153
+ name: base.name ?? preset.id
154
+ };
155
+ if (config.command)
156
+ config.command = config.command.map(
157
+ (c) => replacePlaceholders(c, values)
158
+ );
159
+ if (config.url) config.url = replacePlaceholders(config.url, values);
160
+ if (config.cwd) config.cwd = replacePlaceholders(config.cwd, values);
161
+ if (config.env) {
162
+ config.env = Object.fromEntries(
163
+ Object.entries(config.env).map(([k, v]) => [
164
+ k,
165
+ replacePlaceholders(v, values)
166
+ ])
167
+ );
168
+ }
169
+ if (config.headers) {
170
+ config.headers = Object.fromEntries(
171
+ Object.entries(config.headers).map(([k, v]) => [
172
+ k,
173
+ replacePlaceholders(v, values)
174
+ ])
175
+ );
176
+ }
177
+ return config;
178
+ }
179
+ // Annotate the CommonJS export names for ESM import in node:
180
+ 0 && (module.exports = {
181
+ MCP_PRESETS,
182
+ applyMcpPreset
183
+ });
184
+ //# sourceMappingURL=presets.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/mcp/presets.ts"],"sourcesContent":["/**\n * MCP 安装模板\n *\n * 用于 `/mcp add` 交互式向导:把常见官方服务器的启动命令与参数固化,\n * 用户只需按提示填写少量占位符。`{{key}}` 会在安装时被替换。\n */\n\nimport type { McpServerConfig } from \"./McpClient.js\";\n\n/** 模板占位符 */\nexport interface McpPresetField {\n /** 替换 config 中的 {{key}} */\n key: string;\n /** 提示文案 */\n label: string;\n /** 必填(为空则取消安装) */\n required?: boolean;\n /** 隐藏输入(写入 env/headers 的密钥) */\n secret?: boolean;\n /** 默认值 */\n default?: string;\n}\n\n/** 安装模板 */\nexport interface McpPreset {\n id: string;\n title: string;\n description: string;\n /** name 缺省时使用 id */\n config: Omit<McpServerConfig, \"name\"> & { name?: string };\n fields?: McpPresetField[];\n}\n\n/** 内置模板(官方服务器为主,命令与包名可被用户覆盖) */\nexport const MCP_PRESETS: McpPreset[] = [\n {\n id: \"filesystem\",\n title: \"Filesystem(本地文件)\",\n description: \"让 MCP 读写指定目录,npx 自动拉取官方 server\",\n config: {\n name: \"filesystem\",\n type: \"stdio\",\n command: [\n \"npx\",\n \"-y\",\n \"@modelcontextprotocol/server-filesystem\",\n \"{{dir}}\",\n ],\n enabled: true,\n },\n fields: [\n {\n key: \"dir\",\n label: \"允许访问的目录(绝对路径)\",\n required: true,\n },\n ],\n },\n {\n id: \"memory\",\n title: \"Memory(知识图谱记忆)\",\n description: \"官方 memory server,提供实体/关系记忆\",\n config: {\n name: \"memory\",\n type: \"stdio\",\n command: [\"npx\", \"-y\", \"@modelcontextprotocol/server-memory\"],\n enabled: true,\n },\n },\n {\n id: \"sequential-thinking\",\n title: \"Sequential Thinking(分步推理)\",\n description: \"官方分步思考 server\",\n config: {\n name: \"sequential-thinking\",\n type: \"stdio\",\n command: [\n \"npx\",\n \"-y\",\n \"@modelcontextprotocol/server-sequential-thinking\",\n ],\n enabled: true,\n },\n },\n {\n id: \"github\",\n title: \"GitHub\",\n description: \"官方 GitHub server(需要 Personal Access Token)\",\n config: {\n name: \"github\",\n type: \"stdio\",\n command: [\"npx\", \"-y\", \"@modelcontextprotocol/server-github\"],\n env: { GITHUB_PERSONAL_ACCESS_TOKEN: \"{{token}}\" },\n enabled: true,\n },\n fields: [\n {\n key: \"token\",\n label: \"GitHub Personal Access Token\",\n required: true,\n secret: true,\n },\n ],\n },\n {\n id: \"fetch\",\n title: \"Fetch(网页抓取)\",\n description: \"官方 Python server,需要 uvx(pip install uv)\",\n config: {\n name: \"fetch\",\n type: \"stdio\",\n command: [\"uvx\", \"mcp-server-fetch\"],\n enabled: true,\n },\n },\n {\n id: \"postgres\",\n title: \"PostgreSQL(只读查询)\",\n description: \"官方 postgres server(需要连接串)\",\n config: {\n name: \"postgres\",\n type: \"stdio\",\n command: [\n \"npx\",\n \"-y\",\n \"@modelcontextprotocol/server-postgres\",\n \"{{dsn}}\",\n ],\n enabled: true,\n },\n fields: [\n {\n key: \"dsn\",\n label: \"连接串(postgresql://user:pass@host/db)\",\n required: true,\n secret: true,\n },\n ],\n },\n {\n id: \"ocr\",\n title: \"OCR(内置,开箱即用)\",\n description:\n \"进程内 OCR:macOS Vision / tesseract / 多模态模型自动降级,无需安装\",\n config: {\n name: \"ocr\",\n type: \"builtin\",\n builtin: \"ocr\",\n enabled: true,\n },\n },\n];\n\nfunction replacePlaceholders(\n value: string,\n values: Record<string, string>,\n): string {\n return value.replace(/\\{\\{([A-Za-z0-9_]+)\\}\\}/g, (_m, key: string) => {\n return values[key] ?? \"\";\n });\n}\n\n/** 用填写的占位符生成最终配置(不会修改模板对象) */\nexport function applyMcpPreset(\n preset: McpPreset,\n values: Record<string, string>,\n): McpServerConfig {\n const base = preset.config;\n const config: McpServerConfig = {\n ...base,\n name: base.name ?? preset.id,\n };\n if (config.command)\n config.command = config.command.map((c) =>\n replacePlaceholders(c, values),\n );\n if (config.url) config.url = replacePlaceholders(config.url, values);\n if (config.cwd) config.cwd = replacePlaceholders(config.cwd, values);\n if (config.env) {\n config.env = Object.fromEntries(\n Object.entries(config.env).map(([k, v]) => [\n k,\n replacePlaceholders(v, values),\n ]),\n );\n }\n if (config.headers) {\n config.headers = Object.fromEntries(\n Object.entries(config.headers).map(([k, v]) => [\n k,\n replacePlaceholders(v, values),\n ]),\n );\n }\n return config;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,39 @@
1
+ import { a as McpServerConfig } from '../../McpClient-CEQBUPuC.cjs';
2
+
3
+ /**
4
+ * MCP 安装模板
5
+ *
6
+ * 用于 `/mcp add` 交互式向导:把常见官方服务器的启动命令与参数固化,
7
+ * 用户只需按提示填写少量占位符。`{{key}}` 会在安装时被替换。
8
+ */
9
+
10
+ /** 模板占位符 */
11
+ interface McpPresetField {
12
+ /** 替换 config 中的 {{key}} */
13
+ key: string;
14
+ /** 提示文案 */
15
+ label: string;
16
+ /** 必填(为空则取消安装) */
17
+ required?: boolean;
18
+ /** 隐藏输入(写入 env/headers 的密钥) */
19
+ secret?: boolean;
20
+ /** 默认值 */
21
+ default?: string;
22
+ }
23
+ /** 安装模板 */
24
+ interface McpPreset {
25
+ id: string;
26
+ title: string;
27
+ description: string;
28
+ /** name 缺省时使用 id */
29
+ config: Omit<McpServerConfig, "name"> & {
30
+ name?: string;
31
+ };
32
+ fields?: McpPresetField[];
33
+ }
34
+ /** 内置模板(官方服务器为主,命令与包名可被用户覆盖) */
35
+ declare const MCP_PRESETS: McpPreset[];
36
+ /** 用填写的占位符生成最终配置(不会修改模板对象) */
37
+ declare function applyMcpPreset(preset: McpPreset, values: Record<string, string>): McpServerConfig;
38
+
39
+ export { MCP_PRESETS, type McpPreset, type McpPresetField, applyMcpPreset };
@@ -0,0 +1,39 @@
1
+ import { a as McpServerConfig } from '../../McpClient-CEQBUPuC.js';
2
+
3
+ /**
4
+ * MCP 安装模板
5
+ *
6
+ * 用于 `/mcp add` 交互式向导:把常见官方服务器的启动命令与参数固化,
7
+ * 用户只需按提示填写少量占位符。`{{key}}` 会在安装时被替换。
8
+ */
9
+
10
+ /** 模板占位符 */
11
+ interface McpPresetField {
12
+ /** 替换 config 中的 {{key}} */
13
+ key: string;
14
+ /** 提示文案 */
15
+ label: string;
16
+ /** 必填(为空则取消安装) */
17
+ required?: boolean;
18
+ /** 隐藏输入(写入 env/headers 的密钥) */
19
+ secret?: boolean;
20
+ /** 默认值 */
21
+ default?: string;
22
+ }
23
+ /** 安装模板 */
24
+ interface McpPreset {
25
+ id: string;
26
+ title: string;
27
+ description: string;
28
+ /** name 缺省时使用 id */
29
+ config: Omit<McpServerConfig, "name"> & {
30
+ name?: string;
31
+ };
32
+ fields?: McpPresetField[];
33
+ }
34
+ /** 内置模板(官方服务器为主,命令与包名可被用户覆盖) */
35
+ declare const MCP_PRESETS: McpPreset[];
36
+ /** 用填写的占位符生成最终配置(不会修改模板对象) */
37
+ declare function applyMcpPreset(preset: McpPreset, values: Record<string, string>): McpServerConfig;
38
+
39
+ export { MCP_PRESETS, type McpPreset, type McpPresetField, applyMcpPreset };