foliko 1.1.93 → 2.0.1

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 (212) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/CLAUDE.md +56 -30
  3. package/REFACTORING_PLAN.md +645 -0
  4. package/docs/architecture.md +131 -0
  5. package/docs/migration.md +57 -0
  6. package/docs/public-api.md +138 -0
  7. package/docs/usage.md +385 -0
  8. package/examples/ambient-example.js +20 -137
  9. package/examples/basic.js +21 -48
  10. package/examples/bootstrap.js +16 -74
  11. package/examples/mcp-example.js +6 -29
  12. package/examples/skill-example.js +6 -19
  13. package/examples/workflow.js +8 -56
  14. package/package.json +8 -4
  15. package/plugins/README.md +49 -0
  16. package/plugins/{ambient-agent → ambient}/EventWatcher.js +1 -1
  17. package/plugins/{ambient-agent → ambient}/ExplorerLoop.js +3 -3
  18. package/plugins/{ambient-agent → ambient}/GoalManager.js +2 -2
  19. package/plugins/ambient/README.md +14 -0
  20. package/plugins/{ambient-agent → ambient}/Reflector.js +1 -1
  21. package/plugins/{ambient-agent → ambient}/StateStore.js +1 -1
  22. package/plugins/{ambient-agent → ambient}/index.js +2 -2
  23. package/plugins/{ai-plugin.js → core/ai/index.js} +14 -30
  24. package/plugins/{audit-plugin.js → core/audit/index.js} +3 -30
  25. package/plugins/{coordinator-plugin.js → core/coordinator/index.js} +3 -35
  26. package/plugins/core/default/bootstrap.js +224 -0
  27. package/plugins/core/default/config.js +222 -0
  28. package/plugins/core/default/index.js +58 -0
  29. package/plugins/core/mcp/index.js +1 -0
  30. package/plugins/{python-plugin-loader.js → core/python-loader/index.js} +7 -187
  31. package/plugins/{rules-plugin.js → core/rules/index.js} +121 -64
  32. package/plugins/{scheduler-plugin.js → core/scheduler/index.js} +12 -114
  33. package/plugins/{session-plugin.js → core/session/index.js} +9 -73
  34. package/{src/capabilities/skill-manager.js → plugins/core/skill-manager/index.js} +64 -18
  35. package/plugins/{storage-plugin.js → core/storage/index.js} +5 -29
  36. package/plugins/{subagent-plugin.js → core/sub-agent/index.js} +10 -171
  37. package/plugins/{think-plugin.js → core/think/index.js} +24 -91
  38. package/{src/capabilities/workflow-engine.js → plugins/core/workflow/index.js} +87 -85
  39. package/plugins/default-plugins.js +6 -720
  40. package/plugins/{data-splitter-plugin.js → executors/data-splitter/index.js} +9 -83
  41. package/plugins/{extension-executor-plugin.js → executors/extension/index.js} +13 -97
  42. package/plugins/{python-executor-plugin.js → executors/python/index.js} +6 -31
  43. package/plugins/{shell-executor-plugin.js → executors/shell/index.js} +2 -5
  44. package/plugins/install/README.md +9 -0
  45. package/plugins/{install-plugin.js → install/index.js} +3 -3
  46. package/plugins/{file-system-plugin.js → io/file-system/index.js} +34 -236
  47. package/plugins/{web-plugin.js → io/web/index.js} +11 -113
  48. package/plugins/memory/README.md +13 -0
  49. package/plugins/{memory-plugin.js → memory/index.js} +4 -18
  50. package/plugins/messaging/email/README.md +19 -0
  51. package/plugins/{email → messaging/email}/index.js +3 -3
  52. package/plugins/{feishu-plugin.js → messaging/feishu/index.js} +4 -4
  53. package/plugins/{qq-plugin.js → messaging/qq/index.js} +6 -17
  54. package/plugins/{telegram-plugin.js → messaging/telegram/index.js} +4 -4
  55. package/plugins/{weixin-plugin.js → messaging/weixin/index.js} +16 -16
  56. package/plugins/{plugin-manager-plugin.js → plugin-manager/index.js} +36 -180
  57. package/plugins/{tools-plugin.js → tools/index.js} +68 -116
  58. package/plugins/trading/README.md +15 -0
  59. package/plugins/{gate-trading.js → trading/index.js} +8 -8
  60. package/{examples → sandbox}/test-concurrent-chat.js +2 -2
  61. package/{examples → sandbox}/test-long-chat.js +2 -2
  62. package/{examples → sandbox}/test-session-chat.js +2 -2
  63. package/{examples → sandbox}/test-web-plugin.js +1 -1
  64. package/{examples → sandbox}/test-weixin-feishu.js +2 -2
  65. package/src/agent/base.js +56 -0
  66. package/src/{core/agent-chat.js → agent/chat.js} +11 -11
  67. package/src/{core/coordinator-manager.js → agent/coordinator.js} +3 -3
  68. package/src/agent/index.js +111 -0
  69. package/src/agent/main.js +337 -0
  70. package/src/agent/prompt.js +78 -0
  71. package/src/agent/sub.js +198 -0
  72. package/src/agent/worker.js +104 -0
  73. package/{cli/bin/foliko.js → src/cli/bin.js} +1 -1
  74. package/{cli/src → src/cli}/commands/chat.js +25 -21
  75. package/{cli/src → src/cli}/index.js +1 -0
  76. package/{cli/src → src/cli}/ui/chat-ui-old.js +40 -178
  77. package/{cli/src → src/cli}/ui/chat-ui.js +3 -3
  78. package/{cli/src → src/cli}/ui/components/footer-bar.js +1 -1
  79. package/src/common/errors.js +402 -0
  80. package/src/{utils → common}/logger.js +33 -0
  81. package/src/{utils/chat-queue.js → common/queue.js} +2 -2
  82. package/src/config/plugin-config.js +50 -0
  83. package/src/context/agent.js +32 -0
  84. package/src/context/compaction-prompts.js +170 -0
  85. package/src/context/compaction-utils.js +191 -0
  86. package/src/context/compressor.js +413 -0
  87. package/src/context/index.js +9 -0
  88. package/src/{core/context-manager.js → context/manager.js} +1 -1
  89. package/src/context/request.js +50 -0
  90. package/src/context/session.js +33 -0
  91. package/src/context/storage.js +30 -0
  92. package/src/executors/mcp-client.js +153 -0
  93. package/src/executors/mcp-desc.js +236 -0
  94. package/src/executors/mcp-executor.js +91 -956
  95. package/src/{core → framework}/command-registry.js +1 -1
  96. package/src/framework/framework.js +300 -0
  97. package/src/framework/index.js +18 -0
  98. package/src/framework/lifecycle.js +203 -0
  99. package/src/framework/loader.js +78 -0
  100. package/src/framework/registry.js +86 -0
  101. package/src/{core/ui-extension-context.js → framework/ui-extension.js} +1 -1
  102. package/src/index.js +130 -15
  103. package/src/llm/index.js +26 -0
  104. package/src/llm/provider.js +212 -0
  105. package/src/llm/registry.js +11 -0
  106. package/src/{core/token-counter.js → llm/tokens.js} +4 -37
  107. package/src/{core/plugin-base.js → plugin/base.js} +10 -136
  108. package/src/plugin/index.js +14 -0
  109. package/src/plugin/loader.js +101 -0
  110. package/src/plugin/manager.js +484 -0
  111. package/src/{core → session}/branch-summary-auto.js +2 -2
  112. package/src/{core/chat-session.js → session/chat.js} +2 -2
  113. package/src/session/index.js +7 -0
  114. package/src/{core/session-manager.js → session/session.js} +2 -2
  115. package/src/session/ttl.js +92 -0
  116. package/src/{core/jsonl-storage.js → storage/jsonl.js} +1 -1
  117. package/src/tool/executor.js +85 -0
  118. package/src/tool/index.js +15 -0
  119. package/src/tool/registry.js +143 -0
  120. package/src/{core/tool-router.js → tool/router.js} +17 -124
  121. package/src/tool/schema.js +108 -0
  122. package/src/utils/data-splitter.js +1 -1
  123. package/src/utils/download.js +1 -1
  124. package/src/utils/index.js +6 -6
  125. package/src/utils/message-validator.js +1 -1
  126. package/tests/core/context-storage.test.js +46 -0
  127. package/tests/core/llm.test.js +54 -0
  128. package/tests/core/plugin.test.js +42 -0
  129. package/tests/core/tool.test.js +60 -0
  130. package/tests/setup.js +10 -0
  131. package/tests/smoke.test.js +58 -0
  132. package/vitest.config.js +9 -0
  133. package/cli/src/daemon.js +0 -149
  134. package/docs/CONTEXT_DESIGN.md +0 -1596
  135. package/docs/ai-sdk-optimization.md +0 -655
  136. package/docs/features.md +0 -120
  137. package/docs/qq-bot.md +0 -976
  138. package/docs/quick-reference.md +0 -160
  139. package/docs/user-manual.md +0 -1391
  140. package/images/geometric_shapes.jpg +0 -0
  141. package/images/sunset_mountain_lake.jpg +0 -0
  142. package/skills/poster-guide/SKILL.md +0 -792
  143. package/src/capabilities/index.js +0 -11
  144. package/src/core/agent.js +0 -808
  145. package/src/core/context-compressor.js +0 -959
  146. package/src/core/enhanced-context-compressor.js +0 -210
  147. package/src/core/framework.js +0 -1422
  148. package/src/core/index.js +0 -30
  149. package/src/core/plugin-manager.js +0 -961
  150. package/src/core/provider-registry.js +0 -159
  151. package/src/core/provider.js +0 -156
  152. package/src/core/request-context.js +0 -98
  153. package/src/core/subagent.js +0 -442
  154. package/src/core/system-prompt-builder.js +0 -120
  155. package/src/core/tool-executor.js +0 -202
  156. package/src/core/tool-registry.js +0 -517
  157. package/src/core/worker-agent.js +0 -192
  158. package/src/executors/executor-base.js +0 -58
  159. package/src/utils/error-boundary.js +0 -363
  160. package/src/utils/error.js +0 -374
  161. package/system.md +0 -1645
  162. package/website_v2/README.md +0 -57
  163. package/website_v2/SPEC.md +0 -1
  164. package/website_v2/docs/api.html +0 -128
  165. package/website_v2/docs/configuration.html +0 -147
  166. package/website_v2/docs/plugin-development.html +0 -129
  167. package/website_v2/docs/project-structure.html +0 -89
  168. package/website_v2/docs/skill-development.html +0 -85
  169. package/website_v2/index.html +0 -489
  170. package/website_v2/scripts/main.js +0 -93
  171. package/website_v2/styles/animations.css +0 -8
  172. package/website_v2/styles/docs.css +0 -83
  173. package/website_v2/styles/main.css +0 -417
  174. package/xhs_auth.json +0 -268
  175. package//346/265/267/346/212/245/346/217/222/344/273/266.md +0 -621
  176. /package/plugins/{ambient-agent → ambient}/constants.js +0 -0
  177. /package/plugins/{email → messaging/email}/constants.js +0 -0
  178. /package/plugins/{email → messaging/email}/handlers.js +0 -0
  179. /package/plugins/{email → messaging/email}/monitor.js +0 -0
  180. /package/plugins/{email → messaging/email}/parser.js +0 -0
  181. /package/plugins/{email → messaging/email}/reply.js +0 -0
  182. /package/plugins/{email → messaging/email}/utils.js +0 -0
  183. /package/{examples → sandbox}/test-chat.js +0 -0
  184. /package/{examples → sandbox}/test-mcp.js +0 -0
  185. /package/{examples → sandbox}/test-reload.js +0 -0
  186. /package/{examples → sandbox}/test-telegram.js +0 -0
  187. /package/{examples → sandbox}/test-tg-bot.js +0 -0
  188. /package/{examples → sandbox}/test-tg-simple.js +0 -0
  189. /package/{examples → sandbox}/test-tg.js +0 -0
  190. /package/{examples → sandbox}/test-think.js +0 -0
  191. /package/src/{core/sub-agent-config.js → agent/sub-config.js} +0 -0
  192. /package/{cli/src → src/cli}/commands/daemon.js +0 -0
  193. /package/{cli/src → src/cli}/commands/list.js +0 -0
  194. /package/{cli/src → src/cli}/commands/plugin.js +0 -0
  195. /package/{cli/src → src/cli}/ui/components/agent-mention-provider.js +0 -0
  196. /package/{cli/src → src/cli}/ui/components/chained-autocomplete-provider.js +0 -0
  197. /package/{cli/src → src/cli}/ui/components/message-bubble.js +0 -0
  198. /package/{cli/src → src/cli}/ui/components/status-bar.js +0 -0
  199. /package/{cli/src → src/cli}/utils/ansi.js +0 -0
  200. /package/{cli/src → src/cli}/utils/config.js +0 -0
  201. /package/{cli/src → src/cli}/utils/markdown.js +0 -0
  202. /package/{cli/src → src/cli}/utils/plugin-config.js +0 -0
  203. /package/{cli/src → src/cli}/utils/render-diff.js +0 -0
  204. /package/src/{utils/circuit-breaker.js → common/circuit.js} +0 -0
  205. /package/src/{core → common}/constants.js +0 -0
  206. /package/src/{utils/edit-diff.js → common/diff.js} +0 -0
  207. /package/src/{utils/event-emitter.js → common/events.js} +0 -0
  208. /package/src/{utils → common}/id.js +0 -0
  209. /package/src/{utils → common}/retry.js +0 -0
  210. /package/src/{core/notification-manager.js → notification/manager.js} +0 -0
  211. /package/src/{core/session-entry.js → session/entry.js} +0 -0
  212. /package/src/{core/storage-manager.js → storage/manager.js} +0 -0
