foliko 1.1.68 → 1.1.69

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 (142) hide show
  1. package/.claude/settings.local.json +19 -10
  2. package/.dockerignore +45 -45
  3. package/.env.example +56 -56
  4. package/CLAUDE.md +2 -2
  5. package/README.md +13 -13
  6. package/SPEC.md +3 -3
  7. package/cli/src/commands/chat.js +2 -20
  8. package/cli/src/commands/list.js +7 -6
  9. package/cli/src/commands/plugin.js +3 -2
  10. package/cli/src/daemon.js +2 -2
  11. package/cli/src/ui/chat-ui-old.js +15 -4
  12. package/cli/src/ui/chat-ui.js +152 -38
  13. package/cli/src/ui/footer-bar.js +13 -14
  14. package/cli/src/utils/config.js +29 -0
  15. package/cli/src/utils/plugin-config.js +1 -1
  16. package/docker-compose.yml +33 -33
  17. package/docs/features.md +120 -120
  18. package/docs/quick-reference.md +160 -160
  19. package/docs/user-manual.md +1391 -1391
  20. package/examples/ambient-example.js +2 -2
  21. package/examples/bootstrap.js +3 -3
  22. package/examples/test-chat.js +1 -1
  23. package/examples/test-reload.js +1 -1
  24. package/examples/test-telegram.js +1 -1
  25. package/examples/test-tg-bot.js +1 -1
  26. package/examples/test-tg-simple.js +2 -2
  27. package/examples/test-tg.js +1 -1
  28. package/examples/test-think.js +1 -1
  29. package/examples/test-weixin-feishu.js +3 -3
  30. package/package.json +3 -1
  31. package/plugins/ambient-agent/index.js +1 -1
  32. package/plugins/audit-plugin.js +75 -24
  33. package/plugins/default-plugins.js +21 -11
  34. package/plugins/email/index.js +1 -1
  35. package/plugins/extension-executor-plugin.js +85 -7
  36. package/plugins/feishu-plugin.js +118 -16
  37. package/plugins/install-plugin.js +4 -4
  38. package/plugins/memory-plugin.js +1 -1
  39. package/plugins/plugin-manager-plugin.js +3 -3
  40. package/plugins/python-executor-plugin.js +1 -1
  41. package/plugins/python-plugin-loader.js +1 -1
  42. package/plugins/qq-plugin.js +143 -16
  43. package/plugins/rules-plugin.js +1 -1
  44. package/plugins/scheduler-plugin.js +2 -2
  45. package/plugins/session-plugin.js +309 -393
  46. package/plugins/storage-plugin.js +235 -176
  47. package/plugins/subagent-plugin.js +4 -4
  48. package/plugins/telegram-plugin.js +116 -17
  49. package/plugins/think-plugin.js +1 -1
  50. package/plugins/web-plugin.js +2 -2
  51. package/plugins/weixin-plugin.js +102 -19
  52. package/skills/find-skills/AGENTS.md +2 -2
  53. package/skills/find-skills/SKILL.md +133 -133
  54. package/skills/foliko-dev/AGENTS.md +236 -236
  55. package/skills/foliko-dev/SKILL.md +19 -19
  56. package/skills/mcp-usage/SKILL.md +200 -200
  57. package/skills/plugin-guide/SKILL.md +4 -4
  58. package/skills/python-plugin-dev/SKILL.md +5 -5
  59. package/skills/skill-guide/SKILL.md +104 -6
  60. package/skills/subagent-guide/SKILL.md +237 -237
  61. package/skills/workflow-guide/SKILL.md +646 -646
  62. package/src/capabilities/skill-manager.js +101 -2
  63. package/src/capabilities/workflow-engine.js +1 -1
  64. package/src/core/agent-chat.js +17 -14
  65. package/src/core/branch-summary-auto.js +206 -0
  66. package/src/core/chat-session.js +38 -8
  67. package/src/core/command-registry.js +200 -0
  68. package/src/core/constants.js +11 -11
  69. package/src/core/context-compressor.js +700 -149
  70. package/src/core/context-manager.js +0 -1
  71. package/src/core/enhanced-context-compressor.js +210 -0
  72. package/src/core/framework.js +140 -83
  73. package/src/core/jsonl-storage.js +253 -0
  74. package/src/core/plugin-manager.js +15 -10
  75. package/src/core/provider-registry.js +159 -0
  76. package/src/core/provider.js +2 -0
  77. package/src/core/session-entry.js +225 -0
  78. package/src/core/session-manager.js +701 -0
  79. package/src/core/storage-manager.js +494 -0
  80. package/src/core/sub-agent-config.js +1 -1
  81. package/src/core/token-counter.js +177 -58
  82. package/src/core/ui-extension-context.js +174 -0
  83. package/src/executors/mcp-executor.js +15 -6
  84. package/src/utils/logger.js +152 -180
  85. package/src/utils/plugin-helpers.js +2 -2
  86. package/website_v2/docs/api.html +1 -1
  87. package/website_v2/docs/configuration.html +2 -2
  88. package/website_v2/docs/plugin-development.html +4 -4
  89. package/website_v2/docs/project-structure.html +2 -2
  90. package/website_v2/docs/skill-development.html +2 -2
  91. package/website_v2/index.html +1 -1
  92. package/website_v2/styles/animations.css +7 -7
  93. package/.agent/agents/backend-dev.md +0 -102
  94. package/.agent/agents/data-analyst.md +0 -117
  95. package/.agent/agents/devops.md +0 -115
  96. package/.agent/agents/frontend-dev.md +0 -94
  97. package/.agent/agents/network-requester.md +0 -44
  98. package/.agent/agents/poster-designer.md +0 -52
  99. package/.agent/agents/product-manager.md +0 -85
  100. package/.agent/agents/qa-engineer.md +0 -100
  101. package/.agent/agents/security-engineer.md +0 -99
  102. package/.agent/agents/team-lead.md +0 -137
  103. package/.agent/agents/ui-designer.md +0 -116
  104. package/.agent/data/default.json +0 -58
  105. package/.agent/data/email/processed-emails.json +0 -1
  106. package/.agent/data/plugins-state.json +0 -207
  107. package/.agent/data/scheduler/tasks.json +0 -1
  108. package/.agent/data/web/web-config.json +0 -5
  109. package/.agent/data/weixin/images/file_1776188148383jpg +0 -0
  110. package/.agent/data/weixin/images/file_1776188458326.jpg +0 -0
  111. package/.agent/data/weixin/images/file_1776188689423.jpg +0 -0
  112. package/.agent/data/weixin/images/file_1776188813604.jpg +0 -0
  113. package/.agent/data/weixin/images/file_1776189097450.jpg +0 -0
  114. package/.agent/data/weixin/videos/file_1776188318431.mp4 +0 -0
  115. package/.agent/data/weixin.json +0 -6
  116. package/.agent/mcp_config.json +0 -14
  117. package/.agent/memory/user/mof6gk94-kneeuh.md +0 -9
  118. package/.agent/package.json +0 -8
  119. package/.agent/plugins/marknative/README.md +0 -134
  120. package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
  121. package/.agent/plugins/marknative/fonts.zip +0 -0
  122. package/.agent/plugins/marknative/index.js +0 -256
  123. package/.agent/plugins/marknative/package.json +0 -12
  124. package/.agent/plugins/test-plugin.py +0 -99
  125. package/.agent/plugins.json +0 -14
  126. package/.agent/python-scripts/test_sample.py +0 -24
  127. package/.agent/sessions/cli_default.json +0 -4121
  128. package/.agent/skills/agent-browser/SKILL.md +0 -311
  129. package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
  130. package/.agent/skills/sysinfo/SKILL.md +0 -38
  131. package/.agent/skills/sysinfo/system-info.sh +0 -130
  132. package/.agent/skills/workflow/SKILL.md +0 -324
  133. package/.agent/test-agent.js +0 -35
  134. package/.agent/weixin.json +0 -6
  135. package/.agent/workflows/email-digest.json +0 -50
  136. package/.agent/workflows/file-backup.json +0 -21
  137. package/.agent/workflows/get-ip-notify.json +0 -32
  138. package/.agent/workflows/news-aggregator.json +0 -93
  139. package/.agent/workflows/news-dashboard-v2.json +0 -94
  140. package/.agent/workflows/notification-batch.json +0 -32
  141. package/src/core/session-context.js +0 -346
  142. package/src/core/session-storage.js +0 -295
