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.
- package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +288 -0
- package/.agent/agents/ambient-agent.md +57 -0
- package/.agent/agents/debugger.md +55 -0
- package/.agent/agents/email-assistant.md +49 -0
- package/.agent/agents/file-manager.md +42 -0
- package/.agent/agents/python-developer.md +60 -0
- package/.agent/agents/scheduler.md +59 -0
- package/.agent/agents/web-developer.md +45 -0
- package/.agent/data/default.json +412 -3
- package/.agent/data/plugins-state.json +172 -173
- package/.agent/data/puppeteer-sessions/undefined.json +6 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
- package/.agent/mcp_config.json +11 -3
- package/.agent/memory/feedback/mnrdvj5i-ca3dkd.md +9 -0
- package/.agent/memory/feedback/mnre365e-7s4zax.md +9 -0
- package/.agent/memory/feedback/mnre36jn-nkfgmp.md +9 -0
- package/.agent/memory/feedback/mnre3805-kjiq6h.md +9 -0
- package/.agent/memory/feedback/mnsf66kp-b10rcd.md +9 -0
- package/.agent/memory/feedback/mnsi3sz8-p5g2cw.md +9 -0
- package/.agent/memory/feedback/mnsibe47-sv2ni1.md +9 -0
- package/.agent/memory/feedback/mnsic89w-nn228o.md +9 -0
- package/.agent/memory/feedback/mnsj1xe9-x83ba0.md +9 -0
- package/.agent/memory/feedback/mnsj21iv-wnwelx.md +9 -0
- package/.agent/memory/feedback/mnsj2g4a-cog7a2.md +9 -0
- package/.agent/memory/feedback/mnsj4js7-lktjp6.md +9 -0
- package/.agent/memory/feedback/mnsj5d4y-uglwvp.md +9 -0
- package/.agent/memory/feedback/mnslkuo9-uous66.md +24 -0
- package/.agent/memory/feedback/mnsm3vq0-megoil.md +9 -0
- package/.agent/memory/feedback/mnsnn5x2-sxcihd.md +9 -0
- package/.agent/memory/feedback/mnsnq17s-nabrn9.md +9 -0
- package/.agent/memory/feedback/mnsnybet-wz7rn3.md +9 -0
- package/.agent/memory/feedback/mnsrw0s7-7s9e30.md +9 -0
- package/.agent/memory/feedback/mnu5hpnd-tlm16q.md +9 -0
- package/.agent/memory/feedback/mnu60uqe-xuoxp4.md +9 -0
- package/.agent/memory/project/mnqx54u5-loqtoe.md +9 -0
- package/.agent/memory/project/mnqx84cv-mx6dmd.md +9 -0
- package/.agent/memory/project/mnsacuyr-hgtk5n.md +20 -0
- package/.agent/memory/project/mnu5hy2x-bjsg7u.md +9 -0
- package/.agent/memory/reference/mnre3cww-penbo1.md +9 -0
- package/.agent/memory/reference/mns9wn48-luerua.md +14 -0
- package/.agent/memory/reference/mns9yz5c-thc2s0.md +16 -0
- package/.agent/memory/reference/mnsfy4um-910f1o.md +23 -0
- package/.agent/memory/reference/mnsg37dp-lmfj18.md +32 -0
- package/.agent/memory/reference/mnsll60q-0j911u.md +36 -0
- package/.agent/memory/reference/mnsmlb5y-nej31u.md +16 -0
- package/.agent/memory/reference/mnssle72-yrot96.md +9 -0
- package/.agent/memory/user/mnsfuon6-l416q1.md +21 -0
- package/.agent/memory/user/mnsg9kut-95m7rf.md +20 -0
- package/.agent/memory/user/mnu2eo1v-yy6fhe.md +9 -0
- package/.agent/memory/user/mnu2etuo-8u8jk8.md +9 -0
- package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
- package/.agent/plugins/poster-plugin/fonts/Symbola_hint.ttf +0 -0
- package/.agent/plugins/poster-plugin/package.json +3 -3
- package/.agent/plugins/poster-plugin/src/canvas.js +8 -0
- package/.agent/plugins/poster-plugin/src/components/barcode.js +5 -2
- package/.agent/plugins/poster-plugin/src/components/bubble.js +3 -2
- package/.agent/plugins/poster-plugin/src/components/button.js +74 -30
- package/.agent/plugins/poster-plugin/src/components/columns.js +97 -83
- package/.agent/plugins/poster-plugin/src/components/grid.js +104 -92
- package/.agent/plugins/poster-plugin/src/components/highlightText.js +2 -1
- package/.agent/plugins/poster-plugin/src/components/imageFrame.js +143 -93
- package/.agent/plugins/poster-plugin/src/components/quote.js +85 -13
- package/.agent/plugins/poster-plugin/src/components/ribbon.js +13 -9
- package/.agent/plugins/poster-plugin/src/components/seal.js +5 -3
- package/.agent/plugins/poster-plugin/src/components/star.js +3 -3
- package/.agent/plugins/poster-plugin/src/components/table.js +1 -1
- package/.agent/plugins/poster-plugin/src/components/watermark.js +4 -2
- package/.agent/plugins/poster-plugin/src/composer.js +181 -13
- package/.agent/plugins/poster-plugin/src/elements/artText.js +16 -7
- package/.agent/plugins/poster-plugin/src/elements/background.js +20 -5
- package/.agent/plugins/poster-plugin/src/elements/richText.js +160 -107
- package/.agent/plugins/poster-plugin/src/elements/text.js +48 -45
- package/.agent/plugins/poster-plugin/src/fonts.js +556 -125
- package/.agent/plugins/poster-plugin/src/index.js +46 -1
- package/.agent/plugins/poster-plugin/yarn.lock +186 -356
- package/.agent/plugins/puppeteer-plugin/README.md +147 -0
- package/.agent/plugins/puppeteer-plugin/index.js +1422 -0
- package/.agent/plugins/puppeteer-plugin/package.json +9 -0
- package/.agent/plugins.json +5 -11
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/rules/allow-rule.md +77 -0
- package/.agent/rules/log-rule.md +83 -0
- package/.agent/rules/security-rule.md +93 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/sessions/cli_default.json +122 -689
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/poster-design/SKILL.md +385 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +81 -0
- package/.agent/workflows/simple-test.md +42 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/structured-orchestrate.md +180 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/.claude/settings.local.json +1 -2
- package/.env.example +56 -56
- package/README.md +441 -441
- package/output/foliko-poster.png +0 -0
- package/outputs/emoji-font-showcase.png +0 -0
- package/outputs/foliko-muji-style.png +0 -0
- package/package.json +3 -2
- package/plugins/default-plugins.js +2 -1
- package/plugins/extension-executor-plugin.js +24 -1
- package/plugins/feishu-plugin.js +2 -2
- package/plugins/telegram-plugin.js +2 -2
- package/plugins/weixin-plugin.js +2 -2
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/src/core/agent.js +117 -29
- package/src/executors/mcp-executor.js +282 -26
- package/system.md +719 -570
- package/.agent/agents/code-assistant.json +0 -17
- package/.agent/agents/email-assistant.json +0 -14
- package/.agent/agents/file-assistant.json +0 -18
- package/.agent/agents/orchestrator-demo.md +0 -53
- package/.agent/agents/orchestrator.json +0 -7
- package/.agent/agents/system-assistant.json +0 -15
- package/.agent/agents/web-assistant.json +0 -12
- package/.agent/data/email/processed-emails.json +0 -1
- package/.agent/data/scheduler/tasks.json +0 -1
- package/.agent/data/web/web-config.json +0 -5
- package/.agent/memory/feedback/mnt7jrlt-d67qs7.md +0 -15
- package/.agent/memory/feedback/mnt88ja3-al4fuy.md +0 -9
- package/.agent/package.json +0 -8
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +0 -89
- package/.agent/plugins/daytona/index.js +0 -377
- package/.agent/plugins/daytona/package.json +0 -12
- package/.agent/plugins/marknative/README.md +0 -134
- package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/marknative/fonts.zip +0 -0
- package/.agent/plugins/marknative/index.js +0 -256
- package/.agent/plugins/marknative/package.json +0 -12
- package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
- package/.agent/plugins/poster-plugin/test-background.svg +0 -1
- package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
- package/.agent/plugins/poster-plugin/test-image.png +0 -0
- package/.agent/plugins/system-info/index.js +0 -387
- package/.agent/plugins/system-info/package.json +0 -4
- package/.agent/plugins/system-info/test.js +0 -40
- package/.agent/plugins/test-plugin.py +0 -108
- package/.agent/python-scripts/test_sample.py +0 -24
- package/.agent/skills/agent-browser/SKILL.md +0 -311
- package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
- package/.agent/skills/sysinfo/SKILL.md +0 -38
- package/.agent/skills/sysinfo/system-info.sh +0 -130
- package/.agent/skills/workflow/SKILL.md +0 -324
- package/.agent/test-agent.js +0 -35
- package/.agent/weixin.json +0 -6
- package/.agent/workflows/email-digest.json +0 -50
- package/.agent/workflows/file-backup.json +0 -21
- package/.agent/workflows/get-ip-notify.json +0 -32
- package/.agent/workflows/news-aggregator.json +0 -93
- package/.agent/workflows/news-dashboard-v2.json +0 -94
- package/.agent/workflows/notification-batch.json +0 -32
- 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
|
-
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
904
|
+
type: values.map((v) => `"${v}"`).join(' | '),
|
|
740
905
|
isOptional: false,
|
|
741
906
|
description,
|
|
742
907
|
};
|
|
908
|
+
}
|
|
743
909
|
case 'ZodUnion': {
|
|
744
|
-
const
|
|
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
|
|
916
|
+
return { type: JSON.stringify(field._def?.value), isOptional: false, description };
|
|
749
917
|
case 'ZodRecord': {
|
|
750
|
-
const keyType = this._extractZodFieldType(field._def
|
|
751
|
-
const valueType = this._extractZodFieldType(field._def
|
|
752
|
-
return {
|
|
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
|
|
756
|
-
const valueType = this._extractZodFieldType(field._def
|
|
757
|
-
return {
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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) {
|