foliko 1.1.36 → 1.1.39

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 (168) hide show
  1. package/.agent/agents/network-requester.md +44 -0
  2. package/.agent/agents/poster-designer.md +52 -0
  3. package/.agent/agents/ui-designer.md +1 -1
  4. package/.agent/data/default.json +23 -407
  5. package/.agent/data/email/processed-emails.json +1 -0
  6. package/.agent/data/plugins-state.json +103 -200
  7. package/.agent/data/scheduler/tasks.json +1 -86
  8. package/.agent/data/web/web-config.json +5 -0
  9. package/.agent/data/weixin/images/file_1776188148383jpg +0 -0
  10. package/.agent/data/weixin/images/file_1776188458326.jpg +0 -0
  11. package/.agent/data/weixin/images/file_1776188689423.jpg +0 -0
  12. package/.agent/data/weixin/images/file_1776188813604.jpg +0 -0
  13. package/.agent/data/weixin/images/file_1776189097450.jpg +0 -0
  14. package/.agent/data/weixin/videos/file_1776188318431.mp4 +0 -0
  15. package/.agent/mcp_config.json +4 -17
  16. package/.agent/memory/user/mof6gk94-kneeuh.md +9 -0
  17. package/.agent/package.json +8 -0
  18. package/.agent/plugins/marknative/README.md +134 -0
  19. package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
  20. package/.agent/plugins/marknative/fonts.zip +0 -0
  21. package/.agent/plugins/marknative/index.js +256 -0
  22. package/.agent/plugins/marknative/package.json +12 -0
  23. package/.agent/plugins/test-plugin.py +99 -0
  24. package/.agent/plugins.json +11 -5
  25. package/.agent/python-scripts/test_sample.py +24 -0
  26. package/.agent/sessions/cli_default.json +2415 -349
  27. package/.agent/sessions/default.json +82 -0
  28. package/.agent/sessions/qq_c2c_D960F12877541624D7B2C836110B3D0F.json +25 -0
  29. package/.agent/sessions/test-clean.json +26 -0
  30. package/.agent/sessions/test-compress.json +1462 -0
  31. package/.agent/sessions/test-session.json +13 -0
  32. package/.agent/sessions/weixin_test.json +22 -0
  33. package/.agent/sessions/weixin_test_user_123.json +11 -0
  34. package/.agent/skills/agent-browser/SKILL.md +311 -0
  35. package/.agent/skills/agent-browser/TEST_PLAN.md +200 -0
  36. package/.agent/skills/sysinfo/SKILL.md +38 -0
  37. package/.agent/skills/sysinfo/system-info.sh +130 -0
  38. package/.agent/skills/workflow/SKILL.md +324 -0
  39. package/.agent/test-agent.js +35 -0
  40. package/.agent/weixin.json +6 -0
  41. package/.agent/workflows/email-digest.json +50 -0
  42. package/.agent/workflows/file-backup.json +21 -0
  43. package/.agent/workflows/get-ip-notify.json +32 -0
  44. package/.agent/workflows/news-aggregator.json +93 -0
  45. package/.agent/workflows/news-dashboard-v2.json +94 -0
  46. package/.agent/workflows/notification-batch.json +32 -0
  47. package/.claude/settings.local.json +2 -1
  48. package/.env.example +56 -56
  49. package/README.md +441 -441
  50. package/cli/src/utils/debounce.js +6 -3
  51. package/docs/qq-bot.md +976 -0
  52. package/package.json +3 -1
  53. package/plugins/qq-plugin.js +939 -0
  54. package/plugins/scheduler-plugin.js +17 -17
  55. package/skills/find-skills/AGENTS.md +162 -162
  56. package/skills/find-skills/SKILL.md +133 -133
  57. package/src/core/agent-chat.js +11 -6
  58. package/temp_img.md +1 -0
  59. package/website_v2/styles/animations.css +7 -7
  60. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
  61. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
  62. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
  63. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
  64. package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
  65. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
  66. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
  67. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  68. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  69. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  70. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  71. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
  72. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  73. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  74. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
  75. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  76. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  77. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  78. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  79. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
  80. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
  81. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  82. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  83. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
  84. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  85. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  86. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
  87. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
  88. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
  89. package/.agent/ARCHITECTURE.md +0 -288
  90. package/.agent/data/ambient/goals.json +0 -1
  91. package/.agent/data/puppeteer-sessions/undefined.json +0 -6
  92. package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
  93. package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
  94. package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
  95. package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
  96. package/.agent/memory/feedback/mnygjgox-ualjip.md +0 -11
  97. package/.agent/memory/feedback/mnzugpej-esdwsr.md +0 -9
  98. package/.agent/memory/feedback/mo2quxke-saxs56.md +0 -9
  99. package/.agent/memory/feedback/mo9l6nw9-sm1ye2.md +0 -13
  100. package/.agent/memory/feedback/mo9uxkb3-bbxz3x.md +0 -9
  101. package/.agent/memory/feedback/mo9wpqy0-ftsez9.md +0 -13
  102. package/.agent/memory/feedback/mo9x2ps4-p7huqq.md +0 -11
  103. package/.agent/memory/feedback/mo9x2uay-z7ndjn.md +0 -9
  104. package/.agent/memory/feedback/mo9x2y7d-9wecyx.md +0 -9
  105. package/.agent/memory/feedback/mo9x39q3-nn7myt.md +0 -9
  106. package/.agent/memory/feedback/mo9xfir9-4g8a8j.md +0 -9
  107. package/.agent/memory/feedback/mo9xfui8-ujqrc6.md +0 -9
  108. package/.agent/memory/feedback/mocnx1wx-qtxxlh.md +0 -9
  109. package/.agent/memory/project/mnqx54u5-loqtoe.md +0 -9
  110. package/.agent/memory/project/mnqx84cv-mx6dmd.md +0 -9
  111. package/.agent/memory/project/mnsacuyr-hgtk5n.md +0 -20
  112. package/.agent/memory/project/mnu5hy2x-bjsg7u.md +0 -9
  113. package/.agent/memory/project/mny28ot4-8qe9au.md +0 -9
  114. package/.agent/memory/project/mnztftxj-af82rh.md +0 -9
  115. package/.agent/memory/project/mo0y04d0-bmaefl.md +0 -9
  116. package/.agent/memory/project/mo2iztxb-3c7v81.md +0 -9
  117. package/.agent/memory/project/mo2ssa5x-tpi1p3.md +0 -9
  118. package/.agent/memory/reference/mnre3cww-penbo1.md +0 -9
  119. package/.agent/memory/reference/mns9wn48-luerua.md +0 -14
  120. package/.agent/memory/reference/mns9yz5c-thc2s0.md +0 -16
  121. package/.agent/memory/reference/mnsfy4um-910f1o.md +0 -23
  122. package/.agent/memory/reference/mnsg37dp-lmfj18.md +0 -32
  123. package/.agent/memory/reference/mnsll60q-0j911u.md +0 -36
  124. package/.agent/memory/reference/mnsmlb5y-nej31u.md +0 -16
  125. package/.agent/memory/reference/mnssle72-yrot96.md +0 -9
  126. package/.agent/memory/reference/mnygj8nb-bjthmc.md +0 -20
  127. package/.agent/memory/reference/mnzfvs4m-ufyg9a.md +0 -12
  128. package/.agent/memory/user/mnsfuon6-l416q1.md +0 -21
  129. package/.agent/memory/user/mnsg9kut-95m7rf.md +0 -20
  130. package/.agent/memory/user/mnu2eo1v-yy6fhe.md +0 -9
  131. package/.agent/memory/user/mnu2etuo-8u8jk8.md +0 -9
  132. package/.agent/memory/user/mnx0rk6g-gsznjj.md +0 -9
  133. package/.agent/memory/user/mnyf1riz-4yo5yz.md +0 -9
  134. package/.agent/memory/user/mnzuh4cw-zvee8w.md +0 -13
  135. package/.agent/memory/user/mnzvewyj-jl67cq.md +0 -9
  136. package/.agent/memory/user/mnzwh9xo-43ys3f.md +0 -9
  137. package/.agent/memory/user/mo0ycvpn-eebsxc.md +0 -9
  138. package/.agent/memory/user/mo2k8c8n-132r2u.md +0 -9
  139. package/.agent/memory/user/mo6y2dei-5cf537.md +0 -13
  140. package/.agent/memory/user/mo9xsdo6-8vylww.md +0 -13
  141. package/.agent/plugins/puppeteer-plugin/README.md +0 -147
  142. package/.agent/plugins/puppeteer-plugin/index.js +0 -1422
  143. package/.agent/plugins/puppeteer-plugin/package.json +0 -9
  144. package/.agent/rules/GEMINI.md +0 -273
  145. package/.agent/rules/allow-rule.md +0 -77
  146. package/.agent/rules/log-rule.md +0 -83
  147. package/.agent/rules/security-rule.md +0 -93
  148. package/.agent/scripts/auto_preview.py +0 -148
  149. package/.agent/scripts/checklist.py +0 -217
  150. package/.agent/scripts/session_manager.py +0 -120
  151. package/.agent/scripts/verify_all.py +0 -327
  152. package/.agent/skills/doc.md +0 -177
  153. package/.agent/skills/fk-poster/SKILL.md +0 -1129
  154. package/.agent/skills/fkbuilder/SKILL.md +0 -730
  155. package/.agent/skills/mmx-cli/SKILL.md +0 -431
  156. package/.agent/workflows/brainstorm.md +0 -113
  157. package/.agent/workflows/create.md +0 -59
  158. package/.agent/workflows/debug.md +0 -103
  159. package/.agent/workflows/deploy.md +0 -176
  160. package/.agent/workflows/enhance.md +0 -63
  161. package/.agent/workflows/orchestrate.md +0 -237
  162. package/.agent/workflows/plan.md +0 -89
  163. package/.agent/workflows/preview.md +0 -81
  164. package/.agent/workflows/simple-test.md +0 -42
  165. package/.agent/workflows/status.md +0 -86
  166. package/.agent/workflows/structured-orchestrate.md +0 -180
  167. package/.agent/workflows/test.md +0 -144
  168. package/.agent/workflows/ui-ux-pro-max.md +0 -296