@@ -1,48 +1,88 @@
1
1
  /**
2
- * Storage 存储插件
3
- * 提供数据持久化存储,支持 JSON 文件存储
2
+ * Storage Plugin - JSONL-based key-value storage
3
+ * Supports delayed compaction to reduce file size
4
4
  */
5
5
 
6
- const { Plugin } = require('../src/core/plugin-base')
7
- const { logger } = require('../src/utils/logger')
8
- const log = logger.child('Storage')
9
- const { z } = require('zod')
10
- const fs = require('fs')
11
- const path = require('path')
6
+ const { Plugin } = require('../src/core/plugin-base');
7
+ const { logger } = require('../src/utils/logger');
8
+ const log = logger.child('Storage');
9
+ const { z } = require('zod');
10
+ const path = require('path');
11
+ const { StorageManager } = require('../src/core/storage-manager');
12
12
 
13
13
  class StoragePlugin extends Plugin {
14
14
  constructor(config = {}) {
15
- super()
16
- this.name = 'storage'
17
- this.version = '1.0.0'
18
- this.description = '数据持久化存储插件,支持键值对存储'
19
- this.priority = 3
15
+ super();
16
+ this.name = 'storage';
17
+ this.version = '2.1.0';
18
+ this.description = '数据持久化存储插件,支持键值对存储(JSONL格式)+ 自动 compaction';
19
+ this.priority = 3;
20
20
 
21
- this.system = true
21
+ this.system = true;
22
22
 
23
23
  this.config = {
24
- type: config.type || 'json', // json 或 memory
25
- path: config.path || '.agent/data',
26
- namespace: config.namespace || 'default'
27
- }
28
-
29
- this._framework = null
30
- this._store = new Map()
31
- this._filePath = null
24
+ path: config.path || '.foliko/data',
25
+ namespace: config.namespace || 'default',
26
+ // Compaction 配置
27
+ compactionThreshold: config.compactionThreshold || 1000,
28
+ compactionIntervalMs: config.compactionIntervalMs || 5000,
29
+ autoCompact: config.autoCompact !== false,
30
+ };
31
+
32
+ this._framework = null;
33
+ this._storageManager = null;
32
34
  }
