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
@@ -13,6 +13,46 @@ const { Hono } = require('hono')
13
13
  const fs = require('fs')
14
14
  const path = require('path')
15
15
 
16
+ // ============================================================================
17
+ // WebStore - 持久化 Web 配置到 .agent/data/web/
18
+ // ============================================================================
19
+ class WebStore {
20
+ constructor(persistencePath) {
21
+ this._persistencePath = persistencePath
22
+ this._ensureDir()
23
+ }
24
+
25
+ _ensureDir() {
26
+ if (!fs.existsSync(this._persistencePath)) {
27
+ fs.mkdirSync(this._persistencePath, { recursive: true })
28
+ }
29
+ }
30
+
31
+ _getConfigPath() {
32
+ return path.join(this._persistencePath, 'web-config.json')
33
+ }
34
+
35
+ saveConfig(data) {
36
+ try {
37
+ fs.writeFileSync(this._getConfigPath(), JSON.stringify(data, null, 2))
38
+ } catch (err) {
39
+ log.error(' 保存 Web 配置失败:', err.message)
40
+ }
41
+ }
42
+
43
+ loadConfig() {
44
+ try {
45
+ const filePath = this._getConfigPath()
46
+ if (fs.existsSync(filePath)) {
47
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'))
48
+ }
49
+ } catch (err) {
50
+ log.error(' 加载 Web 配置失败:', err.message)
51
+ }
52
+ return null
53
+ }
54
+ }
55
+
16
56
  class WebPlugin extends Plugin {
17
57
  constructor(config = {}) {
18
58
  super()
@@ -39,6 +79,10 @@ class WebPlugin extends Plugin {
39
79
  this._routes = [] // 路由列表
40
80
  this._webhooks = new Map() // webhook Map: id -> {id, path, prompt, sessionId}
41
81
  this._statics = [] // 静态文件夹列表
82
+
83
+ // 持久化存储
84
+ this._webStore = null
85
+ this._persistencePath = config.persistencePath || '.agent/data/web'
42
86
  }
43
87
 
44
88
  // ==================== 生命周期 ====================
@@ -47,6 +91,12 @@ class WebPlugin extends Plugin {
47
91
  this._framework = framework
48
92
  this._registerTools()
49
93
 
94
+ // 初始化持久化存储
95
+ this._webStore = new WebStore(this._persistencePath)
96
+
97
+ // 加载已保存的配置
98
+ this._loadPersistedConfig()
99
+
50
100
  // 将 WEB_BASE_URL 注入到 framework 的元数据,供所有 agent 使用
51
101
  if (this._baseUrl && framework._mainAgent) {
52
102
  framework._mainAgent.setMetadata('WEB_BASE_URL', this._baseUrl)
@@ -61,12 +111,117 @@ class WebPlugin extends Plugin {
61
111
 
62
112
  reload(framework) {
63
113
  this._framework = framework
114
+
115
+ // 重新初始化存储并加载配置
116
+ this._webStore = new WebStore(this._persistencePath)
117
+ this._loadPersistedConfig()
118
+
64
119
  // 重新注入 WEB_BASE_URL
65
120
  if (this._baseUrl && framework._mainAgent) {
66
121
  framework._mainAgent.setMetadata('WEB_BASE_URL', this._baseUrl)
67
122
  }
68
123
  }
69
124
 
125
+ /**
126
+ * 加载持久化的配置并恢复路由/webhook/静态资源
127
+ */
128
+ _loadPersistedConfig() {
129
+ if (!this._webStore) return
130
+
131
+ const config = this._webStore.loadConfig()
132
+ if (!config) return
133
+
134
+ log.info(` 加载 Web 配置...`)
135
+
136
+ let hasRoutes = false
137
+ let hasWebhooks = false
138
+ let hasStatics = false
139
+
140
+ // 恢复路由
141
+ if (config.routes && Array.isArray(config.routes)) {
142
+ for (const route of config.routes) {
143
+ if (route.method && route.path && route.handler) {
144
+ this._routes.push({
145
+ method: route.method,
146
+ path: route.path,
147
+ handler: route.handler,
148
+ description: route.description || ''
149
+ })
150
+ hasRoutes = true
151
+ log.info(` 恢复路由: ${route.method} ${route.path}`)
152
+ }
153
+ }
154
+ }
155
+
156
+ // 恢复 Webhooks
157
+ if (config.webhooks && Array.isArray(config.webhooks)) {
158
+ for (const webhook of config.webhooks) {
159
+ if (webhook.id && webhook.path) {
160
+ this._webhooks.set(webhook.path, {
161
+ id: webhook.id,
162
+ path: webhook.path,
163
+ prompt: webhook.prompt || '处理以下 webhook 数据,返回适当的响应:',
164
+ awaitResponse: webhook.awaitResponse || false
165
+ })
166
+ hasWebhooks = true
167
+ log.info(` 恢复 Webhook: ${webhook.path}`)
168
+ }
169
+ }
170
+ }
171
+
172
+ // 恢复静态资源
173
+ if (config.statics && Array.isArray(config.statics)) {
174
+ for (const staticItem of config.statics) {
175
+ if (staticItem.urlPath && staticItem.folder) {
176
+ this._statics.push({
177
+ urlPath: staticItem.urlPath,
178
+ folder: staticItem.folder,
179
+ options: staticItem.options || { dotfiles: 'ignore', index: 'index.html' }
180
+ })
181
+ hasStatics = true
182
+ log.info(` 恢复静态资源: ${staticItem.urlPath} -> ${staticItem.folder}`)
183
+ }
184
+ }
185
+ }
186
+
187
+ // 如果有恢复的路由/webhook/静态资源,自动启动服务器
188
+ if ((hasRoutes || hasWebhooks || hasStatics) && !this._server) {
189
+ log.info(` 恢复的 Web 配置需要启动服务器...`)
190
+ this._startServer().catch(err => {
191
+ log.error(` 自动启动服务器失败:`, err.message)
192
+ })
193
+ }
194
+ }
195
+
196
+ /**
197
+ * 保存当前配置到持久化存储
198
+ */
199
+ _saveConfig() {
200
+ if (!this._webStore) return
201
+
202
+ const config = {
203
+ routes: this._routes.map(r => ({
204
+ method: r.method,
205
+ path: r.path,
206
+ handler: r.handler,
207
+ description: r.description
208
+ })),
209
+ webhooks: Array.from(this._webhooks.values()).map(w => ({
210
+ id: w.id,
211
+ path: w.path,
212
+ prompt: w.prompt,
213
+ awaitResponse: w.awaitResponse
214
+ })),
215
+ statics: this._statics.map(s => ({
216
+ urlPath: s.urlPath,
217
+ folder: s.folder,
218
+ options: s.options
219
+ }))
220
+ }
221
+
222
+ this._webStore.saveConfig(config)
223
+ }
224
+
70
225
  uninstall() {
71
226
  this._stopServer()
72
227
  this._framework = null
@@ -146,6 +301,37 @@ class WebPlugin extends Plugin {
146
301
  execute: async () => this._listRoutes()
147
302
  }
148
303
 
304
+ // 删除路由
305
+ this.tools.web_delete_route = {
306
+ name: 'web_delete_route',
307
+ description: '删除已注册的 HTTP 路由',
308
+ inputSchema: z.object({
309
+ method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']).describe('HTTP 方法'),
310
+ path: z.string().describe('路由路径,如 /api/user')
311
+ }),
312
+ execute: async (args) => this._deleteRoute(args.method, args.path)
313
+ }
314
+
315
+ // 删除 Webhook
316
+ this.tools.web_delete_webhook = {
317
+ name: 'web_delete_webhook',
318
+ description: '删除已注册的 Webhook',
319
+ inputSchema: z.object({
320
+ id: z.string().describe('Webhook ID')
321
+ }),
322
+ execute: async (args) => this._deleteWebhook(args.id)
323
+ }
324
+
325
+ // 删除静态资源
326
+ this.tools.web_delete_static = {
327
+ name: 'web_delete_static',
328
+ description: '删除已注册的静态资源文件夹',
329
+ inputSchema: z.object({
330
+ urlPath: z.string().describe('URL 路径前缀,如 /public')
331
+ }),
332
+ execute: async (args) => this._deleteStatic(args.urlPath)
333
+ }
334
+
149
335
  // 发送 HTTP 请求
150
336
  this.tools.web_request = {
151
337
  name: 'web_request',
@@ -317,8 +503,14 @@ class WebPlugin extends Plugin {
317
503
  const prompt = webhook.prompt || '处理以下 webhook 数据,返回适当的响应:'
318
504
  const finalSessionId = sessionId || `web_${Date.now()}`
319
505
 
320
- // 触发 webhook 接收事件
321
- this._framework.emit('webhook:received', { webhook, data: webhookData, sessionId: finalSessionId })
506
+ // 触发 webhook 接收事件(扁平化结构)
507
+ this._framework.emit('webhook:received', {
508
+ path: webhook.path,
509
+ method: c.req.method,
510
+ query,
511
+ body,
512
+ timestamp: webhookData.timestamp
513
+ })
322
514
 
323
515
  // 使用子Agent处理 webhook
324
516
  const webhookAgent = this._framework.createSubAgent({
@@ -342,7 +534,14 @@ class WebPlugin extends Plugin {
342
534
  }
343
535
 
344
536
  // 触发 webhook 处理完成事件
345
- this._framework.emit('webhook:processed', { webhook, data: webhookData, response: responseText, sessionId: finalSessionId })
537
+ this._framework.emit('webhook:processed', {
538
+ path: webhook.path,
539
+ method: c.req.method,
540
+ query,
541
+ body,
542
+ response: responseText,
543
+ timestamp: webhookData.timestamp
544
+ })
346
545
  }).catch(err => {
347
546
  log.error(' Webhook error:', err.message)
348
547
  })
@@ -366,7 +565,14 @@ class WebPlugin extends Plugin {
366
565
  }
367
566
 
368
567
  // 触发 webhook 处理完成事件
369
- this._framework.emit('webhook:received', { webhook, data: webhookData, response: responseText, sessionId: finalSessionId })
568
+ this._framework.emit('webhook:processed', {
569
+ path: webhook.path,
570
+ method: c.req.method,
571
+ query,
572
+ body,
573
+ response: responseText,
574
+ timestamp: webhookData.timestamp
575
+ })
370
576
 
371
577
  return { success: true, message: 'Webhook processed', response: responseText }
372
578
  } catch (err) {
@@ -394,6 +600,9 @@ class WebPlugin extends Plugin {
394
600
  this._routes.push(route)
395
601
  }
396
602
 
603
+ // 持久化保存
604
+ this._saveConfig()
605
+
397
606
  log.info(` Route registered: ${method} ${path}`)
398
607
  return { success: true, message: `Route ${method} ${path} registered`, url: this._getUrl(path), route: { method, path, description } }
399
608
  }
@@ -414,6 +623,9 @@ class WebPlugin extends Plugin {
414
623
  awaitResponse
415
624
  })
416
625
 
626
+ // 持久化保存
627
+ this._saveConfig()
628
+
417
629
  log.info(` Webhook registered: ${webhookPath}`)
418
630
  return {
419
631
  success: true,
@@ -441,6 +653,9 @@ class WebPlugin extends Plugin {
441
653
  }
442
654
  })
443
655
 
656
+ // 持久化保存
657
+ this._saveConfig()
658
+
444
659
  log.info(` Static registered: ${normalizedPath} -> ${folder}`)
445
660
  return {
446
661
  success: true,
@@ -461,6 +676,50 @@ class WebPlugin extends Plugin {
461
676
  }
462
677
  }
463
678
 
679
+ async _deleteRoute(method, path) {
680
+ const index = this._routes.findIndex(r => r.method === method.toUpperCase() && r.path === path)
681
+ if (index < 0) {
682
+ return { success: false, error: `Route not found: ${method} ${path}` }
683
+ }
684
+
685
+ this._routes.splice(index, 1)
686
+ this._saveConfig()
687
+ log.info(` Route deleted: ${method} ${path}`)
688
+ return { success: true, message: `Route deleted: ${method} ${path}` }
689
+ }
690
+
691
+ async _deleteWebhook(id) {
692
+ let found = null
693
+ for (const [path, webhook] of this._webhooks.entries()) {
694
+ if (webhook.id === id) {
695
+ found = path
696
+ break
697
+ }
698
+ }
699
+
700
+ if (!found) {
701
+ return { success: false, error: `Webhook not found: ${id}` }
702
+ }
703
+
704
+ this._webhooks.delete(found)
705
+ this._saveConfig()
706
+ log.info(` Webhook deleted: ${found}`)
707
+ return { success: true, message: `Webhook deleted: ${found}` }
708
+ }
709
+
710
+ async _deleteStatic(urlPath) {
711
+ const normalizedPath = urlPath.endsWith('/') ? urlPath : urlPath + '/'
712
+ const index = this._statics.findIndex(s => s.urlPath === normalizedPath)
713
+ if (index < 0) {
714
+ return { success: false, error: `Static folder not found: ${urlPath}` }
715
+ }
716
+
717
+ this._statics.splice(index, 1)
718
+ this._saveConfig()
719
+ log.info(` Static deleted: ${normalizedPath}`)
720
+ return { success: true, message: `Static folder deleted: ${normalizedPath}` }
721
+ }
722
+
464
723
  // ==================== HTTP 客户端 ====================
465
724
 
466
725
  async _sendRequest(method, urlPath, body, headers) {
@@ -673,7 +673,7 @@ class WeixinPlugin extends Plugin {
673
673
  * 处理统一通知
674
674
  */
675
675
  async _handleNotification(data) {
676
- const { title, message, source, level, sessionId } = data
676
+ const { title, message, source = '系统消息', level, sessionId } = data
677
677
 
678
678
  if (!this._bot) {
679
679
  log.warn(' Bot not ready, cannot send notification')
@@ -717,7 +717,7 @@ class WeixinPlugin extends Plugin {
717
717
  error: '❌'
718
718
  }
719
719
  const emoji = levelEmoji[level] || 'ℹ️'
720
- const notificationText = `${emoji} [${source}] ${title}\n\n${message}`
720
+ const notificationText = `${emoji} [${source}] ${title || '通知'}\n\n${message || ''}`
721
721
 
722
722
  try {
723
723
  await this._sendMessageBatch(null, userId, notificationText, false)