foliko 1.1.7 → 1.1.8

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 (250) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  28. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
  29. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
  30. package/.agent/ARCHITECTURE.md +288 -0
  31. package/.agent/agents/ambient-agent.md +57 -0
  32. package/.agent/agents/debugger.md +55 -0
  33. package/.agent/agents/email-assistant.md +49 -0
  34. package/.agent/agents/file-manager.md +42 -0
  35. package/.agent/agents/python-developer.md +60 -0
  36. package/.agent/agents/scheduler.md +59 -0
  37. package/.agent/agents/web-developer.md +45 -0
  38. package/.agent/data/default.json +412 -3
  39. package/.agent/data/plugins-state.json +172 -173
  40. package/.agent/data/puppeteer-sessions/undefined.json +6 -0
  41. package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
  42. package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
  43. package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
  44. package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
  45. package/.agent/mcp_config.json +11 -3
  46. package/.agent/memory/feedback/mnrdvj5i-ca3dkd.md +9 -0
  47. package/.agent/memory/feedback/mnre365e-7s4zax.md +9 -0
  48. package/.agent/memory/feedback/mnre36jn-nkfgmp.md +9 -0
  49. package/.agent/memory/feedback/mnre3805-kjiq6h.md +9 -0
  50. package/.agent/memory/feedback/mnsf66kp-b10rcd.md +9 -0
  51. package/.agent/memory/feedback/mnsi3sz8-p5g2cw.md +9 -0
  52. package/.agent/memory/feedback/mnsibe47-sv2ni1.md +9 -0
  53. package/.agent/memory/feedback/mnsic89w-nn228o.md +9 -0
  54. package/.agent/memory/feedback/mnsj1xe9-x83ba0.md +9 -0
  55. package/.agent/memory/feedback/mnsj21iv-wnwelx.md +9 -0
  56. package/.agent/memory/feedback/mnsj2g4a-cog7a2.md +9 -0
  57. package/.agent/memory/feedback/mnsj4js7-lktjp6.md +9 -0
  58. package/.agent/memory/feedback/mnsj5d4y-uglwvp.md +9 -0
  59. package/.agent/memory/feedback/mnslkuo9-uous66.md +24 -0
  60. package/.agent/memory/feedback/mnsm3vq0-megoil.md +9 -0
  61. package/.agent/memory/feedback/mnsnn5x2-sxcihd.md +9 -0
  62. package/.agent/memory/feedback/mnsnq17s-nabrn9.md +9 -0
  63. package/.agent/memory/feedback/mnsnybet-wz7rn3.md +9 -0
  64. package/.agent/memory/feedback/mnsrw0s7-7s9e30.md +9 -0
  65. package/.agent/memory/feedback/mnu5hpnd-tlm16q.md +9 -0
  66. package/.agent/memory/feedback/mnu60uqe-xuoxp4.md +9 -0
  67. package/.agent/memory/project/mnqx54u5-loqtoe.md +9 -0
  68. package/.agent/memory/project/mnqx84cv-mx6dmd.md +9 -0
  69. package/.agent/memory/project/mnsacuyr-hgtk5n.md +20 -0
  70. package/.agent/memory/project/mnu5hy2x-bjsg7u.md +9 -0
  71. package/.agent/memory/reference/mnre3cww-penbo1.md +9 -0
  72. package/.agent/memory/reference/mns9wn48-luerua.md +14 -0
  73. package/.agent/memory/reference/mns9yz5c-thc2s0.md +16 -0
  74. package/.agent/memory/reference/mnsfy4um-910f1o.md +23 -0
  75. package/.agent/memory/reference/mnsg37dp-lmfj18.md +32 -0
  76. package/.agent/memory/reference/mnsll60q-0j911u.md +36 -0
  77. package/.agent/memory/reference/mnsmlb5y-nej31u.md +16 -0
  78. package/.agent/memory/reference/mnssle72-yrot96.md +9 -0
  79. package/.agent/memory/user/mnsfuon6-l416q1.md +21 -0
  80. package/.agent/memory/user/mnsg9kut-95m7rf.md +20 -0
  81. package/.agent/memory/user/mnu2eo1v-yy6fhe.md +9 -0
  82. package/.agent/memory/user/mnu2etuo-8u8jk8.md +9 -0
  83. package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
  84. package/.agent/plugins/poster-plugin/fonts/Symbola_hint.ttf +0 -0
  85. package/.agent/plugins/poster-plugin/package.json +3 -3
  86. package/.agent/plugins/poster-plugin/src/canvas.js +8 -0
  87. package/.agent/plugins/poster-plugin/src/components/barcode.js +5 -2
  88. package/.agent/plugins/poster-plugin/src/components/bubble.js +3 -2
  89. package/.agent/plugins/poster-plugin/src/components/button.js +74 -30
  90. package/.agent/plugins/poster-plugin/src/components/columns.js +97 -83
  91. package/.agent/plugins/poster-plugin/src/components/grid.js +104 -92
  92. package/.agent/plugins/poster-plugin/src/components/highlightText.js +2 -1
  93. package/.agent/plugins/poster-plugin/src/components/imageFrame.js +143 -93
  94. package/.agent/plugins/poster-plugin/src/components/quote.js +85 -13
  95. package/.agent/plugins/poster-plugin/src/components/ribbon.js +13 -9
  96. package/.agent/plugins/poster-plugin/src/components/seal.js +5 -3
  97. package/.agent/plugins/poster-plugin/src/components/star.js +3 -3
  98. package/.agent/plugins/poster-plugin/src/components/table.js +1 -1
  99. package/.agent/plugins/poster-plugin/src/components/watermark.js +4 -2
  100. package/.agent/plugins/poster-plugin/src/composer.js +181 -13
  101. package/.agent/plugins/poster-plugin/src/elements/artText.js +16 -7
  102. package/.agent/plugins/poster-plugin/src/elements/background.js +20 -5
  103. package/.agent/plugins/poster-plugin/src/elements/richText.js +160 -107
  104. package/.agent/plugins/poster-plugin/src/elements/text.js +48 -45
  105. package/.agent/plugins/poster-plugin/src/fonts.js +556 -125
  106. package/.agent/plugins/poster-plugin/src/index.js +46 -1
  107. package/.agent/plugins/poster-plugin/yarn.lock +186 -356
  108. package/.agent/plugins/puppeteer-plugin/README.md +147 -0
  109. package/.agent/plugins/puppeteer-plugin/index.js +1422 -0
  110. package/.agent/plugins/puppeteer-plugin/package.json +9 -0
  111. package/.agent/plugins.json +5 -11
  112. package/.agent/rules/GEMINI.md +273 -0
  113. package/.agent/rules/allow-rule.md +77 -0
  114. package/.agent/rules/log-rule.md +83 -0
  115. package/.agent/rules/security-rule.md +93 -0
  116. package/.agent/scripts/auto_preview.py +148 -0
  117. package/.agent/scripts/checklist.py +217 -0
  118. package/.agent/scripts/session_manager.py +120 -0
  119. package/.agent/scripts/verify_all.py +327 -0
  120. package/.agent/sessions/cli_default.json +122 -689
  121. package/.agent/skills/api-patterns/SKILL.md +81 -0
  122. package/.agent/skills/api-patterns/api-style.md +42 -0
  123. package/.agent/skills/api-patterns/auth.md +24 -0
  124. package/.agent/skills/api-patterns/documentation.md +26 -0
  125. package/.agent/skills/api-patterns/graphql.md +41 -0
  126. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  127. package/.agent/skills/api-patterns/response.md +37 -0
  128. package/.agent/skills/api-patterns/rest.md +40 -0
  129. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  130. package/.agent/skills/api-patterns/security-testing.md +122 -0
  131. package/.agent/skills/api-patterns/trpc.md +41 -0
  132. package/.agent/skills/api-patterns/versioning.md +22 -0
  133. package/.agent/skills/app-builder/SKILL.md +75 -0
  134. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  135. package/.agent/skills/app-builder/feature-building.md +53 -0
  136. package/.agent/skills/app-builder/project-detection.md +34 -0
  137. package/.agent/skills/app-builder/scaffolding.md +118 -0
  138. package/.agent/skills/app-builder/tech-stack.md +40 -0
  139. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  140. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  141. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  142. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  143. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  144. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  145. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  146. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  147. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  148. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  149. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  150. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  151. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  152. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  153. package/.agent/skills/architecture/SKILL.md +55 -0
  154. package/.agent/skills/architecture/context-discovery.md +43 -0
  155. package/.agent/skills/architecture/examples.md +94 -0
  156. package/.agent/skills/architecture/pattern-selection.md +68 -0
  157. package/.agent/skills/architecture/patterns-reference.md +50 -0
  158. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  159. package/.agent/skills/clean-code/SKILL.md +201 -0
  160. package/.agent/skills/doc.md +177 -0
  161. package/.agent/skills/frontend-design/SKILL.md +418 -0
  162. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  163. package/.agent/skills/frontend-design/color-system.md +311 -0
  164. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  165. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  166. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  167. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  168. package/.agent/skills/frontend-design/typography-system.md +345 -0
  169. package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
  170. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  171. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  172. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  173. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  174. package/.agent/skills/poster-design/SKILL.md +385 -0
  175. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  176. package/.agent/workflows/brainstorm.md +113 -0
  177. package/.agent/workflows/create.md +59 -0
  178. package/.agent/workflows/debug.md +103 -0
  179. package/.agent/workflows/deploy.md +176 -0
  180. package/.agent/workflows/enhance.md +63 -0
  181. package/.agent/workflows/orchestrate.md +237 -0
  182. package/.agent/workflows/plan.md +89 -0
  183. package/.agent/workflows/preview.md +81 -0
  184. package/.agent/workflows/simple-test.md +42 -0
  185. package/.agent/workflows/status.md +86 -0
  186. package/.agent/workflows/structured-orchestrate.md +180 -0
  187. package/.agent/workflows/test.md +144 -0
  188. package/.agent/workflows/ui-ux-pro-max.md +296 -0
  189. package/.claude/settings.local.json +1 -2
  190. package/.env.example +56 -56
  191. package/README.md +441 -441
  192. package/output/foliko-poster.png +0 -0
  193. package/outputs/emoji-font-showcase.png +0 -0
  194. package/outputs/foliko-muji-style.png +0 -0
  195. package/package.json +3 -2
  196. package/plugins/default-plugins.js +2 -1
  197. package/plugins/extension-executor-plugin.js +24 -1
  198. package/plugins/feishu-plugin.js +2 -2
  199. package/plugins/telegram-plugin.js +2 -2
  200. package/plugins/weixin-plugin.js +2 -2
  201. package/skills/find-skills/AGENTS.md +162 -162
  202. package/skills/find-skills/SKILL.md +133 -133
  203. package/src/core/agent.js +117 -29
  204. package/src/executors/mcp-executor.js +282 -26
  205. package/system.md +719 -570
  206. package/.agent/agents/code-assistant.json +0 -17
  207. package/.agent/agents/email-assistant.json +0 -14
  208. package/.agent/agents/file-assistant.json +0 -18
  209. package/.agent/agents/orchestrator-demo.md +0 -53
  210. package/.agent/agents/orchestrator.json +0 -7
  211. package/.agent/agents/system-assistant.json +0 -15
  212. package/.agent/agents/web-assistant.json +0 -12
  213. package/.agent/data/email/processed-emails.json +0 -1
  214. package/.agent/data/scheduler/tasks.json +0 -1
  215. package/.agent/data/web/web-config.json +0 -5
  216. package/.agent/memory/feedback/mnt7jrlt-d67qs7.md +0 -15
  217. package/.agent/memory/feedback/mnt88ja3-al4fuy.md +0 -9
  218. package/.agent/package.json +0 -8
  219. package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
  220. package/.agent/plugins/daytona/README.md +0 -89
  221. package/.agent/plugins/daytona/index.js +0 -377
  222. package/.agent/plugins/daytona/package.json +0 -12
  223. package/.agent/plugins/marknative/README.md +0 -134
  224. package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
  225. package/.agent/plugins/marknative/fonts.zip +0 -0
  226. package/.agent/plugins/marknative/index.js +0 -256
  227. package/.agent/plugins/marknative/package.json +0 -12
  228. package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
  229. package/.agent/plugins/poster-plugin/test-background.svg +0 -1
  230. package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
  231. package/.agent/plugins/poster-plugin/test-image.png +0 -0
  232. package/.agent/plugins/system-info/index.js +0 -387
  233. package/.agent/plugins/system-info/package.json +0 -4
  234. package/.agent/plugins/system-info/test.js +0 -40
  235. package/.agent/plugins/test-plugin.py +0 -108
  236. package/.agent/python-scripts/test_sample.py +0 -24
  237. package/.agent/skills/agent-browser/SKILL.md +0 -311
  238. package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
  239. package/.agent/skills/sysinfo/SKILL.md +0 -38
  240. package/.agent/skills/sysinfo/system-info.sh +0 -130
  241. package/.agent/skills/workflow/SKILL.md +0 -324
  242. package/.agent/test-agent.js +0 -35
  243. package/.agent/weixin.json +0 -6
  244. package/.agent/workflows/email-digest.json +0 -50
  245. package/.agent/workflows/file-backup.json +0 -21
  246. package/.agent/workflows/get-ip-notify.json +0 -32
  247. package/.agent/workflows/news-aggregator.json +0 -93
  248. package/.agent/workflows/news-dashboard-v2.json +0 -94
  249. package/.agent/workflows/notification-batch.json +0 -32
  250. package/output/zen_silence.png +0 -0