33
35
 
34
36
  install(framework) {
35
- this._framework = framework
36
- return this
37
+ this._framework = framework;
38
+ return this;
39
+ }
40
+
41
+ /**
42
+ * Initialize storage manager with compaction settings
43
+ */
44
+ _initStorage() {
45
+ if (this._storageManager) return;
46
+
47
+ const baseDir = path.resolve(process.cwd(), this.config.path);
48
+ const filePath = path.join(baseDir, `${this.config.namespace}.jsonl`);
49
+
50
+ // 传递 compaction 配置
51
+ this._storageManager = new StorageManager(filePath, true, {
52
+ compactionThreshold: this.config.compactionThreshold,
53
+ compactionIntervalMs: this.config.compactionIntervalMs,
54
+ autoCompact: this.config.autoCompact,
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Get storage store (for internal use)
60
+ */
61
+ getStore() {
62
+ this._initStorage();
63
+ return this._storageManager;
64
+ }
65
+
66
+ /**
67
+ * Set value directly (for internal use by other plugins)
68
+ */
69
+ setDirect(key, value) {
70
+ this._initStorage();
71
+ return this._storageManager.set(key, value);
72
+ }
73
+
74
+ /**
75
+ * Delete key directly (for internal use by other plugins)
76
+ */
77
+ deleteDirect(key) {
78
+ this._initStorage();
79
+ return this._storageManager.delete(key);
37
80
  }
38
81
 
39
82
  start(framework) {
40
- // 初始化存储
41
- if (this.config.type === 'json') {
42
- this._initJsonStore()
43
- }
83
+ this._initStorage();
44
84
 
45
- // 注册存储工具
85
+ // Register storage tools
46
86
  framework.registerTool({
47
87
  name: 'storage_set',
48
88
  description: '存储数据到键值存储',
@@ -53,23 +93,21 @@ class StoragePlugin extends Plugin {
53
93
  }),
54
94
  execute: async (args) => {
55
95
  try {
56
- const ns = args.namespace || this.config.namespace
57
- const fullKey = `${ns}:${args.key}`
58
- this._store.set(fullKey, {
59
- value: args.value,
60
- updatedAt: new Date()
61
- })
62
-
63
- if (this.config.type === 'json') {
64
- await this._persistToFile()
65
- }
66
-
67
- return { success: true, data: { key: args.key, namespace: ns } }
96
+ this._initStorage();
97
+ const ns = args.namespace ? `${args.namespace}:` : '';
98
+ const fullKey = `${ns}${args.key}`;
99
+ const entry = this._storageManager.set(fullKey, args.value);
100
+
101
+ return {
102
+ success: true,
103
+ data: { key: args.key, namespace: args.namespace || this.config.namespace }
104
+ };
68
105
  } catch (err) {
69
- return { success: false, error: err.message }
106
+ log.error('storage_set error:', err.message);
107
+ return { success: false, error: err.message };
70
108
  }
71
109
  }
72
- })
110
+ });
73
111
 
74
112
  framework.registerTool({
75
113
  name: 'storage_get',
@@ -79,46 +117,52 @@ class StoragePlugin extends Plugin {
79
117
  namespace: z.string().optional().describe('命名空间')
80
118
  }),
81
119
  execute: async (args) => {
82
- const ns = args.namespace || this.config.namespace
83
- const fullKey = `${ns}:${args.key}`
84
- const entry = this._store.get(fullKey)
85
-
86
- if (!entry) {
87
- return { success: false, error: 'Key not found', key: args.key }
88
- }
120
+ try {
121
+ this._initStorage();
122
+ const ns = args.namespace ? `${args.namespace}:` : '';
123
+ const fullKey = `${ns}${args.key}`;
124
+ const value = this._storageManager.get(fullKey);
89
125
 
90
- return {
91
- success: true,
92
- data: {
93
- key: args.key,
94
- namespace: ns,
95
- value: entry.value,
96
- updatedAt: entry.updatedAt
126
+ if (value === null) {
127
+ return { success: false, error: 'Key not found', key: args.key };
97
128
  }
129
+
130
+ return {
131
+ success: true,
132
+ data: {
133
+ key: args.key,
134
+ namespace: args.namespace || this.config.namespace,
135
+ value
136
+ }
137
+ };
138
+ } catch (err) {
139
+ log.error('storage_get error:', err.message);
140
+ return { success: false, error: err.message };
98
141
  }
99
142
  }
100
- })
143
+ });
101
144
 
