foliko 1.0.74 → 1.0.75

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 (237) 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 +29 -0
  39. package/.agent/data/plugins-state.json +255 -0
  40. package/.agent/mcp_config.json +4 -0
  41. package/.agent/mcp_config_updated.json +12 -0
  42. package/.agent/plugins.json +5 -0
  43. package/.agent/rules/GEMINI.md +273 -0
  44. package/.agent/rules/allow-rule.md +77 -0
  45. package/.agent/rules/log-rule.md +83 -0
  46. package/.agent/rules/security-rule.md +93 -0
  47. package/.agent/scripts/auto_preview.py +148 -0
  48. package/.agent/scripts/checklist.py +217 -0
  49. package/.agent/scripts/session_manager.py +120 -0
  50. package/.agent/scripts/verify_all.py +327 -0
  51. package/.agent/skills/api-patterns/SKILL.md +81 -0
  52. package/.agent/skills/api-patterns/api-style.md +42 -0
  53. package/.agent/skills/api-patterns/auth.md +24 -0
  54. package/.agent/skills/api-patterns/documentation.md +26 -0
  55. package/.agent/skills/api-patterns/graphql.md +41 -0
  56. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  57. package/.agent/skills/api-patterns/response.md +37 -0
  58. package/.agent/skills/api-patterns/rest.md +40 -0
  59. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  60. package/.agent/skills/api-patterns/security-testing.md +122 -0
  61. package/.agent/skills/api-patterns/trpc.md +41 -0
  62. package/.agent/skills/api-patterns/versioning.md +22 -0
  63. package/.agent/skills/app-builder/SKILL.md +75 -0
  64. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  65. package/.agent/skills/app-builder/feature-building.md +53 -0
  66. package/.agent/skills/app-builder/project-detection.md +34 -0
  67. package/.agent/skills/app-builder/scaffolding.md +118 -0
  68. package/.agent/skills/app-builder/tech-stack.md +40 -0
  69. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  70. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  71. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  72. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  73. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  74. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  75. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  76. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  77. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  78. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  79. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  80. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  81. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  82. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  83. package/.agent/skills/architecture/SKILL.md +55 -0
  84. package/.agent/skills/architecture/context-discovery.md +43 -0
  85. package/.agent/skills/architecture/examples.md +94 -0
  86. package/.agent/skills/architecture/pattern-selection.md +68 -0
  87. package/.agent/skills/architecture/patterns-reference.md +50 -0
  88. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  89. package/.agent/skills/clean-code/SKILL.md +201 -0
  90. package/.agent/skills/doc.md +177 -0
  91. package/.agent/skills/frontend-design/SKILL.md +418 -0
  92. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  93. package/.agent/skills/frontend-design/color-system.md +311 -0
  94. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  95. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  96. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  97. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  98. package/.agent/skills/frontend-design/typography-system.md +345 -0
  99. package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
  100. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  101. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  102. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  103. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  104. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  105. package/.agent/workflows/brainstorm.md +113 -0
  106. package/.agent/workflows/create.md +59 -0
  107. package/.agent/workflows/debug.md +103 -0
  108. package/.agent/workflows/deploy.md +176 -0
  109. package/.agent/workflows/enhance.md +63 -0
  110. package/.agent/workflows/orchestrate.md +237 -0
  111. package/.agent/workflows/plan.md +89 -0
  112. package/.agent/workflows/preview.md +81 -0
  113. package/.agent/workflows/simple-test.md +42 -0
  114. package/.agent/workflows/status.md +86 -0
  115. package/.agent/workflows/structured-orchestrate.md +180 -0
  116. package/.agent/workflows/test.md +144 -0
  117. package/.agent/workflows/ui-ux-pro-max.md +296 -0
  118. package/.claude/settings.local.json +157 -149
  119. package/.editorconfig +56 -0
  120. package/.husky/pre-commit +4 -0
  121. package/.lintstagedrc +7 -0
  122. package/.prettierignore +29 -0
  123. package/.prettierrc +11 -0
  124. package/CLAUDE.md +2 -0
  125. package/README.md +64 -55
  126. package/SPEC.md +102 -61
  127. package/cli/bin/foliko.js +4 -4
  128. package/cli/src/commands/chat.js +53 -51
  129. package/cli/src/commands/list.js +40 -37
  130. package/cli/src/index.js +18 -18
  131. package/cli/src/ui/chat-ui.js +78 -76
  132. package/cli/src/utils/ansi.js +15 -15
  133. package/cli/src/utils/markdown.js +112 -116
  134. package/docker-compose.yml +1 -1
  135. package/docs/ai-sdk-optimization.md +655 -643
  136. package/docs/features.md +80 -80
  137. package/docs/quick-reference.md +49 -46
  138. package/docs/user-manual.md +411 -380
  139. package/examples/ambient-example.js +95 -97
  140. package/examples/basic.js +115 -110
  141. package/examples/bootstrap.js +52 -43
  142. package/examples/mcp-example.js +56 -53
  143. package/examples/skill-example.js +49 -49
  144. package/examples/test-chat.js +60 -58
  145. package/examples/test-mcp.js +49 -43
  146. package/examples/test-reload.js +38 -40
  147. package/examples/test-telegram.js +3 -3
  148. package/examples/test-tg-bot.js +7 -4
  149. package/examples/test-tg-simple.js +4 -3
  150. package/examples/test-tg.js +3 -3
  151. package/examples/test-think.js +13 -7
  152. package/examples/test-web-plugin.js +61 -56
  153. package/examples/test-weixin-feishu.js +40 -37
  154. package/examples/workflow.js +49 -49
  155. package/foliko-1.0.75.tgz +0 -0
  156. package/package.json +37 -3
  157. package/plugins/ai-plugin.js +7 -5
  158. package/plugins/ambient-agent/EventWatcher.js +113 -0
  159. package/plugins/ambient-agent/ExplorerLoop.js +640 -0
  160. package/plugins/ambient-agent/GoalManager.js +197 -0
  161. package/plugins/ambient-agent/Reflector.js +95 -0
  162. package/plugins/ambient-agent/StateStore.js +90 -0
  163. package/plugins/ambient-agent/constants.js +101 -0
  164. package/plugins/ambient-agent/index.js +579 -0
  165. package/plugins/default-plugins.js +62 -49
  166. package/plugins/email/constants.js +64 -0
  167. package/plugins/email/handlers.js +461 -0
  168. package/plugins/email/index.js +278 -0
  169. package/plugins/email/monitor.js +269 -0
  170. package/plugins/email/parser.js +138 -0
  171. package/plugins/email/reply.js +151 -0
  172. package/plugins/email/utils.js +124 -0
  173. package/plugins/feishu-plugin.js +23 -19
  174. package/plugins/file-system-plugin.js +456 -106
  175. package/plugins/install-plugin.js +6 -4
  176. package/plugins/python-executor-plugin.js +3 -1
  177. package/plugins/python-plugin-loader.js +10 -8
  178. package/plugins/rules-plugin.js +5 -3
  179. package/plugins/scheduler-plugin.js +18 -16
  180. package/plugins/session-plugin.js +3 -1
  181. package/plugins/storage-plugin.js +5 -3
  182. package/plugins/subagent-plugin.js +152 -92
  183. package/plugins/telegram-plugin.js +26 -19
  184. package/plugins/think-plugin.js +4 -2
  185. package/plugins/tools-plugin.js +3 -1
  186. package/plugins/web-plugin.js +15 -13
  187. package/plugins/weixin-plugin.js +43 -36
  188. package/reports/system-health-report-20260401.md +79 -0
  189. package/skills/ambient-agent/SKILL.md +49 -39
  190. package/skills/foliko-dev/AGENTS.md +64 -61
  191. package/skills/foliko-dev/SKILL.md +125 -119
  192. package/skills/mcp-usage/SKILL.md +19 -17
  193. package/skills/python-plugin-dev/SKILL.md +16 -15
  194. package/skills/skill-guide/SKILL.md +12 -12
  195. package/skills/subagent-guide/SKILL.md +237 -0
  196. package/skills/workflow-guide/SKILL.md +90 -45
  197. package/skills/workflow-troubleshooting/DEBUGGING.md +36 -21
  198. package/skills/workflow-troubleshooting/SKILL.md +156 -79
  199. package/src/capabilities/index.js +4 -4
  200. package/src/capabilities/skill-manager.js +211 -197
  201. package/src/capabilities/workflow-engine.js +461 -547
  202. package/src/core/agent-chat.js +426 -279
  203. package/src/core/agent.js +453 -249
  204. package/src/core/framework.js +183 -149
  205. package/src/core/index.js +8 -8
  206. package/src/core/plugin-base.js +52 -52
  207. package/src/core/plugin-manager.js +377 -281
  208. package/src/core/provider.js +35 -32
  209. package/src/core/sub-agent-config.js +264 -0
  210. package/src/core/system-prompt-builder.js +120 -0
  211. package/src/core/tool-registry.js +416 -33
  212. package/src/core/tool-router.js +149 -68
  213. package/src/executors/executor-base.js +58 -58
  214. package/src/executors/mcp-executor.js +269 -257
  215. package/src/index.js +5 -17
  216. package/src/utils/circuit-breaker.js +301 -0
  217. package/src/utils/error-boundary.js +363 -0
  218. package/src/utils/error.js +374 -0
  219. package/src/utils/event-emitter.js +20 -20
  220. package/src/utils/id.js +133 -0
  221. package/src/utils/index.js +217 -3
  222. package/src/utils/logger.js +181 -0
  223. package/src/utils/plugin-helpers.js +90 -0
  224. package/src/utils/retry.js +122 -0
  225. package/src/utils/sandbox.js +292 -0
  226. package/test/tool-registry-validation.test.js +218 -0
  227. package/test_report.md +70 -0
  228. package/website/docs/api.html +169 -107
  229. package/website/docs/configuration.html +296 -144
  230. package/website/docs/plugin-development.html +154 -85
  231. package/website/docs/project-structure.html +110 -109
  232. package/website/docs/skill-development.html +117 -61
  233. package/website/index.html +209 -205
  234. package/website/script.js +20 -17
  235. package/website/styles.css +1 -1
  236. package/plugins/ambient-agent-plugin.js +0 -1565
  237. package/plugins/email.js +0 -1142
