foliko 1.1.2 → 1.1.4

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 (205) hide show
  1. package/.agent/agents/code-assistant.json +14 -0
  2. package/.agent/agents/email-assistant.json +14 -0
  3. package/.agent/agents/file-assistant.json +15 -0
  4. package/.agent/agents/system-assistant.json +15 -0
  5. package/.agent/agents/web-assistant.json +12 -0
  6. package/.agent/data/ambient/goals.json +50 -0
  7. package/.agent/data/ambient/memories.json +7 -0
  8. package/.agent/data/default.json +3 -412
  9. package/.agent/data/plugins-state.json +174 -173
  10. package/.agent/data/scheduler/tasks.json +1 -0
  11. package/.agent/memory/core.md +1 -0
  12. package/.agent/memory/project/mnn93ogy-ypjn27.md +9 -0
  13. package/.agent/memory/project/mnn98fqy-5nhc1u.md +25 -0
  14. package/.agent/memory/reference/mnq3oenw-46haj6.md +63 -0
  15. package/.agent/memory/reference/mnq5qxm2-mjoooh.md +116 -0
  16. package/.agent/memory/user/mnm67t9m-x8rekk.md +9 -0
  17. package/.agent/memory/user/mnn5mmqh-w6aktx.md +11 -0
  18. package/.agent/memory/user/mnnbfhhn-dk1bd1.md +22 -0
  19. package/.agent/package.json +8 -0
  20. package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
  21. package/.agent/plugins/daytona/README.md +89 -0
  22. package/.agent/plugins/daytona/index.js +377 -0
  23. package/.agent/plugins/daytona/package.json +12 -0
  24. package/.agent/plugins/marknative/README.md +134 -0
  25. package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
  26. package/.agent/plugins/marknative/index.js +256 -0
  27. package/.agent/plugins/marknative/package.json +12 -0
  28. package/.agent/plugins/marknative/update-readme.js +134 -0
  29. package/.agent/plugins/poster-plugin/emojis/rocket.png +1 -0
  30. package/.agent/plugins/poster-plugin/fonts/SegoeUI Emoji.ttf +0 -0
  31. package/.agent/plugins/poster-plugin/src/elements/text.js +3 -1
  32. package/.agent/plugins/poster-plugin/src/fonts.js +10 -0
  33. package/.agent/plugins/poster-plugin/yarn.lock +1007 -0
  34. package/.agent/plugins/system-info/index.js +387 -0
  35. package/.agent/plugins/system-info/package.json +4 -0
  36. package/.agent/plugins/system-info/test.js +40 -0
  37. package/.agent/plugins.json +11 -5
  38. package/.agent/python-scripts/test_sample.py +24 -0
  39. package/.agent/sessions/cli_default.json +1869 -691
  40. package/.agent/skills/agent-browser/SKILL.md +311 -0
  41. package/.agent/skills/agent-browser/TEST_PLAN.md +200 -0
  42. package/.agent/skills/sysinfo/SKILL.md +38 -0
  43. package/.agent/skills/sysinfo/system-info.sh +130 -0
  44. package/.agent/skills/workflow/SKILL.md +324 -0
  45. package/.agent/weixin.json +6 -0
  46. package/.agent/workflows/email-digest.json +50 -0
  47. package/.agent/workflows/file-backup.json +21 -0
  48. package/.agent/workflows/get-ip-notify.json +32 -0
  49. package/.agent/workflows/news-aggregator.json +93 -0
  50. package/.agent/workflows/news-dashboard-v2.json +94 -0
  51. package/.agent/workflows/notification-batch.json +32 -0
  52. package/.claude/settings.local.json +1 -20
  53. package/.env.example +56 -56
  54. package/README.md +441 -441
  55. package/cli/src/commands/chat.js +22 -13
  56. package/cli/src/ui/chat-ui.js +50 -37
  57. package/output/emoji-segoe-test-v2.png +0 -0
  58. package/output/emoji-segoe-test.png +0 -0
  59. package/output/emoji-test.png +0 -0
  60. package/output/emoji-windows-test.png +0 -0
  61. package/output/foliko-emoji-poster.png +0 -0
  62. package/output/foliko-muji-poster-final.png +0 -0
  63. package/output/foliko-muji-poster-v2.png +0 -0
  64. package/output/foliko-muji-poster.png +0 -0
  65. package/output/foliko-share.png +0 -0
  66. package/output/progress-circle-test.png +0 -0
  67. package/output/vb-agent-poster.png +0 -0
  68. package/package.json +1 -2
  69. package/plugins/default-plugins.js +4 -3
  70. package/plugins/extension-executor-plugin.js +12 -91
  71. package/plugins/file-system-plugin.js +19 -4
  72. package/plugins/memory-plugin.js +33 -4
  73. package/plugins/subagent-plugin.js +14 -37
  74. package/plugins/weixin-plugin.js +40 -168
  75. package/skills/find-skills/AGENTS.md +162 -162
  76. package/skills/find-skills/SKILL.md +133 -133
  77. package/skills/poster-guide/SKILL.md +669 -1426
  78. package/src/core/agent-chat.js +439 -269
  79. package/src/core/agent.js +3 -6
  80. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
  81. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
  82. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
  83. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
  84. package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
  85. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
  86. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
  87. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  88. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  89. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  90. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  91. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
  92. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  93. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  94. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
  95. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  96. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  97. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  98. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  99. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
  100. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
  101. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  102. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  103. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
  104. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  105. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  106. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
  107. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
  108. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
  109. package/.agent/ARCHITECTURE.md +0 -288
  110. package/.agent/agents/ambient-agent.md +0 -57
  111. package/.agent/agents/debugger.md +0 -55
  112. package/.agent/agents/email-assistant.md +0 -49
  113. package/.agent/agents/file-manager.md +0 -42
  114. package/.agent/agents/python-developer.md +0 -60
  115. package/.agent/agents/scheduler.md +0 -59
  116. package/.agent/agents/web-developer.md +0 -45
  117. package/.agent/data/puppeteer-sessions/undefined.json +0 -6
  118. package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
  119. package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
  120. package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
  121. package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
  122. package/.agent/mcp_config_updated.json +0 -12
  123. package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
  124. package/.agent/plugins/puppeteer-plugin/README.md +0 -147
  125. package/.agent/plugins/puppeteer-plugin/index.js +0 -1418
  126. package/.agent/plugins/puppeteer-plugin/package.json +0 -9
  127. package/.agent/rules/GEMINI.md +0 -273
  128. package/.agent/rules/allow-rule.md +0 -77
  129. package/.agent/rules/log-rule.md +0 -83
  130. package/.agent/rules/security-rule.md +0 -93
  131. package/.agent/scripts/auto_preview.py +0 -148
  132. package/.agent/scripts/checklist.py +0 -217
  133. package/.agent/scripts/session_manager.py +0 -120
  134. package/.agent/scripts/verify_all.py +0 -327
  135. package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +0 -11097
  136. package/.agent/skills/api-patterns/SKILL.md +0 -81
  137. package/.agent/skills/api-patterns/api-style.md +0 -42
  138. package/.agent/skills/api-patterns/auth.md +0 -24
  139. package/.agent/skills/api-patterns/documentation.md +0 -26
  140. package/.agent/skills/api-patterns/graphql.md +0 -41
  141. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  142. package/.agent/skills/api-patterns/response.md +0 -37
  143. package/.agent/skills/api-patterns/rest.md +0 -40
  144. package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
  145. package/.agent/skills/api-patterns/security-testing.md +0 -122
  146. package/.agent/skills/api-patterns/trpc.md +0 -41
  147. package/.agent/skills/api-patterns/versioning.md +0 -22
  148. package/.agent/skills/app-builder/SKILL.md +0 -75
  149. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  150. package/.agent/skills/app-builder/feature-building.md +0 -53
  151. package/.agent/skills/app-builder/project-detection.md +0 -34
  152. package/.agent/skills/app-builder/scaffolding.md +0 -118
  153. package/.agent/skills/app-builder/tech-stack.md +0 -40
  154. package/.agent/skills/app-builder/templates/SKILL.md +0 -39
  155. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
  156. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
  157. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
  158. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
  159. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
  160. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
  161. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
  162. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -122
  163. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -122
  164. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -169
  165. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -134
  166. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
  167. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -119
  168. package/.agent/skills/architecture/SKILL.md +0 -55
  169. package/.agent/skills/architecture/context-discovery.md +0 -43
  170. package/.agent/skills/architecture/examples.md +0 -94
  171. package/.agent/skills/architecture/pattern-selection.md +0 -68
  172. package/.agent/skills/architecture/patterns-reference.md +0 -50
  173. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  174. package/.agent/skills/clean-code/SKILL.md +0 -201
  175. package/.agent/skills/doc.md +0 -177
  176. package/.agent/skills/frontend-design/SKILL.md +0 -418
  177. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  178. package/.agent/skills/frontend-design/color-system.md +0 -311
  179. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  180. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  181. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
  182. package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
  183. package/.agent/skills/frontend-design/typography-system.md +0 -345
  184. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  185. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  186. package/.agent/skills/i18n-localization/SKILL.md +0 -154
  187. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
  188. package/.agent/skills/mcp-builder/SKILL.md +0 -176
  189. package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
  190. package/.agent/workflows/brainstorm.md +0 -113
  191. package/.agent/workflows/create.md +0 -59
  192. package/.agent/workflows/debug.md +0 -103
  193. package/.agent/workflows/deploy.md +0 -176
  194. package/.agent/workflows/enhance.md +0 -63
  195. package/.agent/workflows/orchestrate.md +0 -237
  196. package/.agent/workflows/plan.md +0 -89
  197. package/.agent/workflows/preview.md +0 -81
  198. package/.agent/workflows/simple-test.md +0 -42
  199. package/.agent/workflows/status.md +0 -86
  200. package/.agent/workflows/structured-orchestrate.md +0 -180
  201. package/.agent/workflows/test.md +0 -144
  202. package/.agent/workflows/ui-ux-pro-max.md +0 -296
  203. package/output/beef-love-poster.png +0 -0
  204. package/output/international-news-daily.png +0 -0
  205. package/poster-test-2.png +0 -0