102
145
  framework.registerTool({
103
146
  name: 'storage_delete',
104
- description: '删除存储的数据',
147
+ description: '删除存储的数据(软删除,物理删除由 compaction 自动处理)',
105
148
  inputSchema: z.object({
106
149
  key: z.string().describe('存储键名'),
107
150
  namespace: z.string().optional().describe('命名空间')
108
151
  }),
109
152
  execute: async (args) => {
110
- const ns = args.namespace || this.config.namespace
111
- const fullKey = `${ns}:${args.key}`
112
- const existed = this._store.has(fullKey)
113
- this._store.delete(fullKey)
153
+ try {
154
+ this._initStorage();
155
+ const ns = args.namespace ? `${args.namespace}:` : '';
156
+ const fullKey = `${ns}${args.key}`;
157
+ const deleted = this._storageManager.delete(fullKey);
114
158
 
115
- if (this.config.type === 'json') {
116
- await this._persistToFile()
159
+ return { success: true, data: { deleted, key: args.key } };
160
+ } catch (err) {
161
+ log.error('storage_delete error:', err.message);
162
+ return { success: false, error: err.message };
117
163
  }
118
-
119
- return { success: true, data: { deleted: existed, key: args.key } }
120
164
  }
121
- })
165
+ });
122
166
 
123
167
  framework.registerTool({
124
168
  name: 'storage_list',
@@ -127,139 +171,154 @@ class StoragePlugin extends Plugin {
127
171
  namespace: z.string().optional().describe('命名空间,默认全局')
128
172
  }),
129
173
  execute: async (args) => {
130
- const ns = args.namespace || this.config.namespace
131
- const prefix = `${ns}:`
132
- const keys = []
133
-
134
- for (const key of this._store.keys()) {
135
- if (key.startsWith(prefix)) {
136
- keys.push(key.substring(prefix.length))
137
- }
138
- }
139
-
140
- return {
141
- success: true,
142
- data: keys,
143
- metadata: { namespace: ns, count: keys.length }
174
+ try {
175
+ this._initStorage();
176
+ const ns = args.namespace ? `${args.namespace}:` : '';
177
+ const keys = this._storageManager.list(ns);
178
+
179
+ return {
180
+ success: true,
181
+ data: keys.map(k => k.substring(ns.length)),
182
+ metadata: {
183
+ namespace: args.namespace || this.config.namespace,
184
+ count: keys.length
185
+ }
186
+ };
187
+ } catch (err) {
188
+ log.error('storage_list error:', err.message);
189
+ return { success: false, error: err.message };
144
190
  }
145
191
  }
146
- })
192
+ });
147
193
 