@@ -3,9 +3,9 @@
3
3
  * 支持多种 AI 提供商
4
4
  */
5
5
 
6
- const { createOpenAICompatible } = require('@ai-sdk/openai-compatible')
7
- const { createOpenAI } = require('@ai-sdk/openai')
8
- const { createAnthropic } = require('@ai-sdk/anthropic')
6
+ const { createOpenAICompatible } = require('@ai-sdk/openai-compatible');
7
+ const { createOpenAI } = require('@ai-sdk/openai');
8
+ const { createAnthropic } = require('@ai-sdk/anthropic');
9
9
 
10
10
  /**
11
11
  * 默认提供商配置
@@ -13,29 +13,29 @@ const { createAnthropic } = require('@ai-sdk/anthropic')
13
13
  const DEFAULT_PROVIDERS = {
14
14
  openai: {
15
15
  name: 'OpenAI',
16
- baseURL: 'https://api.openai.com/v1'
16
+ baseURL: 'https://api.openai.com/v1',
17
17
  },
18
18
  ollama: {
19
19
  name: 'Ollama',
20
- baseURL: 'http://localhost:11434/v1'
20
+ baseURL: 'http://localhost:11434/v1',
21
21
  },
22
22
  lmstudio: {
23
23
  name: 'LM Studio',
24
- baseURL: 'http://localhost:1234/v1'
24
+ baseURL: 'http://localhost:1234/v1',
25
25
  },
26
26
  deepseek: {
27
27
  name: 'DeepSeek',
28
- baseURL: 'https://api.deepseek.com/v1'
28
+ baseURL: 'https://api.deepseek.com/v1',
29
29
  },
30
30
  anthropic: {
31
31
  name: 'Anthropic',
32
- baseURL: 'https://api.anthropic.com/v1'
32
+ baseURL: 'https://api.anthropic.com/v1',
33
33
  },
34
34
  minimax: {
35
35
  name: 'MiniMax',
36
- baseURL: 'https://api.minimaxi.com/v1'
37
- }
38
- }
36
+ baseURL: 'https://api.minimaxi.com/v1',
37
+ },
38
+ };
39
39
 
40
40
  /**
41
41
  * 创建 AI 客户端
@@ -46,28 +46,31 @@ const DEFAULT_PROVIDERS = {
46
46
  * @param {string} [config.baseURL] - 自定义 API 地址
47
47
  */
