foliko 1.1.3 → 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.
- package/.agent/agents/code-assistant.json +14 -0
- package/.agent/agents/email-assistant.json +14 -0
- package/.agent/agents/file-assistant.json +15 -0
- package/.agent/agents/system-assistant.json +15 -0
- package/.agent/agents/web-assistant.json +12 -0
- package/.agent/data/ambient/goals.json +50 -0
- package/.agent/data/ambient/memories.json +7 -0
- package/.agent/data/default.json +3 -412
- package/.agent/data/plugins-state.json +174 -173
- package/.agent/data/scheduler/tasks.json +1 -0
- package/.agent/memory/core.md +1 -0
- package/.agent/memory/project/mnn93ogy-ypjn27.md +9 -0
- package/.agent/memory/project/mnn98fqy-5nhc1u.md +25 -0
- package/.agent/memory/reference/mnq3oenw-46haj6.md +63 -0
- package/.agent/memory/reference/mnq5qxm2-mjoooh.md +116 -0
- package/.agent/memory/user/mnm67t9m-x8rekk.md +9 -0
- package/.agent/memory/user/mnn5mmqh-w6aktx.md +11 -0
- package/.agent/memory/user/mnnbfhhn-dk1bd1.md +22 -0
- package/.agent/package.json +8 -0
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +89 -0
- package/.agent/plugins/daytona/index.js +377 -0
- package/.agent/plugins/daytona/package.json +12 -0
- package/.agent/plugins/marknative/README.md +134 -0
- package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/marknative/index.js +256 -0
- package/.agent/plugins/marknative/package.json +12 -0
- package/.agent/plugins/marknative/update-readme.js +134 -0
- package/.agent/plugins/poster-plugin/emojis/rocket.png +1 -0
- package/.agent/plugins/poster-plugin/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/poster-plugin/src/elements/text.js +3 -1
- package/.agent/plugins/poster-plugin/src/fonts.js +10 -0
- package/.agent/plugins/poster-plugin/yarn.lock +1007 -0
- package/.agent/plugins/system-info/index.js +387 -0
- package/.agent/plugins/system-info/package.json +4 -0
- package/.agent/plugins/system-info/test.js +40 -0
- package/.agent/plugins.json +11 -5
- package/.agent/python-scripts/test_sample.py +24 -0
- package/.agent/sessions/cli_default.json +1869 -691
- package/.agent/skills/agent-browser/SKILL.md +311 -0
- package/.agent/skills/agent-browser/TEST_PLAN.md +200 -0
- package/.agent/skills/sysinfo/SKILL.md +38 -0
- package/.agent/skills/sysinfo/system-info.sh +130 -0
- package/.agent/skills/workflow/SKILL.md +324 -0
- package/.agent/weixin.json +6 -0
- package/.agent/workflows/email-digest.json +50 -0
- package/.agent/workflows/file-backup.json +21 -0
- package/.agent/workflows/get-ip-notify.json +32 -0
- package/.agent/workflows/news-aggregator.json +93 -0
- package/.agent/workflows/news-dashboard-v2.json +94 -0
- package/.agent/workflows/notification-batch.json +32 -0
- package/.claude/settings.local.json +1 -20
- package/.env.example +56 -56
- package/README.md +441 -441
- package/cli/src/commands/chat.js +22 -13
- package/cli/src/ui/chat-ui.js +50 -37
- package/output/emoji-segoe-test-v2.png +0 -0
- package/output/emoji-segoe-test.png +0 -0
- package/output/emoji-test.png +0 -0
- package/output/emoji-windows-test.png +0 -0
- package/output/foliko-emoji-poster.png +0 -0
- package/output/foliko-muji-poster-final.png +0 -0
- package/output/foliko-muji-poster-v2.png +0 -0
- package/output/foliko-muji-poster.png +0 -0
- package/output/foliko-share.png +0 -0
- package/output/progress-circle-test.png +0 -0
- package/output/vb-agent-poster.png +0 -0
- package/package.json +1 -2
- package/plugins/default-plugins.js +4 -3
- package/plugins/extension-executor-plugin.js +12 -91
- package/plugins/file-system-plugin.js +19 -4
- package/plugins/memory-plugin.js +33 -4
- package/plugins/subagent-plugin.js +14 -37
- package/plugins/weixin-plugin.js +40 -168
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/skills/poster-guide/SKILL.md +669 -1426
- package/src/core/agent-chat.js +439 -269
- package/src/core/agent.js +3 -6
- package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
- package/.agent/ARCHITECTURE.md +0 -288
- package/.agent/agents/ambient-agent.md +0 -57
- package/.agent/agents/debugger.md +0 -55
- package/.agent/agents/email-assistant.md +0 -49
- package/.agent/agents/file-manager.md +0 -42
- package/.agent/agents/python-developer.md +0 -60
- package/.agent/agents/scheduler.md +0 -59
- package/.agent/agents/web-developer.md +0 -45
- package/.agent/data/puppeteer-sessions/undefined.json +0 -6
- package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
- package/.agent/mcp_config_updated.json +0 -12
- package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
- package/.agent/plugins/puppeteer-plugin/README.md +0 -147
- package/.agent/plugins/puppeteer-plugin/index.js +0 -1418
- package/.agent/plugins/puppeteer-plugin/package.json +0 -9
- package/.agent/rules/GEMINI.md +0 -273
- package/.agent/rules/allow-rule.md +0 -77
- package/.agent/rules/log-rule.md +0 -83
- package/.agent/rules/security-rule.md +0 -93
- package/.agent/scripts/auto_preview.py +0 -148
- package/.agent/scripts/checklist.py +0 -217
- package/.agent/scripts/session_manager.py +0 -120
- package/.agent/scripts/verify_all.py +0 -327
- package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +0 -11097
- package/.agent/skills/api-patterns/SKILL.md +0 -81
- package/.agent/skills/api-patterns/api-style.md +0 -42
- package/.agent/skills/api-patterns/auth.md +0 -24
- package/.agent/skills/api-patterns/documentation.md +0 -26
- package/.agent/skills/api-patterns/graphql.md +0 -41
- package/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/.agent/skills/api-patterns/response.md +0 -37
- package/.agent/skills/api-patterns/rest.md +0 -40
- package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
- package/.agent/skills/api-patterns/security-testing.md +0 -122
- package/.agent/skills/api-patterns/trpc.md +0 -41
- package/.agent/skills/api-patterns/versioning.md +0 -22
- package/.agent/skills/app-builder/SKILL.md +0 -75
- package/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/.agent/skills/app-builder/feature-building.md +0 -53
- package/.agent/skills/app-builder/project-detection.md +0 -34
- package/.agent/skills/app-builder/scaffolding.md +0 -118
- package/.agent/skills/app-builder/tech-stack.md +0 -40
- package/.agent/skills/app-builder/templates/SKILL.md +0 -39
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -122
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -122
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -169
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -134
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -119
- package/.agent/skills/architecture/SKILL.md +0 -55
- package/.agent/skills/architecture/context-discovery.md +0 -43
- package/.agent/skills/architecture/examples.md +0 -94
- package/.agent/skills/architecture/pattern-selection.md +0 -68
- package/.agent/skills/architecture/patterns-reference.md +0 -50
- package/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/.agent/skills/clean-code/SKILL.md +0 -201
- package/.agent/skills/doc.md +0 -177
- package/.agent/skills/frontend-design/SKILL.md +0 -418
- package/.agent/skills/frontend-design/animation-guide.md +0 -331
- package/.agent/skills/frontend-design/color-system.md +0 -311
- package/.agent/skills/frontend-design/decision-trees.md +0 -418
- package/.agent/skills/frontend-design/motion-graphics.md +0 -306
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
- package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
- package/.agent/skills/frontend-design/typography-system.md +0 -345
- package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
- package/.agent/skills/frontend-design/visual-effects.md +0 -383
- package/.agent/skills/i18n-localization/SKILL.md +0 -154
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
- package/.agent/skills/mcp-builder/SKILL.md +0 -176
- package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
- package/.agent/workflows/brainstorm.md +0 -113
- package/.agent/workflows/create.md +0 -59
- package/.agent/workflows/debug.md +0 -103
- package/.agent/workflows/deploy.md +0 -176
- package/.agent/workflows/enhance.md +0 -63
- package/.agent/workflows/orchestrate.md +0 -237
- package/.agent/workflows/plan.md +0 -89
- package/.agent/workflows/preview.md +0 -81
- package/.agent/workflows/simple-test.md +0 -42
- package/.agent/workflows/status.md +0 -86
- package/.agent/workflows/structured-orchestrate.md +0 -180
- package/.agent/workflows/test.md +0 -144
- package/.agent/workflows/ui-ux-pro-max.md +0 -296
- package/output/beef-love-poster.png +0 -0
- package/output/international-news-daily.png +0 -0
- 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
|
|
Binary file
|
|
@@ -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
|
|
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' },
|