@@ -202,6 +202,8 @@ class MCPExecutorPlugin extends Plugin {
202
202
  this._framework = null;
203
203
  // serverName -> { client, tools: [{ name, description, inputSchema }], toolObjects: { toolName: actualTool } }
204
204
  this._clients = new Map();
205
+ // 保存服务器配置,用于重新启用
206
+ this._serverConfigs = new Map();
205
207
  this._config = config;
206
208
  // 注册的工具对象(extension-executor 会扫描这个)
207
209
  // 格式: { 'server_toolname': { name, description, inputSchema, execute } }
@@ -217,6 +219,12 @@ class MCPExecutorPlugin extends Plugin {
217
219
  // 先连接所有 MCP 服务器
218
220
  if (this._config.servers) {
219
221
  for (const serverConfig of this._config.servers) {
222
+ if (serverConfig.enabled === false) {
223
+ log.info(` Skipping disabled server: ${serverConfig.name}`);
224
+ // 保存完整配置,以便后续动态启用
225
+ this._serverConfigs.set(serverConfig.name, { ...serverConfig });
226
+ continue;
227
+ }
220
228
  await this.addServer(serverConfig);
221
229
  }
222
230
  }
@@ -409,12 +417,26 @@ class MCPExecutorPlugin extends Plugin {
409
417
  inputSchema: z.object({}),
410
418
  execute: async () => {
411
419
  const servers = [];
420
+ // 已连接的服务器
412
421
  for (const [name, info] of this._clients) {
413
422
  servers.push({
414
423
  name,
424
+ enabled: true,
425
+ connected: true,
415
426
  tools: info.tools.map((t) => ({ name: t.name, description: t.description })),
416
427
  });
417
428
  }
429
+ // 未连接的服务器(配置中存在但未启用)
430
+ for (const [name, config] of this._serverConfigs) {
431
+ if (!this._clients.has(name)) {
432
+ servers.push({
433
+ name,
434
+ enabled: false,
435
+ connected: false,
436
+ tools: [],
437
+ });
438
+ }
439
+ }
418
440
  return { success: true, servers };
419
441
  },
420
442
  });
@@ -456,6 +478,77 @@ class MCPExecutorPlugin extends Plugin {
456
478
  },
457
479
  });