48
48
  function createAI(config) {
49
- const { provider, model, apiKey, baseURL } = config
50
- const providerName = (provider || 'deepseek').toLowerCase()
49
+ const { provider, model, apiKey, baseURL } = config;
50
+ const providerName = (provider || 'deepseek').toLowerCase();
51
51
  // 检查是否是预定义提供商
52
52
  if (DEFAULT_PROVIDERS[providerName]) {
53
- const providerConfig = DEFAULT_PROVIDERS[providerName]
53
+ const providerConfig = DEFAULT_PROVIDERS[providerName];
54
54
  return createOpenAICompatible({
55
55
  name: providerConfig.name,
56
56
  baseURL: baseURL || providerConfig.baseURL,
57
57
  apiKey: apiKey || 'dummy-key',
58
- headers: provider === 'anthropic' ? {
59
- 'x-api-key': apiKey,
60
- 'anthropic-version': '2023-06-01'
61
- } : undefined,
58
+ headers:
59
+ provider === 'anthropic'
60
+ ? {
61
+ 'x-api-key': apiKey,
62
+ 'anthropic-version': '2023-06-01',
63
+ }
64
+ : undefined,
62
65
  models: {
63
66
  default: {
64
67
  id: model || 'deepseek-chat',
65
68
  streamOptions: {
66
- includeUsage: true
67
- }
68
- }
69
- }
70
- })
69
+ includeUsage: true,
70
+ },
71
+ },
72
+ },
73
+ });
71
74
  }