@@ -0,0 +1,256 @@
1
+ const { z } = require('zod');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ module.exports = function (Plugin) {
6
+ return class MarkNativePlugin extends Plugin {
7
+ constructor(config = {}) {
8
+ super();
9
+ this.name = 'marknative';
10
+ this.version = '1.0.1';
11
+ this.description = 'Markdown 转图片插件 - 将 Markdown 转换为 PNG/SVG';
12
+ this.priority = 10;
13
+ this.marknative = null;
14
+ this.checked = false;
15
+ }
16
+
17
+ async _ensureMarkNative() {
18
+ if (this.checked) return;
19
+ this.checked = true;
20
+
21
+ this.marknative = await import('marknative');
22
+ }
23
+
24
+ tools = {
25
+ marknative_render: {
26
+ description: '将 Markdown 渲染为图片并保存到文件(返回文件路径)',
27
+ inputSchema: z.object({
28
+ markdown: z.string().describe('Markdown 内容'),
29
+ outputPath: z.string().optional().describe('输出文件路径(如 output.png),不提供则自动生成'),
30
+ format: z.enum(['png', 'svg']).optional().describe('输出格式:png 或 svg,默认 png'),
31
+ theme: z.string().optional().describe('主题:default, github, solarized, sepia, rose, dark, nord, dracula, ocean, forest'),
32
+ singlePage: z.boolean().optional().describe('是否渲染为单张图片(默认 false)'),
33
+ codeTheme: z.string().optional().describe('代码高亮主题(如 github-dark, nord 等)'),
34
+ }),
35
+ execute: async (args) => {
36
+ try {
37
+ await this._ensureMarkNative();
38
+
39
+ if (!this.marknative) {
40
+ return {
41
+ success: false,
42
+ error: 'marknative 未安装。请运行: cd .agent/plugins/marknative && npm install'
43
+ };
44
+ }
45
+
46
+ const { renderMarkdown } = this.marknative;
47
+
48
+ const format = args.format || 'png';
49
+ const options = {
50
+ format,
51
+ singlePage: args.singlePage || false
52
+ };
53
+
54
+ if (args.theme) options.theme = args.theme;
55
+ if (args.codeTheme) options.codeHighlighting = { theme: args.codeTheme };
56
+
57
+ const pages = await renderMarkdown(args.markdown, options);
58
+
59
+ if (pages.length === 0) {
60
+ return { success: false, error: '渲染失败,无输出' };
61
+ }
62
+
63
+ // 自动生成输出路径
64
+ let basePath = args.outputPath;
65
+ if (!basePath) {
66
+ const timestamp = Date.now().toString(36);
67
+ basePath = `output/markdown-${timestamp}.${format}`;
68
+ }
69
+
70
+ const dir = path.dirname(basePath);
71
+ if (dir && dir !== '.' && !fs.existsSync(dir)) {
72
+ fs.mkdirSync(dir, { recursive: true });
73
+ }
74
+
75
+ const files = [];
76
+ for (let i = 0; i < pages.length; i++) {
77
+ const page = pages[i];
78
+ const filePath = pages.length === 1
79
+ ? basePath
80
+ : basePath.replace(/(\.[^.]+)$/, `-${String(i + 1).padStart(2, '0')}$1`);
81
+
82
+ if (page.format === 'png') {
83
+ fs.writeFileSync(filePath, page.data);
84
+ } else {
85
+ fs.writeFileSync(filePath, page.data, 'utf-8');
86
+ }
87
+ files.push(filePath);
88
+ }
89
+
90
+ return {
91
+ success: true,
92
+ files,
93
+ pageCount: pages.length,
94
+ message: pages.length === 1
95
+ ? `图片已生成: ${files[0]}`
96
+ : `已生成 ${pages.length} 页图片: ${files.join(', ')}`
97
+ };
98
+ } catch (error) {
99
+ return { success: false, error: error.message };
100
+ }
101
+ },
102
+ },
103
+
104
+ marknative_render_to_file: {
105
+ description: '将 Markdown 渲染为图片并保存到文件',
106
+ inputSchema: z.object({
107
+ markdown: z.string().describe('Markdown 内容'),
108
+ outputPath: z.string().describe('输出文件路径(如 output.png)'),
109
+ format: z.enum(['png', 'svg']).optional().describe('输出格式,默认根据文件扩展名'),
110
+ theme: z.string().optional().describe('主题'),
111
+ codeTheme: z.string().optional().describe('代码高亮主题'),
112
+ }),
113
+ execute: async (args) => {
114
+ try {
115
+ await this._ensureMarkNative();
116
+
117
+ if (!this.marknative) {
118
+ return {
119
+ success: false,
120
+ error: 'marknative 未安装。请运行: cd .agent/plugins/marknative && npm install'
121
+ };
122
+ }
123
+
124
+ const { renderMarkdown } = this.marknative;
125
+
126
+ const ext = path.extname(args.outputPath).toLowerCase();
127
+ const format = args.format || (ext === '.svg' ? 'svg' : 'png');
128
+
129
+ const options = { format };
130
+ if (args.theme) options.theme = args.theme;
131
+ if (args.codeTheme) options.codeHighlighting = { theme: args.codeTheme };
132
+
133
+ const pages = await renderMarkdown(args.markdown, options);
134
+
135
+ const dir = path.dirname(args.outputPath);
136
+ if (dir && dir !== '.' && !fs.existsSync(dir)) {
137
+ fs.mkdirSync(dir, { recursive: true });
138
+ }
139
+
140
+ const files = [];
141
+ for (let i = 0; i < pages.length; i++) {
142
+ const page = pages[i];
143
+ const filePath = pages.length === 1
144
+ ? args.outputPath
145
+ : args.outputPath.replace(/(\.[^.]+)$/, `-${String(i + 1).padStart(2, '0')}$1`);
146
+
147
+ if (page.format === 'png') {
148
+ fs.writeFileSync(filePath, page.data);
149
+ } else {
150
+ fs.writeFileSync(filePath, page.data, 'utf-8');
151
+ }
152
+ files.push(filePath);
153
+ }
154
+
155
+ return {
156
+ success: true,
157
+ files,
158
+ pageCount: pages.length,
159
+ message: `已生成 ${pages.length} 页图片: ${files.join(', ')}`
160
+ };
161
+ } catch (error) {
162
+ return { success: false, error: error.message };
163
+ }
164
+ },
165
+ },
166
+
167
+ marknative_preview: {
168
+ description: '预览 Markdown 渲染效果(返回第一页 Base64)',
169
+ inputSchema: z.object({
170
+ markdown: z.string().describe('Markdown 内容'),
171
+ theme: z.string().optional().describe('主题'),
172
+ codeTheme: z.string().optional().describe('代码高亮主题'),
173
+ }),
174
+ execute: async (args) => {
175
+ try {
176
+ await this._ensureMarkNative();
177
+
178
+ if (!this.marknative) {
179
+ return {
180
+ success: false,
181
+ error: 'marknative 未安装。请运行: cd .agent/plugins/marknative && npm install'
182
+ };
183
+ }
184
+
185
+ const { renderMarkdown } = this.marknative;
186
+
187
+ const options = {
188
+ format: 'png',
189
+ singlePage: true
190
+ };
191
+
192
+ if (args.theme) options.theme = args.theme;
193
+ if (args.codeTheme) options.codeHighlighting = { theme: args.codeTheme };
194
+
195
+ const pages = await renderMarkdown(args.markdown, options);
196
+
197
+ if (pages.length === 0) {
198
+ return { success: false, error: '预览生成失败' };
199
+ }
200
+
201
+ return {
202
+ success: true,
203
+ preview: pages[0].data.toString('base64'),
204
+ format: 'png'
205
+ };
206
+ } catch (error) {
207
+ return { success: false, error: error.message };
208
+ }
209
+ },
210
+ },
211
+
212
+ marknative_get_themes: {
213
+ description: '获取所有可用的主题列表',
214
+ inputSchema: z.object({}),
215
+ execute: async () => {
216
+ return {
217
+ success: true,
218
+ themes: [
219
+ { name: 'default', description: '默认主题(浅色)' },
220
+ { name: 'github', description: 'GitHub 风格' },
221
+ { name: 'solarized', description: 'Solarized 风格' },
222
+ { name: 'sepia', description: '复古纸张风格' },
223
+ { name: 'rose', description: '玫瑰粉风格' },
224
+ { name: 'dark', description: '深色主题' },
225
+ { name: 'nord', description: 'Nord 风格' },
226
+ { name: 'dracula', description: 'Dracula 风格' },
227
+ { name: 'ocean', description: '海洋风格' },
228
+ { name: 'forest', description: '森林风格' }
229
+ ],
230
+ codeThemes: ['github-light', 'github-dark', 'nord', 'dracula', 'solarized-light', 'solarized-dark', 'monokai']
231
+ };
232
+ },
233
+ },
234
+
235
+ marknative_status: {
236
+ description: '检查 marknative 插件状态',
237
+ inputSchema: z.object({}),
238
+ execute: async () => {
239
+ await this._ensureMarkNative();
240
+
241
+ return {
242
+ success: true,
243
+ available: this.marknative !== null,
244
+ message: this.marknative ? 'marknative 已就绪' : 'marknative 未安装,请运行: cd .agent/plugins/marknative && npm install'
245
+ };
246
+ },
247
+ },
248
+ };
249
+
250
+ install(framework) {
251
+ return this;
252
+ }
253
+
254
+ uninstall(framework) {}
255
+ };
256
+ };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "marknative-plugin",
3
+ "version": "1.0.0",
4
+ "description": "Markdown 转图片插件 - 将 Markdown 转换为 PNG/SVG",
5
+ "main": "index.js",
6
+ "keywords": ["markdown", "png", "svg", "image", "render", "foliko", "plugin"],
7
+ "author": "",
8
+ "license": "MIT",
9
+ "dependencies": {
10
+ "marknative": "^0.3.1"
11
+ }
12
+ }
@@ -0,0 +1,99 @@
1
+ # .agent/plugins/test-plugin.py
2
+
3
+ PLUGIN = {
4
+ "name": "test-plugin",
5
+ "version": "1.0.0",
6
+ "description": "测试插件 - 提供基础测试功能"
7
+ }
8
+
9
+ TOOLS = [
10
+ {
11
+ "name": "hello",
12
+ "description": "问候测试",
13
+ "params": {"name": "string"}
14
+ },
15
+ {
16
+ "name": "add",
17
+ "description": "加法计算",
18
+ "params": {"a": "number", "b": "number"}
19
+ },
20
+ {
21
+ "name": "multiply",
22
+ "description": "乘法计算",
23
+ "params": {"a": "number", "b": "number"}
24
+ },
25
+ {
26
+ "name": "reverse_text",
27
+ "description": "反转文本",
28
+ "params": {"text": "string"}
29
+ },
30
+ {
31
+ "name": "palindrome_check",
32
+ "description": "回文检测",
33
+ "params": {"text": "string"}
34
+ },
35
+ {
36
+ "name": "get_info",
37
+ "description": "获取插件信息",
38
+ "params": {}
39
+ }
40
+ ]
41
+
42
+ # === 工具实现 ===
43
+
44
+ def hello(params):
45
+ """问候工具"""
46
+ name = params.get("name", "World")
47
+ return {"success": True, "result": f"Hello, {name}! 👋"}
48
+
49
+
50
+ def add(params):
51
+ """加法计算"""
52
+ a = params.get("a", 0)
53
+ b = params.get("b", 0)
54
+ result = a + b
55
+ return {"success": True, "result": result, "expression": f"{a} + {b} = {result}"}
56
+
57
+
58
+ def multiply(params):
59
+ """乘法计算"""
60
+ a = params.get("a", 0)
61
+ b = params.get("b", 0)
62
+ result = a * b
63
+ return {"success": True, "result": result, "expression": f"{a} × {b} = {result}"}
64
+
65
+
66
+ def reverse_text(params):
67
+ """反转文本"""
68
+ text = params.get("text", "")
69
+ reversed_text = text[::-1]
70
+ return {"success": True, "original": text, "reversed": reversed_text}
71
+
72
+
73
+ def palindrome_check(params):
74
+ """回文检测"""
75
+ import re
76
+ text = params.get("text", "")
77
+ # 清理:去除空格和标点,转小写
78
+ cleaned = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '', text).lower()
79
+ is_palindrome = cleaned == cleaned[::-1] and len(cleaned) > 0
80
+ return {
81
+ "success": True,
82
+ "text": text,
83
+ "is_palindrome": is_palindrome,
84
+ "result": "是回文 ✓" if is_palindrome else "不是回文 ✗"
85
+ }
86
+
87
+
88
+ def get_info(params):
89
+ """获取插件信息"""
90
+ return {
91
+ "success": True,
92
+ "result": {
93
+ "name": PLUGIN["name"],
94
+ "version": PLUGIN["version"],
95
+ "description": PLUGIN["description"],
96
+ "tool_count": len(TOOLS),
97
+ "tools": [tool["name"] for tool in TOOLS]
98
+ }
99
+ }
@@ -1,8 +1,14 @@
1
1
  {
2
- "weixin": {
3
- "enabled": true
4
- },
5
- "poster-plugin": {
6
- "enabled": true
2
+ "email": {
3
+ "enabled": true,
4
+ "smtp": {
5
+ "host": "smtp.gmail.com",
6
+ "port": 587,
7
+ "secure": false
8
+ },
9
+ "imap": {
10
+ "host": "imap.gmail.com",
11
+ "port": 993
12
+ }
7
13
  }
8
14
  }
@@ -0,0 +1,24 @@
1
+ """
2
+ 测试模块 - 2026-04-02 02:52:12
3
+ """
4
+
5
+ import unittest
6
+
7
+
8
+
9
+ class TestMath(unittest.TestCase):
10
+ """TestMath 测试类"""
11
+
12
+ def test_add(self):
13
+ """测试用例: test_add"""
14
+ # TODO: 实现测试逻辑
15
+ self.assertTrue(True)
16
+
17
+ def test_subtract(self):
18
+ """测试用例: test_subtract"""
19
+ # TODO: 实现测试逻辑
20
+ self.assertTrue(True)
21
+
22
+
23
+ if __name__ == "__main__":
24
+ unittest.main()