458
480
 
481
+ // 注册 mcp_set_enabled 工具 - 动态开启/关闭 MCP 服务器
482
+ framework.registerTool({
483
+ name: 'mcp_set_enabled',
484
+ description: '动态开启或关闭某个 MCP 服务器',
485
+ inputSchema: z.object({
486
+ server: z.string().describe('MCP 服务器名称'),
487
+ enabled: z.boolean().describe('true=开启,false=关闭'),
488
+ }),
489
+ execute: async (args) => {
490
+ const { server, enabled } = args;
491
+ const clientInfo = this._clients.get(server);
492
+ const serverConfig = this._serverConfigs.get(server);
493
+
494
+ if (enabled) {
495
+ // 启用服务器
496
+ if (clientInfo && clientInfo.enabled) {
497
+ return { success: true, message: `MCP 服务器 '${server}' 已经是开启状态` };
498
+ }
499
+ // 如果服务器从未连接过,也检查配置中的 enabled 状态
500
+ if (!clientInfo && serverConfig && serverConfig.enabled === false) {
501
+ // 服务器是被禁用的,可以尝试启用
502
+ }
503
+ log.info(
504
+ `[MCP] Enabling server: ${server}, clientInfo=${!!clientInfo}, serverConfig.enabled=${serverConfig?.enabled}`
505
+ );
506
+ try {
507
+ if (serverConfig) {
508
+ const result = await this.addServer({ ...serverConfig, enabled: true });
509
+ log.info(`[MCP] addServer result:`, JSON.stringify(result));
510
+ if (!result || result.success === false) {
511
+ this._refreshAllAgentsMCPPrompt(this._framework);
512
+ return result;
513
+ }
514
+ // 保存 enabled 状态到配置文件
515
+ await this._saveMCPServerEnabled(server, true);
516
+ this._refreshAllAgentsMCPPrompt(this._framework);
517
+ return { success: true, message: `MCP 服务器 '${server}' 已开启` };
518
+ } else {
519
+ return { success: false, error: '服务器配置不存在,需要重载配置' };
520
+ }
521
+ } catch (err) {
522
+ log.error(`[MCP] Enabling failed:`, err.message);
523
+ return { success: false, error: `开启失败: ${err.message}` };
524
+ }
525
+ } else {
526
+ // 禁用服务器
527
+ if (!clientInfo) {
528
+ return { success: false, error: `MCP server '${server}' not found` };
529
+ }
530
+ log.info(` Disabling MCP server: ${server}`);
531
+ try {
532
+ clientInfo.client.close?.();
533
+ } catch (e) {}
534
+ // 从 clients 中移除
535
+ this._clients.delete(server);
536
+ // 移除该服务器注册的工具
537
+ for (const key of Object.keys(this.tools)) {
538
+ if (key.startsWith(`${server}_`)) {
539
+ delete this.tools[key];
540
+ }
541
+ }
542
+ // 保存 enabled 状态到配置文件
543
+ await this._saveMCPServerEnabled(server, false);
544
+ this._refreshAllAgentsMCPPrompt(this._framework);
545
+ return { success: true, message: `MCP 服务器 '${server}' 已关闭` };
546
+ }
547
+
548
+ return { success: true, message: `MCP 服务器 '${server}' 状态未变化` };
549
+ },
550
+ });
551
+
459
552
  // 监听 agent 创建事件,附加 MCP 信息到系统提示词
