foliko 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  28. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
  29. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
  30. package/.agent/ARCHITECTURE.md +288 -0
  31. package/.agent/agents/ambient-agent.md +57 -0
  32. package/.agent/agents/debugger.md +55 -0
  33. package/.agent/agents/email-assistant.md +49 -0
  34. package/.agent/agents/file-manager.md +42 -0
  35. package/.agent/agents/python-developer.md +60 -0
  36. package/.agent/agents/scheduler.md +59 -0
  37. package/.agent/agents/web-developer.md +45 -0
  38. package/.agent/data/default.json +412 -3
  39. package/.agent/data/plugins-state.json +177 -174
  40. package/.agent/data/puppeteer-sessions/undefined.json +6 -0
  41. package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
  42. package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
  43. package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
  44. package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
  45. package/.agent/mcp_config.json +11 -3
  46. package/.agent/memory/feedback/mnrdvj5i-ca3dkd.md +9 -0
  47. package/.agent/memory/feedback/mnre365e-7s4zax.md +9 -0
  48. package/.agent/memory/feedback/mnre36jn-nkfgmp.md +9 -0
  49. package/.agent/memory/feedback/mnre3805-kjiq6h.md +9 -0
  50. package/.agent/memory/feedback/mnsf66kp-b10rcd.md +9 -0
  51. package/.agent/memory/feedback/mnsi3sz8-p5g2cw.md +9 -0
  52. package/.agent/memory/feedback/mnsibe47-sv2ni1.md +9 -0
  53. package/.agent/memory/feedback/mnsic89w-nn228o.md +9 -0
  54. package/.agent/memory/feedback/mnsj1xe9-x83ba0.md +9 -0
  55. package/.agent/memory/feedback/mnsj21iv-wnwelx.md +9 -0
  56. package/.agent/memory/feedback/mnsj2g4a-cog7a2.md +9 -0
  57. package/.agent/memory/feedback/mnsj4js7-lktjp6.md +9 -0
  58. package/.agent/memory/feedback/mnsj5d4y-uglwvp.md +9 -0
  59. package/.agent/memory/feedback/mnslkuo9-uous66.md +24 -0
  60. package/.agent/memory/feedback/mnsm3vq0-megoil.md +9 -0
  61. package/.agent/memory/feedback/mnsnn5x2-sxcihd.md +9 -0
  62. package/.agent/memory/feedback/mnsnq17s-nabrn9.md +9 -0
  63. package/.agent/memory/feedback/mnsnybet-wz7rn3.md +9 -0
  64. package/.agent/memory/feedback/mnsrw0s7-7s9e30.md +9 -0
  65. package/.agent/memory/feedback/mnu5hpnd-tlm16q.md +9 -0
  66. package/.agent/memory/feedback/mnu60uqe-xuoxp4.md +9 -0
  67. package/.agent/memory/project/mnqx54u5-loqtoe.md +9 -0
  68. package/.agent/memory/project/mnqx84cv-mx6dmd.md +9 -0
  69. package/.agent/memory/project/mnsacuyr-hgtk5n.md +20 -0
  70. package/.agent/memory/project/mnu5hy2x-bjsg7u.md +9 -0
  71. package/.agent/memory/reference/mnre3cww-penbo1.md +9 -0
  72. package/.agent/memory/reference/mns9wn48-luerua.md +14 -0
  73. package/.agent/memory/reference/mns9yz5c-thc2s0.md +16 -0
  74. package/.agent/memory/reference/mnsfy4um-910f1o.md +23 -0
  75. package/.agent/memory/reference/mnsg37dp-lmfj18.md +32 -0
  76. package/.agent/memory/reference/mnsll60q-0j911u.md +36 -0
  77. package/.agent/memory/reference/mnsmlb5y-nej31u.md +16 -0
  78. package/.agent/memory/reference/mnssle72-yrot96.md +9 -0
  79. package/.agent/memory/user/mnsfuon6-l416q1.md +21 -0
  80. package/.agent/memory/user/mnsg9kut-95m7rf.md +20 -0
  81. package/.agent/memory/user/mnu2eo1v-yy6fhe.md +9 -0
  82. package/.agent/memory/user/mnu2etuo-8u8jk8.md +9 -0
  83. package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
  84. package/.agent/plugins/poster-plugin/fonts/Symbola_hint.ttf +0 -0
  85. package/.agent/plugins/poster-plugin/package.json +3 -3
  86. package/.agent/plugins/poster-plugin/src/canvas.js +8 -0
  87. package/.agent/plugins/poster-plugin/src/components/barcode.js +5 -2
  88. package/.agent/plugins/poster-plugin/src/components/bubble.js +3 -2
  89. package/.agent/plugins/poster-plugin/src/components/button.js +74 -30
  90. package/.agent/plugins/poster-plugin/src/components/columns.js +97 -83
  91. package/.agent/plugins/poster-plugin/src/components/grid.js +104 -92
  92. package/.agent/plugins/poster-plugin/src/components/highlightText.js +2 -1
  93. package/.agent/plugins/poster-plugin/src/components/imageFrame.js +143 -93
  94. package/.agent/plugins/poster-plugin/src/components/quote.js +85 -13
  95. package/.agent/plugins/poster-plugin/src/components/ribbon.js +13 -9
  96. package/.agent/plugins/poster-plugin/src/components/seal.js +5 -3
  97. package/.agent/plugins/poster-plugin/src/components/star.js +3 -3
  98. package/.agent/plugins/poster-plugin/src/components/table.js +1 -1
  99. package/.agent/plugins/poster-plugin/src/components/watermark.js +4 -2
  100. package/.agent/plugins/poster-plugin/src/composer.js +181 -13
  101. package/.agent/plugins/poster-plugin/src/elements/artText.js +16 -7
  102. package/.agent/plugins/poster-plugin/src/elements/background.js +20 -5
  103. package/.agent/plugins/poster-plugin/src/elements/richText.js +160 -107
  104. package/.agent/plugins/poster-plugin/src/elements/text.js +48 -45
  105. package/.agent/plugins/poster-plugin/src/fonts.js +556 -125
  106. package/.agent/plugins/poster-plugin/src/index.js +46 -1
  107. package/.agent/plugins/poster-plugin/yarn.lock +186 -356
  108. package/.agent/plugins/puppeteer-plugin/README.md +147 -0
  109. package/.agent/plugins/puppeteer-plugin/index.js +1422 -0
  110. package/.agent/plugins/puppeteer-plugin/package.json +9 -0
  111. package/.agent/plugins.json +5 -11
  112. package/.agent/rules/GEMINI.md +273 -0
  113. package/.agent/rules/allow-rule.md +77 -0
  114. package/.agent/rules/log-rule.md +83 -0
  115. package/.agent/rules/security-rule.md +93 -0
  116. package/.agent/scripts/auto_preview.py +148 -0
  117. package/.agent/scripts/checklist.py +217 -0
  118. package/.agent/scripts/session_manager.py +120 -0
  119. package/.agent/scripts/verify_all.py +327 -0
  120. package/.agent/sessions/cli_default.json +128 -5479
  121. package/.agent/skills/api-patterns/SKILL.md +81 -0
  122. package/.agent/skills/api-patterns/api-style.md +42 -0
  123. package/.agent/skills/api-patterns/auth.md +24 -0
  124. package/.agent/skills/api-patterns/documentation.md +26 -0
  125. package/.agent/skills/api-patterns/graphql.md +41 -0
  126. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  127. package/.agent/skills/api-patterns/response.md +37 -0
  128. package/.agent/skills/api-patterns/rest.md +40 -0
  129. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  130. package/.agent/skills/api-patterns/security-testing.md +122 -0
  131. package/.agent/skills/api-patterns/trpc.md +41 -0
  132. package/.agent/skills/api-patterns/versioning.md +22 -0
  133. package/.agent/skills/app-builder/SKILL.md +75 -0
  134. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  135. package/.agent/skills/app-builder/feature-building.md +53 -0
  136. package/.agent/skills/app-builder/project-detection.md +34 -0
  137. package/.agent/skills/app-builder/scaffolding.md +118 -0
  138. package/.agent/skills/app-builder/tech-stack.md +40 -0
  139. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  140. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  141. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  142. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  143. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  144. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  145. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  146. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  147. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  148. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  149. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  150. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  151. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  152. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  153. package/.agent/skills/architecture/SKILL.md +55 -0
  154. package/.agent/skills/architecture/context-discovery.md +43 -0
  155. package/.agent/skills/architecture/examples.md +94 -0
  156. package/.agent/skills/architecture/pattern-selection.md +68 -0
  157. package/.agent/skills/architecture/patterns-reference.md +50 -0
  158. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  159. package/.agent/skills/clean-code/SKILL.md +201 -0
  160. package/.agent/skills/doc.md +177 -0
  161. package/.agent/skills/frontend-design/SKILL.md +418 -0
  162. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  163. package/.agent/skills/frontend-design/color-system.md +311 -0
  164. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  165. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  166. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  167. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  168. package/.agent/skills/frontend-design/typography-system.md +345 -0
  169. package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
  170. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  171. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  172. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  173. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  174. package/.agent/skills/poster-design/SKILL.md +385 -0
  175. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  176. package/.agent/workflows/brainstorm.md +113 -0
  177. package/.agent/workflows/create.md +59 -0
  178. package/.agent/workflows/debug.md +103 -0
  179. package/.agent/workflows/deploy.md +176 -0
  180. package/.agent/workflows/enhance.md +63 -0
  181. package/.agent/workflows/orchestrate.md +237 -0
  182. package/.agent/workflows/plan.md +89 -0
  183. package/.agent/workflows/preview.md +81 -0
  184. package/.agent/workflows/simple-test.md +42 -0
  185. package/.agent/workflows/status.md +86 -0
  186. package/.agent/workflows/structured-orchestrate.md +180 -0
  187. package/.agent/workflows/test.md +144 -0
  188. package/.agent/workflows/ui-ux-pro-max.md +296 -0
  189. package/.env.example +56 -56
  190. package/README.md +441 -441
  191. package/SPEC.md +735 -696
  192. package/output/foliko-poster.png +0 -0
  193. package/outputs/emoji-font-showcase.png +0 -0
  194. package/outputs/foliko-muji-style.png +0 -0
  195. package/package.json +3 -2
  196. package/plugins/ambient-agent/EventWatcher.js +33 -37
  197. package/plugins/ambient-agent/ExplorerLoop.js +338 -36
  198. package/plugins/ambient-agent/GoalManager.js +7 -3
  199. package/plugins/ambient-agent/StateStore.js +30 -1
  200. package/plugins/ambient-agent/constants.js +15 -1
  201. package/plugins/ambient-agent/index.js +26 -33
  202. package/plugins/coordinator-plugin.js +3 -3
  203. package/plugins/default-plugins.js +4 -3
  204. package/plugins/email/index.js +150 -36
  205. package/plugins/email/monitor.js +79 -5
  206. package/plugins/email/reply.js +15 -25
  207. package/plugins/extension-executor-plugin.js +184 -32
  208. package/plugins/feishu-plugin.js +2 -2
  209. package/plugins/file-system-plugin.js +57 -24
  210. package/plugins/memory-plugin.js +176 -64
  211. package/plugins/python-plugin-loader.js +79 -9
  212. package/plugins/scheduler-plugin.js +64 -24
  213. package/plugins/telegram-plugin.js +2 -2
  214. package/plugins/think-plugin.js +7 -2
  215. package/plugins/web-plugin.js +263 -4
  216. package/plugins/weixin-plugin.js +2 -2
  217. package/skills/ambient-agent/SKILL.md +342 -314
  218. package/skills/find-skills/AGENTS.md +162 -162
  219. package/skills/find-skills/SKILL.md +133 -133
  220. package/src/core/agent-chat.js +64 -9
  221. package/src/core/agent.js +216 -69
  222. package/src/core/tool-registry.js +5 -5
  223. package/src/executors/mcp-executor.js +453 -35
  224. package/src/utils/id.js +5 -0
  225. package/system.md +3629 -0
  226. package/.agent/agents/code-assistant.json +0 -17
  227. package/.agent/agents/email-assistant.json +0 -14
  228. package/.agent/agents/file-assistant.json +0 -18
  229. package/.agent/agents/orchestrator-demo.md +0 -53
  230. package/.agent/agents/orchestrator.json +0 -7
  231. package/.agent/agents/system-assistant.json +0 -15
  232. package/.agent/agents/web-assistant.json +0 -12
  233. package/.agent/data/ambient/goals.json +0 -50
  234. package/.agent/data/ambient/memories.json +0 -7
  235. package/.agent/data/scheduler/tasks.json +0 -1
  236. package/.agent/memory/core.md +0 -1
  237. package/.agent/memory/feedback/mnrsiuoc-e1ru74.md +0 -9
  238. package/.agent/memory/feedback/mnrt2mmz-98az6n.md +0 -9
  239. package/.agent/memory/feedback/mnrtqrhm-kxsicz.md +0 -9
  240. package/.agent/memory/feedback/mnrts8vg-i0ngzp.md +0 -15
  241. package/.agent/memory/feedback/mnrtt7jt-c0trb2.md +0 -9
  242. package/.agent/memory/feedback/mnruc2f0-5s52la.md +0 -16
  243. package/.agent/memory/feedback/mnrumbmx-63sa0v.md +0 -9
  244. package/.agent/memory/project/mnn93ogy-ypjn27.md +0 -9
  245. package/.agent/memory/project/mnn98fqy-5nhc1u.md +0 -25
  246. package/.agent/memory/project/mnrp7p5n-8enm2a.md +0 -31
  247. package/.agent/memory/project/mnrp9ifb-yynks0.md +0 -40
  248. package/.agent/memory/project/mnrpb3b8-f617s4.md +0 -25
  249. package/.agent/memory/project/mnrrmqgg-focprv.md +0 -9
  250. package/.agent/memory/project/mnrtykbh-6atsor.md +0 -9
  251. package/.agent/memory/project/mnru9jiu-kgau16.md +0 -35
  252. package/.agent/memory/reference/mnq3oenw-46haj6.md +0 -63
  253. package/.agent/memory/reference/mnq5qxm2-mjoooh.md +0 -116
  254. package/.agent/memory/reference/mnrnvpwo-rcqv9m.md +0 -52
  255. package/.agent/memory/reference/mnrovxvz-zy9xqm.md +0 -25
  256. package/.agent/memory/reference/mnroxabj-1b3930.md +0 -68
  257. package/.agent/memory/reference/mnrpjtlp-mnb9od.md +0 -35
  258. package/.agent/memory/reference/mnrps1x3-6b8xfm.md +0 -28
  259. package/.agent/memory/reference/mnrpt9ov-15er5w.md +0 -22
  260. package/.agent/memory/reference/mnrq82dn-y9tv9e.md +0 -50
  261. package/.agent/memory/reference/mnrqnr5v-v75drf.md +0 -34
  262. package/.agent/memory/reference/mnrrfzys-urudaf.md +0 -31
  263. package/.agent/memory/reference/mnrrocha-t0027n.md +0 -21
  264. package/.agent/memory/reference/mnrukklc-bxndsb.md +0 -35
  265. package/.agent/memory/user/mnm67t9m-x8rekk.md +0 -9
  266. package/.agent/memory/user/mnn5mmqh-w6aktx.md +0 -11
  267. package/.agent/memory/user/mnnbfhhn-dk1bd1.md +0 -22
  268. package/.agent/memory/user/mnrt39t8-8eosy0.md +0 -9
  269. package/.agent/package.json +0 -8
  270. package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
  271. package/.agent/plugins/daytona/README.md +0 -89
  272. package/.agent/plugins/daytona/index.js +0 -377
  273. package/.agent/plugins/daytona/package.json +0 -12
  274. package/.agent/plugins/marknative/README.md +0 -134
  275. package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
  276. package/.agent/plugins/marknative/fonts.zip +0 -0
  277. package/.agent/plugins/marknative/index.js +0 -256
  278. package/.agent/plugins/marknative/package.json +0 -12
  279. package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
  280. package/.agent/plugins/poster-plugin/test-background.svg +0 -1
  281. package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
  282. package/.agent/plugins/poster-plugin/test-image.png +0 -0
  283. package/.agent/plugins/system-info/index.js +0 -387
  284. package/.agent/plugins/system-info/package.json +0 -4
  285. package/.agent/plugins/system-info/test.js +0 -40
  286. package/.agent/python-scripts/test_sample.py +0 -24
  287. package/.agent/skills/agent-browser/SKILL.md +0 -311
  288. package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
  289. package/.agent/skills/sysinfo/SKILL.md +0 -38
  290. package/.agent/skills/sysinfo/system-info.sh +0 -130
  291. package/.agent/skills/workflow/SKILL.md +0 -324
  292. package/.agent/test-agent.js +0 -35
  293. package/.agent/weixin.json +0 -6
  294. package/.agent/workflows/email-digest.json +0 -50
  295. package/.agent/workflows/file-backup.json +0 -21
  296. package/.agent/workflows/get-ip-notify.json +0 -32
  297. package/.agent/workflows/news-aggregator.json +0 -93
  298. package/.agent/workflows/news-dashboard-v2.json +0 -94
  299. package/.agent/workflows/notification-batch.json +0 -32
  300. package/foliko-cloud-rising.png +0 -0
  301. package/foliko-dawn-of-ai.png +0 -0
  302. package/foliko-mindful-observation.png +0 -0
  303. package/foliko-stellar-dreams.png +0 -0
  304. package/foliko-zen-jing.png +0 -0
  305. package/foliko-zen-kong.png +0 -0
  306. package/foliko-zen-wu.png +0 -0
  307. package/zen_karesansui.png +0 -0