72
75
 
73
76
  // 自定义提供商
@@ -77,10 +80,10 @@ function createAI(config) {
77
80
  apiKey: apiKey || 'dummy-key',
78
81
  models: {
79
82
  default: {
80
- id: model || 'gpt-4'
81
- }
82
- }
83
- })
83
+ id: model || 'gpt-4',
84
+ },
85
+ },
86
+ });
84
87
  }
85
88
 
86
89
  /**
@@ -90,8 +93,8 @@ function getAvailableProviders() {
90
93
  return Object.entries(DEFAULT_PROVIDERS).map(([key, value]) => ({
91
94
  id: key,
92
95
  name: value.name,
93
- baseURL: value.baseURL
94
- }))
96
+ baseURL: value.baseURL,
97
+ }));
95
98
  }
96
99
 
97
100
  /**
@@ -100,12 +103,12 @@ function getAvailableProviders() {
100
103
  * @param {Object} provider - Provider 实例
101
104
  */
102
105
  function createModel(model, provider) {
103
- return provider(model)
106
+ return provider(model);
104
107
  }
105
108
 
106
109
  module.exports = {
107
110
  createAI,
108
111
  createModel,
109
112
  getAvailableProviders,
110
- DEFAULT_PROVIDERS
111
- }
113
+ DEFAULT_PROVIDERS,
114
+ };
@@ -0,0 +1,264 @@
1
+ /**
2
+ * SubAgent 配置管理
3
+ * 负责读取、解析和缓存 .agent/agents/ 目录下的 md 文件
4
+ * 类似 SkillManager 的工作方式
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ /**
11
+ * 解析 YAML frontmatter
12
+ */
13
+ function parseFrontmatter(content) {
14
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
15
+ if (!match) return null;
16
+
17
+ const frontmatter = {};
18
+ const lines = match[1].split('\n');
19
+ let currentKey = null;
20
+
21
+ for (const line of lines) {
22
+ // 处理 metadata 嵌套
23
+ if (currentKey === 'metadata') {
24
+ if (line.match(/^ {2}[a-zA-Z]/)) {
25
+ const colonIndex = line.indexOf(':');
26
+ if (colonIndex > 0) {
27
+ const key = line.substring(2, colonIndex).trim();
28
+ const value = line
29
+ .substring(colonIndex + 1)
30
+ .trim()
31
+ .replace(/^["']|["']$/g, '');
32
+ frontmatter[currentKey][key] = value;
33
+ continue;
34
+ }
35
+ } else if (line.match(/^[a-zA-Z]/)) {
36
+ currentKey = null;
37
+ continue;
38
+ }
39
+ }
40
+
41
+ const colonIndex = line.indexOf(':');
42
+ if (colonIndex === -1) continue;
43
+
44
+ const key = line.substring(0, colonIndex).trim();
45
+ let value = line.substring(colonIndex + 1).trim();
46
+
47
+ // 移除引号
48
+ if (
49
+ (value.startsWith('"') && value.endsWith('"')) ||
50
+ (value.startsWith("'") && value.endsWith("'"))
51
+ ) {
52
+ value = value.slice(1, -1);
53
+ }
54
+
55
+ if (key === 'metadata') {
56
+ currentKey = 'metadata';
57
+ frontmatter.metadata = {};
58
+ } else if (key === 'allowed-tools') {
59
+ frontmatter[key] = value
60
+ .split(',')
61
+ .map((v) => v.trim())
62
+ .filter(Boolean);
63
+ } else if (key === 'skills') {
64
+ frontmatter[key] = value
65
+ .split(',')
66
+ .map((v) => v.trim())
67
+ .filter(Boolean);
68
+ } else if (key === 'tools') {
69
+ frontmatter[key] = value
70
+ .split(',')
71
+ .map((v) => v.trim())
72
+ .filter(Boolean);
73
+ } else {
74
+ frontmatter[key] = value;
75
+ }
76
+ }
77
+
78
+ return frontmatter;
79
+ }
80
+
81
+ /**
82
+ * 移除 frontmatter,只保留正文内容
83
+ */
84
+ function stripFrontmatter(content) {
85
+ return content.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, '');
86
+ }
87
+
88
+ class SubAgentConfig {
89
+ constructor(name, filePath) {
90
+ this.name = name;
91
+ this.filePath = filePath;
92
+ this._frontmatter = null;
93
+ this._content = null;
94
+ this._loaded = false;
95
+ }
96
+
97
+ /**
98
+ * 加载并解析 md 文件
99
+ */
100
+ load() {
101
+ if (this._loaded) return;
102
+
103
+ try {
104
+ const content = fs.readFileSync(this.filePath, 'utf-8');
105
+ this._frontmatter = parseFrontmatter(content);
106
+ this._content = stripFrontmatter(content);
107
+ this._loaded = true;
108
+ } catch (e) {
109
+ console.warn(`[SubAgentConfig] Failed to load ${this.filePath}:`, e.message);
110
+ this._frontmatter = {};
111
+ this._content = '';
112
+ this._loaded = true;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * 获取 frontmatter 中的值
118
+ */
119
+ get(key, defaultValue = null) {
120
+ this.load();
121
+ return this._frontmatter?.[key] ?? defaultValue;
122
+ }
123
+
124
+ /**
125
+ * 获取名称
126
+ */
127
+ getName() {
128
+ return this.get('name', this.name);
129
+ }
130
+
131
+ /**
132
+ * 获取描述
133
+ */
134
+ getDescription() {
135
+ return this.get('description', '');
136
+ }
137
+
138
+ /**
139
+ * 获取技能列表
140
+ */
141
+ getSkills() {
142
+ return this.get('skills', []);
143
+ }
144
+
145
+ /**
146
+ * 获取工具列表
147
+ */
148
+ getTools() {
149
+ return this.get('tools', []);
150
+ }
151
+
152
+ /**
153
+ * 获取模型配置
154
+ */
155
+ getModel() {
156
+ return this.get('model', 'inherit');
157
+ }
158
+
159
+ /**
160
+ * 获取完整内容(用于构建系统提示词)
161
+ */
162
+ getContent() {
163
+ this.load();
164
+ return this._content || '';
165
+ }
166
+
167
+ /**
168
+ * 获取完整的系统提示词(frontmatter + 内容)
169
+ */
170
+ getSystemPrompt() {
171
+ this.load();
172
+ const desc = this.getDescription();
173
+ const content = this._content || '';
174
+
175
+ // 构建系统提示词
176
+ let prompt = `# ${this.getName()}`;
177
+ if (desc) {
178
+ prompt += `\n\n${desc}`;
179
+ }
180
+ if (content.trim()) {
181
+ prompt += `\n\n${content.trim()}`;
182
+ }
183
+ return prompt;
184
+ }
185
+
186
+ /**
187
+ * 检查是否有效
188
+ */
189
+ isValid() {
190
+ this.load();
191
+ return this._loaded && this._frontmatter !== null;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * SubAgent 配置管理器
197
+ * 管理目录下所有子代理配置的加载和缓存
198
+ */
199
+ class SubAgentConfigManager {
200
+ constructor(agentsDir) {
201
+ this.agentsDir = agentsDir;
202
+ this._configs = new Map(); // name -> SubAgentConfig
203
+ }
204
+
205
+ /**
206
+ * 加载目录下所有子代理配置
207
+ */
208
+ loadAll() {
209
+ if (!fs.existsSync(this.agentsDir)) {
210
+ return;
211
+ }
212
+
213
+ const entries = fs.readdirSync(this.agentsDir, { withFileTypes: true });
214
+ for (const entry of entries) {
215
+ if (entry.isFile() && entry.name.endsWith('.md')) {
216
+ const name = entry.name.replace('.md', '');
217
+ const filePath = path.join(this.agentsDir, entry.name);
218
+
219
+ if (!this._configs.has(name)) {
220
+ this._configs.set(name, new SubAgentConfig(name, filePath));
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ /**
227
+ * 刷新配置(清除后重新加载)
228
+ */
229
+ refresh() {
230
+ this._configs.clear();
231
+ this.loadAll();
232
+ }
233
+
234
+ /**
235
+ * 获取某个子代理配置
236
+ */
237
+ get(name) {
238
+ return this._configs.get(name) || null;
239
+ }
240
+
241
+ /**
242
+ * 获取所有配置
243
+ */
244
+ getAll() {
245
+ return Array.from(this._configs.values());
246
+ }
247
+
248
+ /**
249
+ * 获取所有有效配置
250
+ */
251
+ getValidConfigs() {
252
+ return this.getAll().filter((c) => c.isValid());
253
+ }
254
+
255
+ /**
256
+ * 重新加载
257
+ */
258
+ reload() {
259
+ this._configs.clear();
260
+ this.loadAll();
261
+ }
262
+ }
263
+
264
+ module.exports = { SubAgentConfig, SubAgentConfigManager, parseFrontmatter, stripFrontmatter };
@@ -0,0 +1,120 @@
1
+ /**
2
+ * 系统提示词构建器
3
+ * 负责从多个来源组合系统提示词各部分
4
+ * 支持插件注册自己的提示词部分,支持重载后更新
5
+ */
6
+
7
+ class SystemPromptPart {
8
+ constructor(name, priority, provider) {
9
+ this.name = name;
10
+ this.priority = priority;
11
+ this._provider = provider;
12
+ this._dirty = true;
13
+ this._cached = null;
14
+ }
15
+
16
+ get() {
17
+ if (this._dirty || this._cached === null) {
18
+ try {
19
+ this._cached = this._provider();
20
+ this._dirty = false;
21
+ } catch (e) {
22
+ console.warn(`[SystemPromptPart:${this.name}] Provider failed:`, e.message);
23
+ this._cached = null;
24
+ }
25
+ }
26
+ return this._cached;
27
+ }
28
+
29
+ invalidate() {
30
+ this._dirty = true;
31
+ }
32
+ }
33
+
34
+ class SystemPromptBuilder {
35
+ constructor() {
36
+ this._parts = new Map(); // name -> SystemPromptPart
37
+ this._orderedParts = []; // sorted by priority
38
+ }
39
+
40
+ /**
41
+ * 注册一个提示词部分
42
+ * @param {string} name - 部分名称(唯一标识)
43
+ * @param {number} priority - 优先级(数字越小越靠前)
44
+ * @param {Function} provider - 返回提示词内容的函数
45
+ */
46
+ register(name, priority, provider) {
47
+ const part = new SystemPromptPart(name, priority, provider);
48
+ this._parts.set(name, part);
49
+ this._reorder();
50
+ return this;
51
+ }
52
+
53
+ /**
54
+ * 注销一个提示词部分
55
+ */
56
+ unregister(name) {
57
+ this._parts.delete(name);
58
+ this._reorder();
59
+ return this;
60
+ }
61
+
62
+ /**
63
+ * 使某个部分失效(下次 get 时会重新计算)
64
+ */
65
+ invalidate(name) {
66
+ const part = this._parts.get(name);
67
+ if (part) {
68
+ part.invalidate();
69
+ }
70
+ return this;
71
+ }
72
+
73
+ /**
74
+ * 使所有部分失效
75
+ */
76
+ invalidateAll() {
77
+ for (const part of this._parts.values()) {
78
+ part.invalidate();
79
+ }
80
+ return this;
81
+ }
82
+
83
+ /**
84
+ * 获取某个部分的内容
85
+ */
86
+ getPart(name) {
87
+ const part = this._parts.get(name);
88
+ return part ? part.get() : null;
89
+ }
90
+
91
+ /**
92
+ * 构建完整的系统提示词
93
+ * @returns {string}
94
+ */
95
+ build() {
96
+ const parts = [];
97
+ for (const part of this._orderedParts) {
98
+ const content = part.get();
99
+ if (content && content.trim()) {
100
+ parts.push(content.trim());
101
+ }
102
+ }
103
+ return parts.join('\n\n');
104
+ }
105
+
106
+ /**
107
+ * 获取所有部分名称
108
+ */
109
+ getPartNames() {
110
+ return [...this._parts.keys()];
111
+ }
112
+
113
+ _reorder() {
114
+ this._orderedParts = Array.from(this._parts.values()).sort(
115
+ (a, b) => a.priority - b.priority
116
+ );
117
+ }
118
+ }
119
+
120
+ module.exports = { SystemPromptBuilder, SystemPromptPart };