@@ -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,134 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 更新仓库 README 的脚本
5
+ * 读取所有插件目录,生成插件列表表格
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const REPO_DIR = path.join(__dirname, '..', '..', '..');
12
+ const README_PATH = path.join(REPO_DIR, 'README.md');
13
+
14
+ // 插件信息
15
+ const plugins = [];
16
+
17
+ function getPluginInfo(pluginPath) {
18
+ const indexPath = path.join(pluginPath, 'index.js');
19
+ const readmePath = path.join(pluginPath, 'README.md');
20
+
21
+ let name = path.basename(pluginPath);
22
+ let description = '暂无描述';
23
+ let tools = [];
24
+
25
+ // 读取 README
26
+ if (fs.existsSync(readmePath)) {
27
+ const content = fs.readFileSync(readmePath, 'utf-8');
28
+ const descMatch = content.match(/^#\s+(.+)$/m);
29
+ if (descMatch) {
30
+ description = descMatch[1];
31
+ }
32
+ }
33
+
34
+ // 读取 index.js 获取工具列表
35
+ if (fs.existsSync(indexPath)) {
36
+ const content = fs.readFileSync(indexPath, 'utf-8');
37
+ const toolMatches = content.match(/^\s{2}(\w+):\s*\{\s*description:/gm);
38
+ if (toolMatches) {
39
+ tools = toolMatches.map(m => m.match(/\s{2}(\w+):/)[1]);
40
+ }
41
+ }
42
+
43
+ return { name, description, tools };
44
+ }
45
+
46
+ // 扫描插件目录
47
+ function scanPlugins() {
48
+ const pluginsDir = path.join(REPO_DIR);
49
+
50
+ if (!fs.existsSync(pluginsDir)) {
51
+ console.error('Plugins directory not found:', pluginsDir);
52
+ return;
53
+ }
54
+
55
+ const entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
56
+
57
+ for (const entry of entries) {
58
+ if (entry.isDirectory() && !entry.name.startsWith('.')) {
59
+ const pluginPath = path.join(pluginsDir, entry.name);
60
+ const indexPath = path.join(pluginPath, 'index.js');
61
+
62
+ if (fs.existsSync(indexPath)) {
63
+ const info = getPluginInfo(pluginPath);
64
+ plugins.push(info);
65
+ console.log(`Found plugin: ${info.name}`);
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ // 生成 README 内容
72
+ function generateReadme() {
73
+ const pluginTable = plugins.map(p => {
74
+ const toolList = p.tools.length > 0
75
+ ? p.tools.map(t => `| \`${t}\` | - |`).join('\n')
76
+ : '| - | - |';
77
+
78
+ return `## ${p.name.charAt(0).toUpperCase() + p.name.slice(1).replace(/-/g, ' ')}\n\n${p.description}\n\n### 工具\n\n| 工具 | 描述 |\n|------|------|\n${toolList}\n`;
79
+ }).join('\n---\n\n');
80
+
81
+ const pluginListTable = plugins.map(p => {
82
+ const name = p.name.charAt(0).toUpperCase() + p.name.slice(1).replace(/-/g, ' ');
83
+ return `| [\`${p.name}\`](#${p.name.toLowerCase()}) | ${p.description} | ✅ 可用 |`;
84
+ }).join('\n');
85
+
86
+ const pluginToolsTable = plugins.map(p => {
87
+ return `### ${p.name}\n\n| 工具 | 描述 |\n|------|------|\n${p.tools.map(t => `| \`${t}\` | - |`).join('\n')}\n`;
88
+ }).join('\n---\n\n');
89
+
90
+ return `# Foliko Plugins
91
+
92
+ Foliko Agent 框架的插件仓库,为 Foliko 提供扩展功能。
93
+
94
+ ## 插件列表
95
+
96
+ | 插件 | 描述 | 状态 |
97
+ |------|------|------|
98
+ ${pluginListTable}
99
+
100
+ ${pluginToolsTable}
101
+
102
+ ## 安装所有插件
103
+
104
+ \`\`\`bash
105
+ ${plugins.map(p => `folko plugin install ${p.name}`).join('\n')}
106
+ folko reload
107
+ \`\`\`
108
+
109
+ ## 许可证
110
+
111
+ Apache-2.0
112
+ `;
113
+ }
114
+
115
+ // 主函数
116
+ function main() {
117
+ console.log('Scanning plugins...');
118
+ scanPlugins();
119
+
120
+ console.log(`\nFound ${plugins.length} plugins`);
121
+
122
+ if (plugins.length === 0) {
123
+ console.log('No plugins found, skipping README update');
124
+ return;
125
+ }
126
+
127
+ console.log('\nGenerating README...');
128
+ const content = generateReadme();
129
+
130
+ fs.writeFileSync(README_PATH, content, 'utf-8');
131
+ console.log(`README updated: ${README_PATH}`);
132
+ }
133
+
134
+ main();
@@ -0,0 +1 @@
1
+ 404: Not Found
@@ -55,7 +55,9 @@ function getFontForText(requestedFont, text) {
55
55
  return (
56
56
  lower.includes('color emoji') || // Noto Color Emoji, Apple Color Emoji
57
57
  lower.includes('noto emoji') || // Noto Emoji
58
- lower.includes('segoe ui emoji') || // Windows emoji
58
+ lower.includes('segoe ui emoji') || // Windows Segoe UI Emoji
59
+ lower.includes('segoe ui symbol') || // Windows Segoe UI Symbol
60
+ lower.includes('segui') || // Windows Segoe UI 开头
59
61
  lower.includes('symbola') || // Symbola
60
62
  lower.includes('emoji') // 任何包含 emoji 的字体
61
63
  )
@@ -17,6 +17,7 @@ const emojiFontMappings = {
17
17
  'NotoEmoji-Regular': 'Noto Emoji',
18
18
  'Apple Color Emoji': 'Apple Color Emoji',
19
19
  'Segoe UI Emoji': 'Segoe UI Emoji',
20
+ 'SegoeUI Emoji': 'Segoe UI Emoji',
20
21
  'Symbola': 'Symbola',
21
22
  }
22
23
 
@@ -31,6 +32,11 @@ const systemFonts = [
31
32
  { path: 'C:\\Windows\\Fonts\\Times New Roman.ttf', family: 'Times New Roman' },
32
33
  { path: 'C:\\Windows\\Fonts\\Consolas.ttf', family: 'Consolas' },
33
34
  { path: 'C:\\Windows\\Fonts\\Georgia.ttf', family: 'Georgia' },
35
+ // Windows Emoji 字体
36
+ { path: 'C:\\Windows\\Fonts\\seguiemj.ttf', family: 'Segoe UI Emoji' },
37
+ { path: 'C:\\Windows\\Fonts\\seguisym.ttf', family: 'Segoe UI Symbol' },
38
+ { path: 'C:\\Windows\\Fonts\\seguisb.ttf', family: 'Segoe UI Symbol' },
39
+ { path: 'C:\\Windows\\Fonts\\EmojiOne Color.ttf', family: 'EmojiOne Color' },
34
40
  // Linux emoji 字体(扩展搜索路径)
35
41
  { path: '/usr/share/fonts/truetype/noto/NotoColorEmoji.ttf', family: 'Noto Color Emoji' },
36
42
  { path: '/usr/share/fonts/truetype/noto/NotoEmoji-Regular.ttf', family: 'Noto Emoji' },
@@ -160,6 +166,10 @@ function initFonts() {
160
166
 
161
167
  // 注册系统 emoji 字体(用于支持 emoji 渲染)
162
168
  const emojiFonts = [
169
+ // Windows Emoji 字体(优先)
170
+ { path: 'C:\\Windows\\Fonts\\seguiemj.ttf', family: 'Segoe UI Emoji' },
171
+ { path: 'C:\\Windows\\Fonts\\seguisym.ttf', family: 'Segoe UI Symbol' },
172
+ { path: 'C:\\Windows\\Fonts\\seguisb.ttf', family: 'Segoe UI Symbol' },
163
173
  // Linux
164
174
  { path: '/usr/share/fonts/truetype/noto/NotoColorEmoji.ttf', family: 'Noto Color Emoji' },
165
175
  { path: '/usr/share/fonts/opentype/noto/NotoColorEmoji.ttf', family: 'Noto Color Emoji' },