@@ -0,0 +1,131 @@
1
+ # Architecture
2
+
3
+ Foliko — 简约的插件化 Agent 框架。
4
+
5
+ ## 整体架构
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────┐
9
+ │ Foliko Framework │
10
+ ├─────────────────────────────────────────────────────────────┤
11
+ │ Framework (Container Layer) │
12
+ │ ├── pluginManager — 插件注册/加载/卸载/热重载 │
13
+ │ ├── toolRegistry — 工具注册/执行/Zod 校验 │
14
+ │ ├── eventEmitter — 内建事件总线 │
15
+ │ └── contextManager — 三层上下文管理 │
16
+ ├─────────────────────────────────────────────────────────────┤
17
+ │ Agent (Dialogue Layer) │
18
+ │ ├── MainAgent — 主对话代理 │
19
+ │ ├── SubAgent — 子代理(隔离执行) │
20
+ │ ├── WorkerAgent — 工作代理(协处理器管理) │
21
+ │ ├── AgentChatHandler — LLM 通信 + 工具调用循环 │
22
+ │ └── SystemPromptBuilder— 动态系统提示词构建 │
23
+ ├─────────────────────────────────────────────────────────────┤
24
+ │ LLM Layer │
25
+ │ ├── LLMProvider — AI 供应商封装 │
26
+ │ ├── ProviderRegistry — 供应商配置中心 │
27
+ │ └── Vercel AI SDK — 底层流式/工具调用 │
28
+ ├─────────────────────────────────────────────────────────────┤
29
+ │ Plugin System │
30
+ │ ├── core/ (ai, storage, skill-manager, etc.) │
31
+ │ ├── executors/ (shell, python, extension) │
32
+ │ ├── messaging/ (email, telegram, weixin, etc.) │
33
+ │ ├── io/ (file-system) │
34
+ │ └── memory, trading, ambient, install ... │
35
+ └─────────────────────────────────────────────────────────────┘
36
+ ```
37
+
38
+ ## 三层上下文
39
+
40
+ ```
41
+ ┌─────────────────────────────────────────────────┐
42
+ │ Request Context │
43
+ │ requestId, traceId, timeout, startTime │
44
+ │ 通过 runWithRequestContext() 设置 │
45
+ └─────────────────────────────────────────────────┘
46
+
47
+
48
+ ┌─────────────────────────────────────────────────┐
49
+ │ Session Context │
50
+ │ sessionId, variables, messageStore │
51
+ │ 通过 runInSession() 设置 │
52
+ │ Per-Session 消息隔离 │
53
+ └─────────────────────────────────────────────────┘
54
+
55
+
56
+ ┌─────────────────────────────────────────────────┐
57
+ │ Agent Context │
58
+ │ agentId, tools, skills, systemPrompt │
59
+ │ 由 MainAgent/SubAgent 实例持有 │
60
+ └─────────────────────────────────────────────────┘
61
+ ```
62
+
63
+ 实现: `src/context/manager.js` + AsyncLocalStorage (`src/framework/framework.js`)
64
+
65
+ ## 数据流
66
+
67
+ ```
68
+ User Input
69
+
70
+
71
+ MainAgent.chat() / chatStream()
72
+
73
+
74
+ AgentChatHandler ──► LLMProvider.createModel() ──► AI API
75
+ │ │
76
+ ▼ ▼
77
+ Tool Call Loop ◄────────────────────────────── Tool Call Response
78
+
79
+
80
+ ToolRegistry.execute(name, args)
81
+
82
+
83
+ Plugin Tool Handlers / SubAgent / Workflow
84
+
85
+
86
+ Result returned to LLM → Next iteration or final response
87
+ ```
88
+
89
+ ## 插件生命周期
90
+
91
+ ```
92
+ Plugin
93
+ │ constructor(config)
94
+
95
+
96
+ install(framework) — 注册工具、事件监听
97
+
98
+
99
+ start(framework) — 启动长连接/定时任务
100
+
101
+
102
+ reload(framework) — 热重载 (可选)
103
+
104
+
105
+ uninstall(framework) — 清理资源
106
+ ```
107
+
108
+ ## 模块大小目标
109
+
110
+ - 单文件 ≤ 400 行
111
+ - 类 ≤ 8 个 public 方法
112
+ - 插件目录独立 maintain
113
+
114
+ ## 核心文件一览
115
+
116
+ | 文件 | 职责 |
117
+ |------|------|
118
+ | `src/framework/framework.js` | 容器,管理所有子系统 |
119
+ | `src/framework/lifecycle.js` | bootstrap/ready/destroy |
120
+ | `src/agent/main.js` | 主对话代理 |
121
+ | `src/agent/sub.js` | 子代理隔离执行 |
122
+ | `src/agent/chat.js` | LLM 通信 + 工具循环 |
123
+ | `src/agent/prompt.js` | 系统提示词构建 |
124
+ | `src/llm/provider.js` | AI 供应商抽象 |
125
+ | `src/plugin/manager.js` | 插件生命周期管理 |
126
+ | `src/plugin/base.js` | Plugin 基类 |
127
+ | `src/tool/registry.js` | 工具注册与执行 |
128
+ | `src/tool/executor.js` | 工具执行路由 |
129
+ | `src/tool/schema.js` | JSON Schema → Zod 转换 |
130
+ | `src/context/manager.js` | 三层上下文管理 |
131
+ | `src/session/session.js` | Per-Session 存储 |
@@ -0,0 +1,57 @@
1
+ # Migration Guide
2
+
3
+ 旧路径 → 新路径迁移对照表。
4
+
5
+ ## 核心模块迁移
6
+
7
+ | 旧路径 | 新路径 | 说明 |
8
+ |--------|--------|------|
9
+ | `src/core/agent.js` | `src/agent/main.js` | Agent 类 → MainAgent |
10
+ | `src/core/chat.js` | `src/agent/chat.js` | 聊天处理器 |
11
+ | `src/core/prompt.js` | `src/agent/prompt.js` | 系统提示构建 |
12
+ | `src/core/coordinator.js` | `src/agent/coordinator.js` | 协调器 |
13
+ | `src/core/tool.js` | `src/tool/*` | 拆分为 registry/executor/schema |
14
+ | `src/core/llm.js` | `src/llm/provider.js` | LLM provider 层 |
15
+ | `src/core/plugin.js` | `src/plugin/base.js` | Plugin 基类 |
16
+ | `src/core/errors.js` | `src/common/errors.js` | 错误类型 |
17
+ | `src/core/events.js` | `src/common/events.js` | 事件总线 |
18
+ | `src/core/manager.js` | `src/plugin/manager.js` | PluginManager |
19
+ | `src/core/framework.js` | `src/framework/framework.js` | Framework 核心 |
20
+ | `src/core/lifecycle.js` | `src/framework/lifecycle.js` | 生命周期管理 |
21
+ | `src/core/session.js` | `src/session/session.js` | 会话管理 |
22
+
23
+ ## 插件目录迁移
24
+
25
+ | 旧路径 | 新路径 | 说明 |
26
+ |--------|--------|------|
27
+ | `plugins/email/` | `plugins/messaging/email/` | 邮件插件 |
28
+ | `plugins/ambient-agent/` | `plugins/ambient/` | 自主 Agent |
29
+ | `plugins/default-plugins.js` | `plugins/core/default/` | 拆分为 index.js + config.js + bootstrap.js |
30
+ | `plugins/executors/*` | `plugins/executors/` | 执行器插件保持位置 |
31
+ | `plugins/io/*` | `plugins/io/` | IO 插件保持位置 |
32
+
33
+ ## 符号迁移
34
+
35
+ | 旧符号 | 新符号 | 位置 |
36
+ |--------|--------|------|
37
+ | `Agent` | `MainAgent` | `src/agent/main.js` |
38
+ | `createAI()` | `new LLMProvider(config)` | `src/llm/provider.js` |
39
+ | `isThinkingModel()` | 同名 | `src/llm/provider.js` |
40
+ | `_jsonSchemaToZod()` | `jsonSchemaToZod()` | `src/tool/schema.js` |
41
+ | `bootstrapDefaults()` | 同名 | `plugins/core/default/bootstrap.js` |
42
+ | `loadAgentConfig()` | 同名 | `plugins/core/default/config.js` |
43
+
44
+ ## PluginManager 新增方法
45
+
46
+ | 方法 | 说明 |
47
+ |------|------|
48
+ | `isEnabled(name)` | 检查插件是否启用 |
49
+ | `startAll()` | 启动所有已加载插件 |
50
+ | `setBootstrapping(bool)` | 设置引导状态 |
51
+
52
+ ## Framework 新增方法
53
+
54
+ | 方法 | 说明 |
55
+ |------|------|
56
+ | `_setReady()` | 标记框架就绪并触发 `framework:ready` 事件 |
57
+ | `isEnabled(name)` | 代理到 `pluginManager.isEnabled()` |
@@ -0,0 +1,138 @@
1
+ # Public API Reference
2
+
3
+ Foliko 对外公共 API 速查。
4
+
5
+ ## 入门三件套
6
+
7
+ ```js
8
+ const foliko = require('foliko');
9
+
10
+ // 1) Bootstrap — 加载配置并启动框架
11
+ const framework = await foliko.bootstrap({
12
+ _config: { ai: { provider: 'deepseek', model: 'deepseek-chat' } }
13
+ });
14
+
15
+ // 2) createApp — 构造未启动的 Framework,支持链式 .use()
16
+ const app = foliko.createApp();
17
+ await app.use(foliko.withAI({ provider: 'openai', model: 'gpt-4' }));
18
+ await app.use(foliko.withShell());
19
+ await bootstrap(app, {});
20
+
21
+ // 3) createAgent — 显式创建 Agent
22
+ const agent = foliko.createAgent(framework, {
23
+ name: 'MyAgent',
24
+ systemPrompt: 'You are a helpful assistant.',
25
+ });
26
+ ```
27
+
28
+ ## 框架生命周期
29
+
30
+ ```js
31
+ const fw = await foliko.bootstrap(config);
32
+ await foliko.ready(fw); // 等待框架就绪
33
+ await foliko.destroy(fw); // 销毁框架
34
+ ```
35
+
36
+ ## 上下文管理
37
+
38
+ ```js
39
+ // Session 上下文
40
+ await foliko.runInSession(framework, sessionId, options, async () => {
41
+ // 在此作用域内可通过 framework.getCurrentSessionContext() 获取 Session
42
+ });
43
+
44
+ // Request 上下文
45
+ await foliko.runInRequest(framework, { requestId, traceId }, async () => {
46
+ // 在此作用域内可通过 framework.getRequestContext() 获取 Request
47
+ });
48
+ ```
49
+
50
+ ## 工具注册
51
+
52
+ ```js
53
+ const toolDef = {
54
+ name: 'my_tool',
55
+ description: 'Does something',
56
+ inputSchema: z.object({ msg: z.string() }),
57
+ execute: async (args) => { return { result: args.msg }; },
58
+ };
59
+
60
+ foliko.registerTool(framework, toolDef);
61
+ ```
62
+
63
+ ## 快捷插件工厂
64
+
65
+ ```js
66
+ const aiPlugin = foliko.withAI({ provider: 'deepseek', model: 'deepseek-chat' });
67
+ const shellPlugin = foliko.withShell({ allowedCommands: ['ls', 'cat'] });
68
+ const pythonPlugin = foliko.withPython({ timeout: 30000 });
69
+ ```
70
+
71
+ ## 框架实例方法
72
+
73
+ ```js
74
+ // 插件管理
75
+ framework.pluginManager.has(name);
76
+ framework.pluginManager.get(name);
77
+ framework.pluginManager.getAll();
78
+ framework.pluginManager.isEnabled(name);
79
+ framework.pluginManager.getNames();
80
+
81
+ // Agent 管理
82
+ framework.getMainAgent();
83
+ framework.getAgents();
84
+ framework.createAgent(config);
85
+ framework.createSubAgent(config);
86
+ framework.createSessionAgent(sessionId, config);
87
+
88
+ // Session 管理
89
+ framework.getOrCreateSessionContext(sessionId, options);
90
+ framework.getCurrentSessionContext();
91
+ framework.getCurrentSessionId();
92
+ framework.listSessionContexts();
93
+ framework.destroySessionContext(sessionId);
94
+
95
+ // 工具
96
+ framework.registerTool(toolDef);
97
+ framework.getTools();
98
+ framework.executeTool(name, args);
99
+
100
+ // 事件
101
+ framework.on('email:received', handler);
102
+ framework.on('framework:ready', handler);
103
+ framework.on('tool:call', handler);
104
+ framework.on('session:context-created', handler);
105
+ ```
106
+
107
+ ## 导出类型
108
+
109
+ ```js
110
+ const {
111
+ Framework, MainAgent, SubAgent, WorkerAgent,
112
+ Plugin, PluginManager,
113
+ ToolRegistry, ToolExecutor,
114
+ EventEmitter, Logger,
115
+ LLM, z,
116
+ SkillManagerPlugin, Skill, SkillMetadata,
117
+ WorkflowPlugin, WorkflowEngine, StepExecutor,
118
+ MCPExecutorPlugin,
119
+ Agent, // == MainAgent (backward compat)
120
+ } = require('foliko');
121
+ ```
122
+
123
+ ## 全部导出速查
124
+
125
+ | Export | 来源 | 说明 |
126
+ |--------|------|------|
127
+ | `bootstrap` | lifecycle | 加载配置启动框架 |
128
+ | `createApp` | facade | 构造未启动 Framework |
129
+ | `createAgent` | agent/index | 创建 MainAgent |
130
+ | `runInSession` | framework | Session 上下文运行 |
131
+ | `runInRequest` | framework | Request 上下文运行 |
132
+ | `registerTool` | facade | 快速注册工具 |
133
+ | `use` | facade | 加载插件到实例 |
134
+ | `ready` | lifecycle | 等待就绪 |
135
+ | `destroy` | lifecycle | 销毁框架 |
136
+ | `withAI` | facade | 创建 AI 插件 |
137
+ | `withShell` | facade | 创建 Shell 插件 |
138
+ | `withPython` | facade | 创建 Python 插件 |
package/docs/usage.md ADDED
@@ -0,0 +1,385 @@
1
+ # Foliko 使用指南
2
+
3
+ ## 目录结构
4
+
5
+ ```
6
+ <project-root>/
7
+ ├── .foliko/ # 项目级配置目录
8
+ │ ├── config # 基础配置 (key: value 格式)
9
+ │ ├── ai.json # AI 模型配置
10
+ │ ├── plugins.json # 插件配置 (messaging 等)
11
+ │ ├── weixin.json # 微信配置
12
+ │ ├── mcp_config.json # MCP 服务器配置
13
+ │ ├── agents/ # SubAgent 定义
14
+ │ ├── skills/ # 项目级技能 (子目录或 .md 文件)
15
+ │ ├── workflows/ # 工作流 (.md 作为 skill, .json/.js 作为 workflow)
16
+ │ ├── rules/ # 权限规则 (.json 或 .md)
17
+ │ └── sessions/ # 会话数据
18
+
19
+ ├── skills/ # 项目根目录技能
20
+ ├── plugins/ # 项目级插件
21
+
22
+ ├── ~/.foliko/ # 用户主目录全局配置
23
+ │ ├── config # 全局配置 (项目级未设置时生效)
24
+ │ ├── skills/ # 全局技能 (优先级最高)
25
+ │ ├── workflows/ # 全局工作流
26
+ │ └── rules/ # 全局规则
27
+
28
+ └── src/ # 框架核心
29
+ ```
30
+
31
+ ## 配置
32
+
33
+ ### `.foliko/config`
34
+
35
+ 基础配置文件,`key: value` 格式,支持 `#` 注释:
36
+
37
+ ```ini
38
+ # AI 配置
39
+ api_key: sk-your-key
40
+ model: deepseek-chat
41
+ provider: deepseek
42
+ baseURL: https://api.deepseek.com
43
+
44
+ # 目录路径配置 (覆盖默认值)
45
+ skills_dirs: ~/.foliko/skills,.foliko/skills,skills
46
+ workflows_dir: ~/.foliko/workflows
47
+ rules_dir: ~/.foliko/rules
48
+ agents_dir: ~/.foliko/agents
49
+ ```
50
+
51
+ - `skills_dirs`: 逗号分隔的目录列表,顺序决定优先级(先匹配的优先)
52
+ - `workflows_dir`: 工作流目录
53
+ - `rules_dir`: 规则目录
54
+ - `agents_dir`: SubAgent 定义目录
55
+
56
+ 不设置则使用默认路径(参见下方"目录优先级")。
57
+
58
+ ### `.foliko/ai.json`
59
+
60
+ AI 模型配置,支持所有 provider 参数:
61
+
62
+ ```json
63
+ {
64
+ "provider": "deepseek",
65
+ "model": "deepseek-chat",
66
+ "apiKey": "sk-xxx",
67
+ "baseURL": "https://api.deepseek.com"
68
+ }
69
+ ```
70
+
71
+ 支持 provider: `deepseek`, `openai`, `anthropic`, `minimax`, `openai-compatible`
72
+
73
+ ### `.foliko/plugins.json`
74
+
75
+ 插件配置:
76
+
77
+ ```json
78
+ {
79
+ "telegram": { "botToken": "xxx" },
80
+ "weixin": { "appId": "xxx", "appSecret": "xxx" },
81
+ "email": { "host": "smtp.xxx.com", "port": 587 },
82
+ "pluginLinks": {
83
+ "my-plugin": "/path/to/my-plugin/index.js"
84
+ }
85
+ }
86
+ ```
87
+
88
+ `pluginLinks` 用于注册自定义插件路径。
89
+
90
+ ### `.foliko/mcp_config.json`
91
+
92
+ MCP 服务器配置:
93
+
94
+ ```json
95
+ {
96
+ "mcpServers": {
97
+ "my-server": {
98
+ "command": "npx",
99
+ "args": ["-y", "@modelcontextprotocol/server-filesystem"],
100
+ "env": { "KEY": "value" },
101
+ "enabled": true
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ## 目录优先级
108
+
109
+ ### Skills
110
+
111
+ 扫描顺序(先加载的优先,同名 skill 不会被后加载的覆盖):
112
+
113
+ 1. `~/.foliko/skills/` — 用户全局
114
+ 2. `~/.foliko/workflows/` — 用户全局工作流(作为 skill)
115
+ 3. `.foliko/skills/` — 项目级
116
+ 4. `.foliko/workflows/` — 项目级工作流(作为 skill)
117
+ 5. `skills/` — 项目根目录
118
+ 6. `plugins/core/skills/` — 内置(不存在则跳过)
119
+
120
+ 可在 `.foliko/config` 中通过 `skills_dirs` 完全替换默认列表。
121
+
122
+ ### Workflows (结构化)
123
+
124
+ 默认扫描(用户优先):
125
+
126
+ 1. `~/.foliko/workflows/` — 用户全局
127
+ 2. `.foliko/workflows/` — 项目级
128
+
129
+ 只加载 `.json` 和 `.js` 文件(需包含 `steps` 数组)。
130
+ 可在 `.foliko/config` 通过 `workflows_dir` 修改项目级目录。
131
+
132
+ ### Rules
133
+
134
+ 默认扫描(用户优先):
135
+
136
+ 1. `~/.foliko/rules/` — 用户全局
137
+ 2. `.foliko/rules/` — 项目级
138
+
139
+ 支持 `.json` 和 `.md`(YAML frontmatter)格式。
140
+ 可在 `.foliko/config` 通过 `rules_dir` 修改项目级目录。
141
+
142
+ ## Skills
143
+
144
+ ### 格式
145
+
146
+ Skill 是一个 markdown 文件,包含 YAML frontmatter:
147
+
148
+ ```markdown
149
+ ---
150
+ name: my-skill
151
+ description: 技能描述
152
+ ---
153
+
154
+ # 技能标题
155
+
156
+ 这里写技能的具体使用指导。
157
+ ```
158
+
159
+ ### 加载方式
160
+
161
+ ```
162
+ skills/ → 子目录内有 SKILL.md → 加载为 skill
163
+ .foliko/skills/ → 同上
164
+ .foliko/workflows/ → 独立 .md 文件 → 加载为 skill(文件名即为 skill 名)
165
+ ```
166
+
167
+ ### 命令注册
168
+
169
+ 如果 skill 目录下有 `index.js`,导出命令数组即可注册为可调用的 slash 命令:
170
+
171
+ ```js
172
+ module.exports = [
173
+ {
174
+ name: 'greet',
175
+ description: '打招呼',
176
+ options: [
177
+ { flags: '-n, --name <value>', description: '姓名' }
178
+ ],
179
+ execute: async (parsedArgs, ctx) => {
180
+ return `Hello, ${parsedArgs.name || 'World'}!`
181
+ }
182
+ }
183
+ ]
184
+ ```
185
+
186
+ 命令通过 `ext_call({ plugin: "skill", tool: "skill-name:command-name", args: { command: "..." } })` 调用。
187
+
188
+ ### 相关工具
189
+
190
+ - `loadSkill({ skill: "name" })` — 获取技能内容
191
+ - `reloadSkills` — 重载所有技能
192
+ - `loadReference({ skill, reference })` — 加载技能的参考文档
193
+ - `listScripts` / `loadScript` — 技能脚本管理
194
+
195
+ ## Workflows
196
+
197
+ ### 结构化工作流
198
+
199
+ `.foliko/workflows/` 下的 `.json` 或 `.js` 文件,定义带步骤的工作流:
200
+
201
+ ```json
202
+ {
203
+ "name": "my-workflow",
204
+ "description": "工作流描述",
205
+ "steps": [
206
+ { "type": "tool", "tool": "tool_name", "args": { ... } },
207
+ { "type": "script", "script": "return input.value" },
208
+ { "type": "condition", "branches": [...] }
209
+ ]
210
+ }
211
+ ```
212
+
213
+ 支持的步骤类型:`tool`, `script`, `condition`, `switch`, `try`, `parallel`, `sequential`, `loop`, `delay`, `workflow`
214
+
215
+ ### 相关工具
216
+
217
+ - `execute_workflow({ workflow, input })` — 执行工作流
218
+ - `listWorkflows` — 列出所有已加载工作流
219
+ - `reloadWorkflows` — 重载工作流
220
+
221
+ ## Rules
222
+
223
+ ### JSON 格式
224
+
225
+ ```json
226
+ [
227
+ {
228
+ "name": "block-dangerous-tools",
229
+ "type": "deny",
230
+ "target": "shell_exec",
231
+ "pattern": "rm\\s+-rf",
232
+ "enabled": true
233
+ }
234
+ ]
235
+ ```
236
+
237
+ ### Markdown 格式
238
+
239
+ ```markdown
240
+ ---
241
+ name: block-dangerous
242
+ type: deny
243
+ target: shell_exec
244
+ condition: rm\s+-rf
245
+ description: 阻止危险命令
246
+ enabled: true
247
+ ---
248
+ ```
249
+
250
+ 规则类型:
251
+ - `allow` — 允许特定调用
252
+ - `deny` — 拒绝特定调用
253
+ - `transform` — 转换调用参数
254
+
255
+ ### 相关工具
256
+
257
+ - `rules_list` — 列出所有规则
258
+ - `rules_add` — 添加规则
259
+ - `rules_remove` — 移除规则
260
+ - `rules_stats` — 规则统计
261
+ - `rules_test` — 测试规则匹配
262
+
263
+ ## 动态切换工作目录
264
+
265
+ 在运行时切换到其他项目目录,所有插件自动重载:
266
+
267
+ ```js
268
+ const { setCwd } = require('./src/framework')
269
+ await setCwd(framework, '/new/project/path')
270
+ ```
271
+
272
+ 切换后自动:
273
+ 1. 更新 `framework._cwd`(通过 `framework.getCwd()` 获取)
274
+ 2. 销毁当前 session 上下文
275
+ 3. 调每个插件的 `onCwdChanged()` 做预清理
276
+ 4. 调每个插件的 `reload()` 从新目录重新扫描
277
+ - skill-manager: 从新 CWD 的 skillsDirs 重新加载技能
278
+ - workflow: 从新 CWD 重新加载工作流
279
+ - rules: 从新 CWD 重新加载规则
280
+ - extension-executor: 重新扫描所有插件的工具注册
281
+ 5. 发射 `cwd:changed` 事件
282
+
283
+ ### 在 agent 中使用
284
+
285
+ ```js
286
+ // 注册为 agent 可调用的工具
287
+ framework.registerTool({
288
+ name: 'set_working_directory',
289
+ description: '切换工作目录',
290
+ inputSchema: z.object({
291
+ path: z.string().describe('新工作目录路径')
292
+ }),
293
+ execute: async (args) => {
294
+ await setCwd(framework, args.path)
295
+ return { success: true, data: `Switched to ${args.path}` }
296
+ }
297
+ })
298
+ ```
299
+
300
+ ## 常用事件
301
+
302
+ | 事件 | 触发时机 | 参数 |
303
+ |---|---|---|
304
+ | `framework:ready` | 框架启动完成 | `framework` |
305
+ | `framework:destroyed` | 框架销毁 | — |
306
+ | `cwd:changed` | 工作目录切换 | `{ oldCwd, newCwd, framework }` |
307
+ | `skill:reloaded` | 技能重载 | `{ skills: string[] }` |
308
+ | `session:context-created` | 新会话创建 | `{ sessionId, manager }` |
309
+ | `rescan:complete` | 项目重新扫描完成 | `{ unloaded, loaded, keepLoaded }` |
310
+ | `plugin:loaded` | 插件加载 | plugin 实例 |
311
+ | `plugin:reloaded` | 插件重载 | plugin 实例 |
312
+ | `tool:call` / `tool-call` | 工具调用 | `{ name, args, source }` |
313
+ | `tool:result` | 工具返回结果 | `{ name, result }` |
314
+ | `tool:error` | 工具出错 | `{ name, args, error, source }` |
315
+
316
+ ## 插件开发
317
+
318
+ ### 基础结构
319
+
320
+ ```js
321
+ const { Plugin } = require('./src/plugin/base')
322
+
323
+ class MyPlugin extends Plugin {
324
+ constructor(config = {}) {
325
+ super()
326
+ this.name = 'my-plugin'
327
+ this.version = '1.0.0'
328
+ this.description = 'My custom plugin'
329
+ this.priority = 50
330
+ this.system = false
331
+ }
332
+
333
+ install(framework) {
334
+ // 注册工具、监听事件
335
+ framework.registerTool({
336
+ name: 'my_tool',
337
+ description: 'My tool',
338
+ inputSchema: z.object({ ... }),
339
+ execute: async (args) => { ... }
340
+ })
341
+ framework.on('some:event', handler)
342
+ return this
343
+ }
344
+
345
+ start(framework) {
346
+ // 初始化逻辑,start() 可能会被调用多次
347
+ return this
348
+ }
349
+
350
+ reload(framework) {
351
+ // 热重载
352
+ }
353
+
354
+ async onCwdChanged(oldCwd, newCwd, framework) {
355
+ // 工作目录切换前的预清理
356
+ // 之后会自动调 reload()
357
+ }
358
+
359
+ uninstall(framework) {
360
+ // 清理
361
+ }
362
+ }
363
+
364
+ module.exports = MyPlugin
365
+ ```
366
+
367
+ ### 生命周期
368
+
369
+ ```
370
+ install() → load() → [start() + 注册工具]
371
+
372
+ startAll() → [start() 再次调用]
373
+
374
+ reload() → 热重载
375
+
376
+ uninstall() → 卸载清理
377
+ ```
378
+
379
+ **注意**:`start()` 会被调用两次(`load()` 和 `startAll()`),插件需通过 `_loaded` 标志或幂等设计来防止重复初始化。
380
+
381
+ ### 放置位置
382
+
383
+ - 项目级:`plugins/<name>/index.js`
384
+ - 全局:`~/.foliko/plugins/<name>.js` 或 `~/.foliko/plugins/<name>/index.js`
385
+ - 通过 `pluginLinks` 指定任意路径