460
553
  framework.on('agent:created', (agent) => {
461
554
  if (!this._mainAgent) {
@@ -485,7 +578,7 @@ class MCPExecutorPlugin extends Plugin {
485
578
  const traverse = (agent) => {
486
579
  if (!agent || visited.has(agent)) return;
487
580
  visited.add(agent);
488
- this._refreshAgentMCPPrompt(agent);
581
+ //this._refreshAgentMCPPrompt(agent);
489
582
 
490
583
  // 递归处理子 agent
491
584
  const subAgents = agent.getSubAgents?.() || agent._subAgents || new Map();
@@ -509,11 +602,11 @@ class MCPExecutorPlugin extends Plugin {
509
602
  return;
510
603
  }
511
604
 
512
- const mcpDesc = this._buildMCPServersDescription();
513
- if (!mcpDesc) return;
605
+ // const mcpDesc = this._buildMCPServersDescription();
606
+ // if (!mcpDesc) return;
514
607
 
515
608
  // 将 MCP 描述追加到系统提示词
516
- agent.setSystemPrompt(existingPrompt + '\n\n' + mcpDesc);
609
+ //agent.setSystemPrompt(existingPrompt + '\n\n' + mcpDesc);
517
610
  }
518
611
 
519
612
  /**
@@ -592,8 +685,12 @@ class MCPExecutorPlugin extends Plugin {
592
685
  }
593
686
  }
594
687
  } catch (e) {
595
- // 如果转换失败,使用简化格式
596
- desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
688
+ // 如果转换失败,使用 fallback
689
+ try {
690
+ desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
691
+ } catch (e2) {
692
+ // fallback 也失败,忽略参数描述
693
+ }
597
694
  }
598
695
  }
599
696
  }
@@ -606,6 +703,61 @@ class MCPExecutorPlugin extends Plugin {
606
703
  return desc.trim();
607
704
  }
608
705
 
706
+ _bindMcpParamsDesc(rawSchema) {
707
+ let desc = '';
708
+ const schema = this._extractSchema(rawSchema);
709
+ if (!schema) return desc;
710
+ try {
711
+ let schemaResult = null;
712
+ let zodSchemaForFallback = null; // 保存 Zod schema 供 fallback 使用
713
+ // 检查是否是 Zod schema (有 shape 方法或 _def 属性)
714
+ const isZodSchema =
715
+ typeof schema.shape === 'function' || (schema._def && schema._def.typeName);
716
+ if (isZodSchema) {
717
+ // Zod schema 直接转换
718
+ schemaResult = zodSchemaToMarkdown(schema);
719
+ zodSchemaForFallback = schema;
720
+ } else if (schema.jsonSchema) {
721
+ // JSON Schema 格式,尝试转换为 Zod schema
722
+ const zodSchema = this._jsonSchemaToZod(schema.jsonSchema || schema);
723
+ if (zodSchema) {
724
+ schemaResult = zodSchemaToMarkdown(zodSchema);
725
+ zodSchemaForFallback = zodSchema;
726
+ }
727
+ } else if (schema.properties) {
728
+ // 已经是对象格式
729
+ const zodSchema = this._jsonSchemaToZod(schema);
730
+ if (zodSchema) {
731
+ schemaResult = zodSchemaToMarkdown(zodSchema);
732
+ zodSchemaForFallback = zodSchema;
733
+ }
734
+ }
735
+
736
+ // 检查是否包含未解析的原始 Zod 类型名或只有类型信息没有参数
737
+ if (schemaResult) {
738
+ const hasUnparsedTypes = /\|.*\bZod\w+\b.*\|/.test(schemaResult);
739
+ // 检查是否只有类型信息而没有实际参数(如 "Type: Object" 或 "Type: ZodAny")
740
+ const hasOnlyType =
741
+ /^-\s+\w+:\s+.+\n?$/.test(schemaResult.trim()) && !schemaResult.includes('`');
742
+ if (hasUnparsedTypes || hasOnlyType) {
743
+ // zodSchemaToMarkdown 未正确解析,使用 fallback
744
+ desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
745
+ } else {
746
+ desc += `**参数:**\n\n`;
747
+ desc += schemaResult + '\n\n';
748
+ }
749
+ }
750
+ } catch (e) {
751
+ // 如果转换失败,使用 fallback
752
+ try {
753
+ desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
754
+ } catch (e2) {
755
+ // fallback 也失败,忽略参数描述
756
+ }
757
+ }
758
+ return desc;
759
+ }
760
+
609
761
  /**
610
762
  * 将 JSON Schema 转换为 Zod schema
611
763
  */
@@ -711,20 +863,31 @@ class MCPExecutorPlugin extends Plugin {
711
863
  * 从 Zod schema 字段提取类型信息
712
864
  */
713
865
  _extractZodFieldType(field) {
866
+ if (!field) {
867
+ return { type: 'unknown', isOptional: false, description: '' };
868
+ }
869
+
714
870
  const typeName = field._def?.typeName || field.constructor?.name || '';
715
871
  const description = field.description || field._def?.description || '';
716
872
 
717
873
  switch (typeName) {
718
874
  case 'ZodOptional': {
719
- const inner = field._def.innerType;
875
+ const inner = field._def?.innerType;
876
+ if (!inner) return { type: 'optional', isOptional: true, description };
720
877
  return this._extractZodFieldType(inner);
721
878
  }
722
879
  case 'ZodArray': {
723
- const innerInfo = this._extractZodFieldType(field._def.type);
880
+ const inner = field._def?.type;
881
+ if (!inner) return { type: 'array', isOptional: false, description };
882
+ const innerInfo = this._extractZodFieldType(inner);
724
883
  return { type: `${innerInfo.type}[]`, isOptional: false, description };
725
884
  }
726
885
  case 'ZodObject': {
727
- const shape = field._def.shape();
886
+ const shapeFn = field._def?.shape;
887
+ if (typeof shapeFn !== 'function')
888
+ return { type: 'object', isOptional: false, description };
889
+ const shape = shapeFn();
890
+ if (!shape) return { type: 'object', isOptional: false, description };
728
891
  const props = Object.keys(shape).join(', ');
729
892
  return { type: `object{${props}}`, isOptional: false, description };
730
893
  }
@@ -734,31 +897,44 @@ class MCPExecutorPlugin extends Plugin {
734
897
  return { type: 'number', isOptional: false, description };
735
898
  case 'ZodBoolean':
736
899
  return { type: 'boolean', isOptional: false, description };
737
- case 'ZodEnum':
900
+ case 'ZodEnum': {
901
+ const values = field._def?.values;
902
+ if (!values) return { type: 'enum', isOptional: false, description };
738
903
  return {
739
- type: field._def.values.map((v) => `"${v}"`).join(' | '),
904
+ type: values.map((v) => `"${v}"`).join(' | '),
740
905
  isOptional: false,
741
906
  description,
742
907
  };
908
+ }
743
909
  case 'ZodUnion': {
744
- const types = field._def.options.map((opt) => this._extractZodFieldType(opt).type);
910
+ const options = field._def?.options;
911
+ if (!options) return { type: 'union', isOptional: false, description };
912
+ const types = options.map((opt) => this._extractZodFieldType(opt).type);
745
913
  return { type: `union(${types.join(' | ')})`, isOptional: false, description };
746
914
  }
747
915
  case 'ZodLiteral':
748
- return { type: JSON.stringify(field._def.value), isOptional: false, description };
916
+ return { type: JSON.stringify(field._def?.value), isOptional: false, description };
749
917
  case 'ZodRecord': {
750
- const keyType = this._extractZodFieldType(field._def.keyType).type;
751
- const valueType = this._extractZodFieldType(field._def.valueType).type;
752
- return { type: `record<${keyType}, ${valueType}>`, isOptional: false, description };
918
+ const keyType = this._extractZodFieldType(field._def?.keyType);
919
+ const valueType = this._extractZodFieldType(field._def?.valueType);
920
+ return {
921
+ type: `record<${keyType?.type || 'any'}, ${valueType?.type || 'any'}>`,
922
+ isOptional: false,
923
+ description,
924
+ };
753
925
  }
754
926
  case 'ZodMap': {
755
- const keyType = this._extractZodFieldType(field._def.keyType).type;
756
- const valueType = this._extractZodFieldType(field._def.valueType).type;
757
- return { type: `map<${keyType}, ${valueType}>`, isOptional: false, description };
927
+ const keyType = this._extractZodFieldType(field._def?.keyType);
928
+ const valueType = this._extractZodFieldType(field._def?.valueType);
929
+ return {
930
+ type: `map<${keyType?.type || 'any'}, ${valueType?.type || 'any'}>`,
931
+ isOptional: false,
932
+ description,
933
+ };
758
934
  }
759
935
  case 'ZodSet': {
760
- const valueType = this._extractZodFieldType(field._def.valueType).type;
761
- return { type: `set<${valueType}>`, isOptional: false, description };
936
+ const valueType = this._extractZodFieldType(field._def?.valueType);
937
+ return { type: `set<${valueType?.type || 'any'}>`, isOptional: false, description };
762
938
  }
763
939
  case 'ZodAny':
764
940
  return { type: 'any', isOptional: false, description };
@@ -781,7 +957,9 @@ class MCPExecutorPlugin extends Plugin {
781
957
  case 'ZodNativeEnum':
782
958
  return { type: 'nativeEnum', isOptional: false, description };
783
959
  case 'ZodDefault': {
784
- const innerInfo = this._extractZodFieldType(field._def.innerType);
960
+ const inner = field._def?.innerType;
961
+ if (!inner) return { type: 'default', isOptional: false, description };
962
+ const innerInfo = this._extractZodFieldType(inner);
785
963
  return { type: innerInfo.type, isOptional: false, description };
786
964
  }
787
965
  case 'ZodEffects':
@@ -835,11 +1013,44 @@ class MCPExecutorPlugin extends Plugin {
835
1013
  * 添加 MCP 服务器
836
1014
  */
837
1015
  async addServer(config) {
838
- const { name, command, args = [], env, url, type, headers = {}, authProvider } = config;
1016
+ const {
1017
+ name,
1018
+ command,
1019
+ args = [],
1020
+ env,
1021
+ url,
1022
+ type,
1023
+ headers = {},
1024
+ authProvider,
1025
+ enabled,
1026
+ } = config;
1027
+ log.info(
1028
+ `[MCP] addServer called: ${name}, enabled=${enabled}, hasClient=${this._clients.has(name)}`
1029
+ );
1030
+
839
1031
  if (this._clients.has(name)) {
840
1032
  log.warn(` Server '${name}' already exists, skipping`);
841
- return;
1033
+ return { success: false, error: `Server '${name}' already connected` };
842
1034
  }
1035
+
1036
+ // 如果 enabled === false,跳过连接(用于 mcp_set_enabled 禁用后再开启的场景)
1037
+ if (enabled === false) {
1038
+ log.info(` Server '${name}' is disabled, skipping connection`);
1039
+ return { success: false, error: `Server '${name}' is disabled` };
1040
+ }
1041
+
1042
+ // 保存配置,用于重新启用
1043
+ this._serverConfigs.set(name, {
1044
+ name,
1045
+ command,
1046
+ args,
1047
+ env,
1048
+ url,
1049
+ type,
1050
+ headers,
1051
+ authProvider,
1052
+ enabled,
1053
+ });
843
1054
  log.info(` Connecting to ${name}...`);
844
1055
  let client;
845
1056
  try {
@@ -873,7 +1084,7 @@ class MCPExecutorPlugin extends Plugin {
873
1084
  }
874
1085
  } catch (err) {
875
1086
  log.error(` Failed to create client '${name}':`, err.message);
876
- return;
1087
+ return { success: false, error: `创建客户端失败: ${err.message}` };
877
1088
  }
878
1089
 
879
1090
  // 获取 MCP 服务器的工具列表
@@ -882,7 +1093,8 @@ class MCPExecutorPlugin extends Plugin {
882
1093
  mcpTools = await this._withTimeout(client.tools(), 10000, `client.tools ${name}`);
883
1094
  } catch (err) {
884
1095
  log.error(` Failed to get tools from '${name}':`, err.message);
885
- return;
1096
+ client.close?.();
1097
+ return { success: false, error: `获取工具列表失败: ${err.message}` };
886
1098
  }
887
1099
 
888
1100
  // 提取工具信息和实际工具对象
@@ -921,6 +1133,7 @@ class MCPExecutorPlugin extends Plugin {
921
1133
  client,
922
1134
  tools: toolsInfo,
923
1135
  toolObjects, // 实际工具对象,供 mcp_call 直接调用
1136
+ enabled: config.enabled !== false,
924
1137
  });
925
1138
 
926
1139
  log.info(
@@ -930,6 +1143,8 @@ class MCPExecutorPlugin extends Plugin {
930
1143
  .filter((k) => k.startsWith(name + '_'))
931
1144
  .join(', ')})`
932
1145
  );
1146
+
1147
+ return { success: true, name, toolsCount: toolsInfo.length };
933
1148
  }
934
1149
 
935
1150
  /**
@@ -994,10 +1209,18 @@ class MCPExecutorPlugin extends Plugin {
994
1209
  } catch (e) {}
995
1210
  }
996
1211
  this._clients.clear();
1212
+ // 清理服务器配置
1213
+ this._serverConfigs.clear();
997
1214
 
998
1215
  // 2. 并行添加新服务器
999
1216
  log.info(' Adding new servers...');
1000
1217
  const addPromises = Object.entries(newServers).map(async ([name, serverConfig]) => {
1218
+ if (serverConfig.enabled === false) {
1219
+ log.info(` Skipping disabled server: ${name}`);
1220
+ // 仍保存配置,以便后续动态启用
1221
+ this._serverConfigs.set(name, { name, ...serverConfig });
1222
+ return;
1223
+ }
1001
1224
  const normalizedConfig = {
1002
1225
  name,
1003
1226
  type: serverConfig.type,
@@ -1007,6 +1230,7 @@ class MCPExecutorPlugin extends Plugin {
1007
1230
  command: serverConfig.command,
1008
1231
  args: serverConfig.args,
1009
1232
  env: serverConfig.env,
1233
+ enabled: true,
1010
1234
  };
1011
1235
  await this.addServer(normalizedConfig);
1012
1236
  });
@@ -1020,6 +1244,38 @@ class MCPExecutorPlugin extends Plugin {
1020
1244
  }
1021
1245
  }
1022
1246
 
1247
+ /**
1248
+ * 保存 MCP 服务器的 enabled 状态到配置文件
1249
+ */
1250
+ async _saveMCPServerEnabled(serverName, enabled) {
1251
+ const fs = require('fs');
1252
+ const path = require('path');
1253
+ const configPath = path.resolve('.agent/mcp_config.json');
1254
+
1255
+ try {
1256
+ if (!fs.existsSync(configPath)) {
1257
+ log.warn(` MCP config file not found: ${configPath}`);
1258
+ return false;
1259
+ }
1260
+
1261
+ const configContent = fs.readFileSync(configPath, 'utf8');
1262
+ const config = JSON.parse(configContent);
1263
+
1264
+ if (!config.mcpServers || !config.mcpServers[serverName]) {
1265
+ log.warn(` Server '${serverName}' not found in MCP config`);
1266
+ return false;
1267
+ }
1268
+
1269
+ config.mcpServers[serverName].enabled = enabled;
1270
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
1271
+ log.info(` Saved enabled=${enabled} for server '${serverName}' to config`);
1272
+ return true;
1273
+ } catch (err) {
1274
+ log.error(` Failed to save MCP config:`, err.message);
1275
+ return false;
1276
+ }
1277
+ }
1278
+
1023
1279
  async uninstall(framework) {
1024
1280
  // 断开所有 MCP 连接
1025
1281
  for (const [name, clientInfo] of this._clients) {