148
194
  framework.registerTool({
149
195
  name: 'storage_clear',
150
- description: '清空命名空间下的所有数据',
196
+ description: '清空命名空间下的所有数据(立即物理删除)',
151
197
  inputSchema: z.object({
152
198
  namespace: z.string().optional().describe('命名空间,默认全局')
153
199
  }),
154
200
  execute: async (args) => {
155
- const ns = args.namespace || this.config.namespace
156
- const prefix = `${ns}:`
157
- let count = 0
158
-
159
- for (const key of this._store.keys()) {
160
- if (key.startsWith(prefix)) {
161
- this._store.delete(key)
162
- count++
201
+ try {
202
+ this._initStorage();
203
+ const ns = args.namespace ? `${args.namespace}:` : '';
204
+ const keys = this._storageManager.list(ns);
205
+ let count = 0;
206
+
207
+ for (const key of keys) {
208
+ if (this._storageManager.delete(key)) {
209
+ count++;
210
+ }
163
211
  }
164
- }
165
212
 
166
- if (this.config.type === 'json') {
167
- await this._persistToFile()
213
+ return { success: true, data: { namespace: args.namespace || this.config.namespace, cleared: count } };
214
+ } catch (err) {
215
+ log.error('storage_clear error:', err.message);
216
+ return { success: false, error: err.message };
168
217
  }
169
-
170
- return { success: true, data: { namespace: ns, cleared: count } }
171
218
  }
172
- })
173
-
174
- return this
175
- }
176
-
177
- /**
178
- * 初始化 JSON 文件存储
179
- */
180
- _initJsonStore() {
181
- this._filePath = path.resolve(process.cwd(), this.config.path, `${this.config.namespace}.json`)
182
-
183
- // 确保目录存在
184
- const dir = path.dirname(this._filePath)
185
- if (!fs.existsSync(dir)) {
186
- fs.mkdirSync(dir, { recursive: true })
187
- }
188
-
189
- // 加载已有数据
190
- if (fs.existsSync(this._filePath)) {
191
- try {
192
- const content = fs.readFileSync(this._filePath, 'utf-8')
193
- const data = JSON.parse(content)
219
+ });
194
220
 
195
- for (const [key, entry] of Object.entries(data)) {
196
- this._store.set(key, entry)
221
+ framework.registerTool({
222
+ name: 'storage_watch',
223
+ description: '监听键值变化(返回当前值)',
224
+ inputSchema: z.object({
225
+ key: z.string().describe('存储键名'),
226
+ namespace: z.string().optional().describe('命名空间')
227
+ }),
228
+ execute: async (args) => {
229
+ try {
230
+ this._initStorage();
231
+ const ns = args.namespace ? `${args.namespace}:` : '';
232
+ const fullKey = `${ns}${args.key}`;
233
+ const value = this._storageManager.watch(fullKey);
234
+
235
+ return {
236
+ success: true,
237
+ data: { key: args.key, value },
238
+ metadata: { watched: true }
239
+ };
240
+ } catch (err) {
241
+ log.error('storage_watch error:', err.message);
242
+ return { success: false, error: err.message };
197
243
  }
198
-
199
- log.info(` Loaded ${this._store.size} entries from ${this._filePath}`)
200
- } catch (err) {
201
- log.warn(` Failed to load storage file: ${err.message}`)
202
244
  }
203
- }
204
- }
245
+ });
205
246
 
206
- /**
207
- * 持久化到文件
208
- */
209
- async _persistToFile() {
210
- if (!this._filePath) return
211
-
212
- try {
213
- const data = Object.fromEntries(this._store)
214
- fs.writeFileSync(this._filePath, JSON.stringify(data, null, 2), 'utf-8')
215
- } catch (err) {
216
- log.error(` Failed to persist: ${err.message}`)
217
- }
218
- }
219
-
220
- /**
221
- * 获取存储实例(供其他插件使用)
222
- */
223
- getStore() {
224
- return this._store
225
- }
247
+ /**
248
+ * 新增: 手动触发 compaction
249
+ * 当 tombstone 数量达到阈值时,compaction 会自动在后台执行
250
+ * 此工具可手动触发 compaction 立即清理
251
+ */
252
+ framework.registerTool({
253
+ name: 'storage_compact',
254
+ description: '手动触发 compaction,清理已删除的墓碑记录并重写文件',
255
+ inputSchema: z.object({
256
+ namespace: z.string().optional().describe('命名空间,默认全局')
257
+ }),
258
+ execute: async (args) => {
259
+ try {
260
+ this._initStorage();
261
+
262
+ const result = await this._storageManager.compact();
263
+
264
+ return {
265
+ success: true,
266
+ data: {
267
+ namespace: args.namespace || this.config.namespace,
268
+ compacted: result.compacted,
269
+ status: result.status
270
+ }
271
+ };
272
+ } catch (err) {
273
+ log.error('storage_compact error:', err.message);
274
+ return { success: false, error: err.message };
275
+ }
276
+ }
277
+ });
226
278
 
227
- /**
228
- * 直接设置值并自动持久化(供其他插件使用)
229
- * @param {string} key - 键
230
- * @param {any} value - 值
231
- */
232
- setDirect(key, value) {
233
- this._store.set(key, value)
234
- if (this.config.type === 'json') {
235
- this._persistToFile()
236
- }
237
- }
279
+ /**
280
+ * 新增: 获取存储统计信息
281
+ */
282
+ framework.registerTool({
283
+ name: 'storage_stats',
284
+ description: '获取存储统计信息,包括条目数、墓碑数量、compaction 配置等',
285
+ inputSchema: z.object({
286
+ namespace: z.string().optional().describe('命名空间,默认全局')
287
+ }),
288
+ execute: async (args) => {
289
+ try {
290
+ this._initStorage();
291
+ const stats = this._storageManager.getCompactionStats();
292
+
293
+ return {
294
+ success: true,
295
+ data: {
296
+ namespace: args.namespace || this.config.namespace,
297
+ ...stats
298
+ }
299
+ };
300
+ } catch (err) {
301
+ log.error('storage_stats error:', err.message);
302
+ return { success: false, error: err.message };
303
+ }
304
+ }
305
+ });
238
306
 
239
- /**
240
- * 删除键并自动持久化(供其他插件使用)
241
- * @param {string} key - 键
242
- */
243
- deleteDirect(key) {
244
- this._store.delete(key)
245
- if (this.config.type === 'json') {
246
- this._persistToFile()
247
- }
307
+ return this;
248
308
  }
249
309
 
250
310
  reload(framework) {
251
- this._framework = framework
252
- this._store.clear()
253
-
254
- if (this.config.type === 'json') {
255
- this._initJsonStore()
256
- }
311
+ this._framework = framework;
312
+ this._initStorage();
257
313
  }
258
314
 
259
315
  uninstall(framework) {
260
- this._store.clear()
261
- this._framework = null
316
+ if (this._storageManager) {
317
+ this._storageManager.clear();
318
+ this._storageManager = null;
319
+ }
320
+ this._framework = null;
262
321
  }
263
322
  }