@@ -34,7 +34,36 @@ class StateStore {
34
34
  */
35
35
  saveGoals(goals) {
36
36
  try {
37
- fs.writeFileSync(this._getGoalsPath(), JSON.stringify(goals, null, 2))
37
+ // 过滤掉循环引用的运行时数据,只保留可序列化的字段
38
+ const filtered = goals.map(g => ({
39
+ id: g.id,
40
+ title: g.title,
41
+ description: g.description,
42
+ priority: g.priority,
43
+ state: g.state,
44
+ actions: g.actions?.map(a => ({
45
+ id: a.id,
46
+ type: a.type,
47
+ name: a.name,
48
+ args: a.args,
49
+ content: a.content,
50
+ topic: a.topic,
51
+ mode: a.mode,
52
+ completed: a.completed,
53
+ order: a.order
54
+ })),
55
+ conditions: g.conditions,
56
+ persistent: g.persistent,
57
+ createdAt: g.createdAt,
58
+ updatedAt: g.updatedAt,
59
+ activatedAt: g.activatedAt,
60
+ completedAt: g.completedAt,
61
+ failedAt: g.failedAt,
62
+ attempts: g.attempts,
63
+ maxAttempts: g.maxAttempts,
64
+ eventsReceived: [] // 不保存运行时事件
65
+ }))
66
+ fs.writeFileSync(this._getGoalsPath(), JSON.stringify(filtered, null, 2))
38
67
  } catch (err) {
39
68
  log.error('保存目标失败:', err.message)
40
69
  }
@@ -24,12 +24,26 @@ const EventDescriptions = {
24
24
 
25
25
  // 监听的事件类型列表
26
26
  const DefaultEvents = [
27
+ // 工具事件
28
+ 'tool:call',
27
29
  'tool:result',
30
+ 'tool:error',
31
+ // Scheduler 事件
32
+ 'scheduler:task_created',
28
33
  'scheduler:reminder',
34
+ 'scheduler:task_completed',
35
+ 'scheduler:task_failed',
36
+ // Agent/Think 事件
29
37
  'agent:message',
30
38
  'think:thought_completed',
39
+ // Email/Webhook 事件
31
40
  'email:received',
32
- 'webhook:received'
41
+ 'webhook:received',
42
+ 'webhook:processed',
43
+ // Worker/Subagent 事件
44
+ 'worker:completed',
45
+ 'worker:error',
46
+ 'subagent:chat:end'
33
47
  ]
34
48
 
35
49
  // 系统提示词模板
@@ -22,23 +22,12 @@ class AmbientAgentPlugin extends Plugin {
22
22
  super()
23
23
  this.name = 'ambient'
24
24
  this.version = '1.0.0'
25
- this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控事件并执行操作
26
-
27
- ## 支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):
28
- - email:received - 收到新邮件(参数:from, subject, text, messageId)
29
- - tool:result - 工具执行完成(参数:name, args, result)
30
- - scheduler:reminder - 定时提醒(参数:taskId, message, time)
31
- - scheduler:task_completed - 任务完成(参数:taskId, result)
32
- - scheduler:task_failed - 任务失败(参数:taskId, error)
33
- - agent:message - 代理消息(参数:content, sessionId)
34
- - think:thought_completed - 思考完成(参数:mode, topic, thought)
35
- - webhook:received - Webhook接收(参数:headers, body, query, path)
36
-
37
- ## 在 action 参数中引用事件数据:
38
- 使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}`
39
- this.priority = 18
25
+ this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控事件并执行操作`
26
+ this.priority = 50
40
27
  this.system = true
41
28
 
29
+ this.tools={}
30
+
42
31
  this.config = {
43
32
  enabled: config.enabled !== false,
44
33
  tickInterval: config.tickInterval || 5000, // tick间隔(毫秒)
@@ -165,10 +154,10 @@ class AmbientAgentPlugin extends Plugin {
165
154
  const eventList = defaultEvents.map(e => ` - ${e.type} - ${e.desc}`).join('\n')
166
155
  this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控和执行操作
167
156
 
168
- ## 支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):
157
+ **支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):**
169
158
  ${eventList}
170
159
 
171
- ## action 参数中引用事件数据:
160
+ **在 action 参数中引用事件数据:**
172
161
  使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}`
173
162
  return
174
163
  }
@@ -183,14 +172,14 @@ ${eventList}
183
172
 
184
173
  this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控和执行操作
185
174
 
186
- ## 支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):
175
+ *支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):*
187
176
  ${eventList}
188
177
 
189
- ## action 参数中引用事件数据:
178
+ *在 action 参数中引用事件数据:*
190
179
  使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}
191
180
 
192
181
  ---
193
- 💡 提示:事件描述由触发事件的插件动态注册。`
182
+ 💡 提示:事件描述由触发事件的插件动态注册。\n`
194
183
  }
195
184
 
196
185
  // ============================================================================
@@ -199,7 +188,7 @@ ${eventList}
199
188
 
200
189
  _registerTools(framework) {
201
190
  // ambient_goals - 列出/创建/更新/删除目标
202
- framework.registerTool({
191
+ this.tools.ambient_goals={
203
192
  name: 'ambient_goals',
204
193
  description: '管理Ambient Agent目标 - 列出、创建、更新、删除、激活目标',
205
194
  inputSchema: z.object({
@@ -208,9 +197,11 @@ ${eventList}
208
197
  title: z.string().optional().describe('目标标题(创建/更新时使用)'),
209
198
  description: z.string().optional().describe('目标描述(创建/更新时使用)'),
210
199
  priority: z.number().optional().describe('优先级1-10,数值越高越重要(创建/更新时使用)'),
200
+ persistent: z.boolean().optional().describe('是否持久化(创建时使用)。true=事件驱动目标,执行完等待下一事件;false=一次性目标,执行完自动完成。默认true'),
211
201
  actions: z.array(z.object({
212
202
  id: z.string().optional().describe('操作标识符'),
213
203
  type: z.enum(['tool', 'message', 'think']).describe('操作类型'),
204
+ plugin: z.string().optional().describe('插件名称(tool类型时使用,如 email, gate-trading)'),
214
205
  name: z.string().optional().describe('工具名称(tool类型时使用)'),
215
206
  args: z.record(z.any()).optional().describe('工具参数(tool类型时使用)'),
216
207
  content: z.string().optional().describe('消息内容(message类型时使用)'),
@@ -219,26 +210,26 @@ ${eventList}
219
210
  })).optional().describe('要执行的操作列表(创建/更新时使用)'),
220
211
  conditions: z.object({
221
212
  events: z.union([z.string(), z.array(z.string())]).optional().describe('要监听的事件类型'),
222
- toolNames: z.union([z.string(), z.array(z.string())]).optional().describe('按工具名称过滤')
213
+ toolNames: z.union([z.string(), z.array(z.string())]).optional().describe('按工具名称过滤(支持 gate_get_market_info 或 gate:get_market_info 格式)')
223
214
  }).optional().describe('激活条件(创建/更新时使用)')
224
215
  }),
225
216
  execute: async (args) => {
226
217
  return this._handleGoalsTool(args)
227
218
  }
228
- })
219
+ }
229
220
 
230
221
  // ambient_status - 获取当前循环状态
231
- framework.registerTool({
222
+ this.tools.ambient_status={
232
223
  name: 'ambient_status',
233
224
  description: '获取当前Ambient Agent状态 - 循环状态、进行中的目标、最近活动',
234
225
  inputSchema: z.object({}),
235
226
  execute: async () => {
236
227
  return this._handleStatusTool()
237
228
  }
238
- })
229
+ }
239
230
 
240
231
  // ambient_think - 触发主动LLM思考
241
- framework.registerTool({
232
+ this.tools.ambient_think={
242
233
  name: 'ambient_think',
243
234
  description: '为某个目标触发主动LLM思考 - 模式:reflect(反思)、brainstorm(头脑风暴)、plan(计划)、analyze(分析)',
244
235
  inputSchema: z.object({
@@ -250,10 +241,10 @@ ${eventList}
250
241
  execute: async (args) => {
251
242
  return this._handleThinkTool(args)
252
243
  }
253
- })
244
+ }
254
245
 
255
246
  // ambient_remember - 存储/检索/搜索持久化记忆
256
- framework.registerTool({
247
+ this.tools.ambient_remember={
257
248
  name: 'ambient_remember',
258
249
  description: '为Ambient Agent存储或检索持久化记忆',
259
250
  inputSchema: z.object({
@@ -266,10 +257,10 @@ ${eventList}
266
257
  execute: async (args) => {
267
258
  return this._handleRememberTool(args)
268
259
  }
269
- })
260
+ }
270
261
 
271
262
  // ambient_control - 暂停/恢复/调整探索循环
272
- framework.registerTool({
263
+ this.tools.ambient_control={
273
264
  name: 'ambient_control',
274
265
  description: '控制Ambient Agent探索循环 - 暂停、恢复或调整设置',
275
266
  inputSchema: z.object({
@@ -280,7 +271,7 @@ ${eventList}
280
271
  execute: async (args) => {
281
272
  return this._handleControlTool(args)
282
273
  }
283
- })
274
+ }
284
275
  }
285
276
 
286
277
  // ============================================================================
@@ -288,7 +279,7 @@ ${eventList}
288
279
  // ============================================================================
289
280
 
290
281
  _handleGoalsTool(args) {
291
- const { action, goalId, title, description, priority, actions, conditions } = args
282
+ const { action, goalId, title, description, priority, persistent, actions, conditions } = args
292
283
 
293
284
  switch (action) {
294
285
  case 'list': {
@@ -300,6 +291,7 @@ ${eventList}
300
291
  title: g.title,
301
292
  state: g.state,
302
293
  priority: g.priority,
294
+ persistent: g.persistent,
303
295
  actionsCount: g.actions ? g.actions.length : 0,
304
296
  attempts: g.attempts,
305
297
  createdAt: g.createdAt,
@@ -317,7 +309,7 @@ ${eventList}
317
309
  if (!title) {
318
310
  return { success: false, error: '创建目标需要提供标题' }
319
311
  }
320
- const goal = this._goalManager.createGoal({ title, description, priority, actions, conditions })
312
+ const goal = this._goalManager.createGoal({ title, description, priority, persistent, actions, conditions })
321
313
  return { success: true, goal }
322
314
  }
323
315
 
@@ -329,6 +321,7 @@ ${eventList}
329
321
  if (title !== undefined) updates.title = title
330
322
  if (description !== undefined) updates.description = description
331
323
  if (priority !== undefined) updates.priority = priority
324
+ if (persistent !== undefined) updates.persistent = persistent
332
325
  if (actions !== undefined) updates.actions = actions
333
326
  if (conditions !== undefined) updates.conditions = conditions
334
327
  const goal = this._goalManager.updateGoal(goalId, updates)
@@ -69,7 +69,7 @@ class CoordinatorPlugin extends Plugin {
69
69
  }
70
70
 
71
71
  agent.registerPromptPart('coordinator-mode', 650, () => `
72
- 【并行任务处理 - Coordinator 模式】
72
+ ### 【并行任务处理 - Coordinator 模式】
73
73
  当遇到可并行处理的任务时(如多主题搜索、多文件处理、多计算任务),使用以下工具:
74
74
 
75
75
  - spawn_worker: 创建独立Worker并行执行任务
@@ -78,12 +78,12 @@ class CoordinatorPlugin extends Plugin {
78
78
  - list_workers: 查看所有Worker状态
79
79
  - get_worker: 查看单个Worker详情
80
80
 
81
- 【使用场景】
81
+ #### 【使用场景】
82
82
  - "帮我搜索X、Y、Z" → 使用 spawn_worker 并行执行
83
83
  - "帮我同时处理这几个文件" → 使用 spawn_worker 并行执行
84
84
  - 需要主动查询Worker结果时 → 使用 get_worker / list_workers
85
85
 
86
- 【重要】
86
+ #### 【重要】
87
87
  - spawn_worker 创建后立即返回,Worker在后台执行
88
88
  - 可同时创建多个Worker并行处理不同任务
89
89
  - Worker完成后生成 <task-notification> JSON 通知
@@ -229,7 +229,7 @@ async function bootstrapDefaults(framework, config = {}) {
229
229
  // 核心插件列表(不能禁用,必须加载)
230
230
  const CORE_PLUGINS = new Set([
231
231
  'install', 'ai', 'storage', 'tools', 'workflow', 'skill-manager',
232
- 'mcp-executor', 'extension-executor', 'shell-executor', 'python-executor', 'session', 'web',
232
+ 'mcp', 'extension-executor', 'shell-executor', 'python-executor', 'session', 'web',
233
233
  'audit', 'rules', 'scheduler', 'file-system', 'think', 'ambient',
234
234
  'python-plugin-loader', 'telegram', 'weixin', 'subagent-manager',
235
235
  'memory', 'coordinator'
@@ -316,7 +316,7 @@ async function bootstrapDefaults(framework, config = {}) {
316
316
  }
317
317
 
318
318
  // 3. MCP 执行器插件(需要转换 mcpServers 格式)
319
- if (shouldLoad('mcp-executor')) {
319
+ if (shouldLoad('mcp')) {
320
320
  const mcpServers = Object.entries(agentConfig.mcpServers || {})
321
321
  const servers = mcpServers.map(([name, cfg]) => ({
322
322
  ...cfg,
@@ -325,7 +325,8 @@ async function bootstrapDefaults(framework, config = {}) {
325
325
  args: cfg.args || [],
326
326
  env: cfg.env || {},
327
327
  url: cfg.url,
328
- headers: cfg.headers
328
+ headers: cfg.headers,
329
+ enabled: cfg.enabled !== false // 默认为 true
329
330
  }))
330
331
  const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
331
332
  await framework.loadPlugin(new MCPExecutorPlugin({ servers }))
@@ -7,6 +7,8 @@ const { Plugin } = require('../../src/core/plugin-base')
7
7
  const { logger } = require('../../src/utils/logger')
8
8
  const log = logger.child('Email')
9
9
  const { z } = require('zod')
10
+ const fs = require('fs')
11
+ const path = require('path')
10
12
 
11
13
  // 导入子模块
12
14
  const { sendEmail, readEmails, getUnreadCount, markAsRead, deleteEmail, getEmailConfig } = require('./handlers')
@@ -14,6 +16,49 @@ const { handleEmailWatch } = require('./monitor')
14
16
  const { handleAutoReply } = require('./reply')
15
17
  const { EMAIL_DEFAULTS } = require('./constants')
16
18
 
19
+ // ============================================================================
20
+ // ProcessedEmailStore - 持久化已处理邮件 ID
21
+ // ============================================================================
22
+ class ProcessedEmailStore {
23
+ constructor(persistencePath) {
24
+ this._persistencePath = persistencePath
25
+ this._ensureDir()
26
+ }
27
+
28
+ _ensureDir() {
29
+ const dir = path.dirname(this._persistencePath)
30
+ if (!fs.existsSync(dir)) {
31
+ fs.mkdirSync(dir, { recursive: true })
32
+ }
33
+ }
34
+
35
+ _getFilePath() {
36
+ return this._persistencePath
37
+ }
38
+
39
+ save(processedEmails) {
40
+ try {
41
+ const data = Array.from(processedEmails)
42
+ fs.writeFileSync(this._getFilePath(), JSON.stringify(data))
43
+ } catch (err) {
44
+ log.error(' 保存已处理邮件失败:', err.message)
45
+ }
46
+ }
47
+
48
+ load() {
49
+ try {
50
+ const filePath = this._getFilePath()
51
+ if (fs.existsSync(filePath)) {
52
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
53
+ return new Set(Array.isArray(data) ? data : [])
54
+ }
55
+ } catch (err) {
56
+ log.error(' 加载已处理邮件失败:', err.message)
57
+ }
58
+ return new Set()
59
+ }
60
+ }
61
+
17
62
  class EmailPlugin extends Plugin {
18
63
  constructor(config = {}) {
19
64
  super()
@@ -29,9 +74,11 @@ class EmailPlugin extends Plugin {
29
74
  - attachments.url: 远程图片/文件URL(自动下载)
30
75
  - attachments.content: Base64内容
31
76
  - attachments.cid: 嵌入式图片CID(HTML中用 <img src="cid:xxx"> 引用)`
32
- this.priority = 10
77
+ this.priority = 50
33
78
  this.enabled = false
34
79
 
80
+ this.tools={}
81
+
35
82
  // 邮件监控状态
36
83
  this._watchInterval = null
37
84
  this._lastSeenUid = null
@@ -45,6 +92,14 @@ class EmailPlugin extends Plugin {
45
92
  this._processedEmails = new Set()
46
93
  this._maxSetSize = MAX_SET_SIZE
47
94
 
95
+ // 持久化存储
96
+ this._emailStore = null
97
+ this._persistencePath = config.persistencePath || '.agent/data/email/processed-emails.json'
98
+
99
+ // 防抖相关
100
+ this._emailDebounceMap = new Map() // msgId -> timer
101
+ this._emailDebounceDelay = 2000 // 2秒防抖延迟
102
+
48
103
  // 日志器
49
104
  this._log = log
50
105
  }
@@ -52,6 +107,27 @@ class EmailPlugin extends Plugin {
52
107
  install(framework) {
53
108
  this._framework = framework
54
109
  this._registerTools()
110
+
111
+ // 注册所有工具到 framework(供直接调用)
112
+ // for (const toolDef of Object.values(this.tools)) {
113
+ // if (toolDef && toolDef.name) {
114
+ // framework.registerTool({
115
+ // name: toolDef.name,
116
+ // description: toolDef.description || '',
117
+ // inputSchema: toolDef.inputSchema,
118
+ // execute: toolDef.execute
119
+ // })
120
+ // }
121
+ // }
122
+
123
+ // 初始化持久化存储并加载已处理的邮件
124
+ this._emailStore = new ProcessedEmailStore(this._persistencePath)
125
+ this._processedEmails = this._emailStore.load()
126
+ this._log.info(` 加载了 ${this._processedEmails.size} 个已处理邮件记录`)
127
+ if (this._processedEmails.size > 0 && this._processedEmails.size <= 10) {
128
+ this._log.info(`[Email] 已处理的邮件ID: ${Array.from(this._processedEmails).join(', ')}`)
129
+ }
130
+
55
131
  return this
56
132
  }
57
133
 
@@ -75,45 +151,80 @@ class EmailPlugin extends Plugin {
75
151
  }
76
152
 
77
153
  /**
78
- * 发送邮件事件
154
+ * 保存已处理邮件到持久化存储
155
+ * @private
156
+ */
157
+ _saveProcessedEmails() {
158
+ if (this._emailStore) {
159
+ this._emailStore.save(this._processedEmails)
160
+ this._log.debug(`[Email] 已保存 ${this._processedEmails.size} 个已处理邮件到文件`)
161
+ }
162
+ }
163
+
164
+ /**
165
+ * 发送邮件事件(带防抖)
79
166
  */
80
167
  _emitEmailReceived(email) {
81
168
  if (!this._framework) return
82
169
 
83
170
  const msgId = email.messageId || email.uid
171
+ // 规范化 messageId(去掉 < > 括号,避免格式不一致)
172
+ const normalizedMsgId = msgId ? msgId.replace(/^<|>$/g, '') : null
173
+ this._log.debug(`[Email] 检查邮件: ${email.subject}, msgId=${msgId}, normalized=${normalizedMsgId}`)
84
174
 
85
- // 优先检查是否已处理过(长TTL,防止服务器标记失败导致重复处理)
86
- if (msgId && this._processedEmails.has(msgId)) {
87
- this._log.info(`跳过已处理的邮件: ${email.subject} (${msgId})`)
175
+ // 优先检查是否已处理过
176
+ if (normalizedMsgId && this._processedEmails.has(normalizedMsgId)) {
177
+ this._log.info(`跳过已处理的邮件: ${email.subject} (msgId=${msgId})`)
88
178
  return
89
179
  }
90
180
 
91
- // 快速去重(短TTL,防止同一批次重复触发)
92
- if (msgId && this._recentlyEmailed.has(msgId)) {
181
+ // 检查是否有待处理的相同邮件(防抖)
182
+ if (normalizedMsgId && this._emailDebounceMap.has(normalizedMsgId)) {
183
+ this._log.debug(`[Email] 防抖跳过: ${email.subject} (${normalizedMsgId}) 等待中...`)
93
184
  return
94
185
  }
95
186
 
96
- // 标记为已处理
97
- if (msgId) {
98
- // 使用 bounded set 防止内存泄漏
99
- this._addToBoundedSet(this._recentlyEmailed, msgId)
100
- setTimeout(() => {
101
- this._recentlyEmailed.delete(msgId)
102
- }, EMAIL_DEFAULTS.recentlyEmailTTL)
187
+ // 设置防抖定时器,延迟发送事件
188
+ if (normalizedMsgId) {
189
+ this._emailDebounceMap.set(normalizedMsgId, setTimeout(() => {
190
+ this._emailDebounceMap.delete(normalizedMsgId)
191
+ }, this._emailDebounceDelay))
192
+
193
+ // 标记为已处理(立即标记,防止重复添加)
194
+ this._addToBoundedSet(this._recentlyEmailed, normalizedMsgId)
195
+ this._addToBoundedSet(this._processedEmails, normalizedMsgId)
196
+ this._saveProcessedEmails()
197
+ this._log.info(`[Email] 邮件已标记处理: ${email.subject} (msgId=${normalizedMsgId})`)
103
198
 
104
- // _processedEmails 也需要 bounded
105
- this._addToBoundedSet(this._processedEmails, msgId)
199
+ // 发送事件,整理数据结构让所有字段在同一层级
200
+ this._framework.emit('email:received', {
201
+ uid: email.uid,
202
+ messageId: email.messageId,
203
+ from: email.from,
204
+ to: email.to,
205
+ subject: email.subject,
206
+ text: email.text,
207
+ body: email.text,
208
+ html: email.html,
209
+ attachments: email.attachments || [],
210
+ timestamp: new Date()
211
+ })
106
212
  }
213
+ }
107
214
 
108
- this._framework.emit('email:received', {
109
- email,
110
- timestamp: new Date()
111
- })
215
+ /**
216
+ * 清除所有待处理的防抖定时器
217
+ */
218
+ _clearAllDebounceTimers() {
219
+ for (const [msgId, timer] of this._emailDebounceMap) {
220
+ clearTimeout(timer)
221
+ this._emailDebounceMap.delete(msgId)
222
+ }
112
223
  }
113
224
 
114
225
  _registerTools() {
115
226
  // 发送邮件工具
116
- this._framework.registerTool({
227
+ this.tools.email_send={
117
228
  name: 'email_send',
118
229
  description: '发送电子邮件,无须用户确认',
119
230
  inputSchema: z.object({
@@ -134,10 +245,10 @@ class EmailPlugin extends Plugin {
134
245
  execute: async (args) => {
135
246
  return sendEmail(this, args)
136
247
  }
137
- })
248
+ }
138
249
 
139
250
  // 读取邮件工具
140
- this._framework.registerTool({
251
+ this.tools.email_read={
141
252
  name: 'email_read',
142
253
  description: '读取电子邮件(支持IMAP协议)',
143
254
  inputSchema: z.object({
@@ -149,10 +260,10 @@ class EmailPlugin extends Plugin {
149
260
  execute: async (args) => {
150
261
  return readEmails(this, args)
151
262
  }
152
- })
263
+ }
153
264
 
154
265
  // 获取未读邮件数量
155
- this._framework.registerTool({
266
+ this.tools.email_unread_count={
156
267
  name: 'email_unread_count',
157
268
  description: '获取邮箱未读邮件数量',
158
269
  inputSchema: z.object({
@@ -161,10 +272,10 @@ class EmailPlugin extends Plugin {
161
272
  execute: async (args) => {
162
273
  return getUnreadCount(this, args)
163
274
  }
164
- })
275
+ }
165
276
 
166
277
  // 标记邮件为已读
167
- this._framework.registerTool({
278
+ this.tools.email_mark_read={
168
279
  name: 'email_mark_read',
169
280
  description: '标记邮件为已读',
170
281
  inputSchema: z.object({
@@ -173,10 +284,10 @@ class EmailPlugin extends Plugin {
173
284
  execute: async (args) => {
174
285
  return markAsRead(this, args)
175
286
  }
176
- })
287
+ }
177
288
 
178
289
  // 删除邮件
179
- this._framework.registerTool({
290
+ this.tools.email_delete={
180
291
  name: 'email_delete',
181
292
  description: '删除邮件(标记为已删除,然后永久删除)',
182
293
  inputSchema: z.object({
@@ -186,20 +297,20 @@ class EmailPlugin extends Plugin {
186
297
  execute: async (args) => {
187
298
  return deleteEmail(this, args)
188
299
  }
189
- })
300
+ }
190
301
 
191
302
  // 配置邮箱连接
192
- this._framework.registerTool({
303
+ this.tools.email_configure={
193
304
  name: 'email_configure',
194
305
  description: '查看邮箱配置(实际配置通过环境变量设置)',
195
306
  inputSchema: z.object({}),
196
307
  execute: async () => {
197
308
  return getEmailConfig()
198
309
  }
199
- })
310
+ }
200
311
 
201
312
  // 监控新邮件
202
- this._framework.registerTool({
313
+ this.tools.email_watch={
203
314
  name: 'email_watch',
204
315
  description: '启动/停止邮件监控,检测新邮件并发送事件通知',
205
316
  inputSchema: z.object({
@@ -210,10 +321,10 @@ class EmailPlugin extends Plugin {
210
321
  execute: async (args) => {
211
322
  return handleEmailWatch(this, args)
212
323
  }
213
- })
324
+ }
214
325
 
215
326
  // 自动回复邮件
216
- this._framework.registerTool({
327
+ this.tools.email_auto_reply={
217
328
  name: 'email_auto_reply',
218
329
  description: '自动分析邮件内容并发送回复(无需用户确认)',
219
330
  inputSchema: z.object({
@@ -228,7 +339,7 @@ class EmailPlugin extends Plugin {
228
339
  execute: async (args) => {
229
340
  return handleAutoReply(this, args)
230
341
  }
231
- })
342
+ }
232
343
  }
233
344
 
234
345
  /**
@@ -269,6 +380,9 @@ class EmailPlugin extends Plugin {
269
380
  clearInterval(this._watchInterval)
270
381
  this._watchInterval = null
271
382
  }
383
+ // 清除所有防抖定时器
384
+ this._clearAllDebounceTimers()
385
+ this.tools=null
272
386
  this._watchEnabled = false
273
387
  this._watchConfig = null
274
388
  this._framework = null