264
323
 
265
- module.exports = StoragePlugin
324
+ module.exports = { StoragePlugin };
@@ -499,7 +499,7 @@ class SubAgentManagerPlugin extends Plugin {
499
499
 
500
500
  agent.registerTool({
501
501
  name: 'subagent_reload',
502
- description: '重新加载子Agent配置(当新增或删除.agent/agents下的文件后使用)',
502
+ description: '重新加载子Agent配置(当新增或删除.foliko/agents下的文件后使用)',
503
503
  inputSchema: z.object({}),
504
504
  execute: async () => {
505
505
  try {
@@ -567,7 +567,7 @@ class SubAgentManagerPlugin extends Plugin {
567
567
 
568
568
  framework.registerTool({
569
569
  name: 'subagent_reload',
570
- description: '重新加载子Agent配置(当新增或删除.agent/agents下的文件后使用)',
570
+ description: '重新加载子Agent配置(当新增或删除.foliko/agents下的文件后使用)',
571
571
  inputSchema: z.object({}),
572
572
  execute: async () => {
573
573
  try {
@@ -586,8 +586,8 @@ class SubAgentManagerPlugin extends Plugin {
586
586
  * 从 agentsDir 目录加载子Agent配置
587
587
  */
588
588
  _loadAgentsFromDir() {
589
- // 默认使用 .agent/agents 目录
590
- const agentsDir = this.config.agentsDir || path.join(process.cwd(), '.agent', 'agents')
589
+ // 默认使用 .foliko/agents 目录
590
+ const agentsDir = this.config.agentsDir || path.join(process.cwd(), '.foliko', 'agents')
591
591
  //log.info(' _loadAgentsFromDir called, agentsDir:', agentsDir)
592
592
  if (!fs.existsSync(agentsDir)) {
593
593
  log.info(' agentsDir not found or does not exist')