@ww_nero/skills 3.2.0 → 3.2.1

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.
@@ -0,0 +1,25 @@
1
+ 制作PPT的完整步骤如下(可根据当前实际状态,跳过部分已经完成的环节):
2
+
3
+ 1. **规划PPT内容**,存储到markdown文件中:
4
+ - 每页Slide的规划需要包含:内容、布局方式、插图(只有用户明确提出要求时才添加插图)
5
+ - 不同页面应尽可能使用不同的布局方式,避免过于单调,可适当使用图表来呈现信息,例如折线图、柱状图、饼状图等;各正文页面标题样式、背景和文字色调**必须保持一致**。
6
+ - 如果用户未明确提出要求,则页面默认比例为宽1280px、高720px,默认背景为弱渐变的浅灰蓝(#F2F4F7 → #FCFCFC),现代科技感、扁平化风格。
7
+ - 如果需要插入图片,则按照以下方式:
8
+ - 收集图片素材,优先使用用户提供的图片;如未提供,则使用图像生成工具生成合适的图片
9
+ - 将图片素材保存到`images`文件夹中,使用内容和宽高比例作为图片名称,例如`main_background_16_9.png`表示该图片是主背景图,宽高比为16:9;对于用户提供的图片素材,可调用工具解读图片内容
10
+
11
+ 2. **通过SVG代码实现Slides的排版**:
12
+ - 如需Image,统一使用`rect`或`circle`元素进行占位(必须符合图片宽高比例),占位元素应设置合适的位置,可添加浅色填充或边框以便预览时识别
13
+ - 如需Icon,优先使用Emoji,其次使用纯SVG代码的方式绘制
14
+ - 如需Chart,如折线图、柱状图等,应使用纯SVG代码的方式绘制,而不是使用图片占位元素
15
+ - 每页Slide的保存在一个独立HTML文件中,例如`slide_01.html`、`slide_02.html`等。
16
+
17
+ 3. **把SVG转成PPTX文件**:
18
+ - 参考snippet工具中提供的`svg_to_pptx`代码示例,编写临时的python脚本,把svg转化成可编辑的pptx文件,不要遗漏任何元素(例如线条、装饰等)
19
+ - 转化的方法是把svg代码转化成使用python创建pptx中可操作元素的代码,示例中的创建元素的工具函数均可以使用
20
+ - 同时对于每个slide务必创建单独的create_slide函数,例如`create_slide1`、`create_slide2`等
21
+ - **不要使用`BeautifulSoup`这种通用的解析元素的方式,而是逐个元素从svg代码转化为python创建元素的代码**
22
+ - 转换过程中,需要把图片占位元素替换成前面准备的图片素材
23
+ - 每个页面编写一个单独的python脚本进行转化,最后再写一个python脚本,把所有单页的pptx文件合并成一个。
24
+
25
+ **注意**:完成后**需要保留**规划文档、html页面文件和python转化脚本,方便进一步根据反馈进行修改
package/index.js CHANGED
@@ -82,7 +82,13 @@ const loadJson = (filename) => {
82
82
  };
83
83
 
84
84
  const SNIPPETS = loadJson('snippets.json');
85
- const GUIDES = loadJson('guide.json');
85
+
86
+ const loadText = (filename) => {
87
+ const filePath = path.join(ASSETS_ROOT, filename);
88
+ return fs.readFileSync(filePath, 'utf8');
89
+ };
90
+
91
+ const PPT_PROMPT = loadText('ppt_prompt.txt');
86
92
 
87
93
  const buildSnippet = (title, workingDirectory) => {
88
94
  const entry = SNIPPETS[title];
@@ -109,19 +115,6 @@ const buildSnippet = (title, workingDirectory) => {
109
115
  return lines.join('\n');
110
116
  };
111
117
 
112
- const buildGuide = (title) => {
113
- const entry = GUIDES[title];
114
- if (!entry) {
115
- const supported = Object.keys(GUIDES).join(', ');
116
- throw new Error(`title 仅支持: ${supported}`);
117
- }
118
-
119
- const lines = [];
120
- lines.push(`【${entry.title}】技能指导`);
121
- lines.push(entry.content);
122
-
123
- return lines.join('\n');
124
- };
125
118
 
126
119
  const listTools = () => ({
127
120
  tools: [
@@ -133,7 +126,7 @@ const listTools = () => ({
133
126
  properties: {
134
127
  working_directory: {
135
128
  type: 'string',
136
- description: '工作目录的绝对路径,生成的脚本文件将保存到此目录'
129
+ description: '工作目录的绝对路径,示例脚本文件将保存到此目录'
137
130
  },
138
131
  title: {
139
132
  type: 'string',
@@ -145,24 +138,18 @@ const listTools = () => ({
145
138
  }
146
139
  },
147
140
  {
148
- name: 'guide',
149
- description: '返回技能指导说明',
141
+ name: 'make_ppt',
142
+ description: '制作PPT的全流程指导说明及注意事项',
150
143
  inputSchema: {
151
144
  type: 'object',
152
- properties: {
153
- title: {
154
- type: 'string',
155
- description: '技能类型,可选: convert_doc_types | make_ppt',
156
- enum: Object.keys(GUIDES)
157
- }
158
- },
159
- required: ['title']
145
+ properties: {},
146
+ required: []
160
147
  }
161
148
  }
162
149
  ]
163
150
  });
164
151
 
165
- const server = new Server({ name: 'skills', version: '3.2.0' }, { capabilities: { tools: {} } });
152
+ const server = new Server({ name: 'skills', version: '3.2.1' }, { capabilities: { tools: {} } });
166
153
 
167
154
  server.setRequestHandler(ListToolsRequestSchema, async () => listTools());
168
155
 
@@ -179,10 +166,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
179
166
  return { content: [{ type: 'text', text: result }] };
180
167
  }
181
168
 
182
- if (name === 'guide') {
183
- const title = args?.title;
184
- const payload = buildGuide(title);
185
- return { content: [{ type: 'text', text: payload }] };
169
+ if (name === 'make_ppt') {
170
+ return { content: [{ type: 'text', text: PPT_PROMPT }] };
186
171
  }
187
172
 
188
173
  return { content: [{ type: 'text', text: `未知工具: ${name}` }], isError: true };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ww_nero/skills",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "MCP server that returns Python reference snippets and skill guides",
5
5
  "main": "index.js",
6
6
  "bin": {
package/assets/guide.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "convert_doc_types": {
3
- "title": "转化文档类型",
4
- "content": "执行文档类型转化任务(如 PPTX、PDF、DOCX、HTML、PNG 等格式互转)时,可参考以下方法:\n\n## 方法一:使用命令行工具(推荐用于简单场景)\n\n以下工具均已安装,可直接在终端调用:\n\n- **LibreOffice (soffice)**:支持 Office 文档互转\n - PPTX → PDF: `soffice --headless --convert-to pdf input.pptx --outdir ./output`\n - DOCX → PDF: `soffice --headless --convert-to pdf input.docx --outdir ./output`\n - XLSX → PDF: `soffice --headless --convert-to pdf input.xlsx --outdir ./output`\n\n- **Pandoc**:支持多种文档格式转换\n - Markdown → DOCX: `pandoc input.md -o output.docx`\n - Markdown → PDF(中文): `pandoc input.md -o output.pdf --pdf-engine=xelatex -V CJKmainfont=\"Microsoft YaHei\"`\n - HTML → Markdown: `pandoc input.html -o output.md`\n\n- **LaTeX (pdflatex/xelatex)**:用于高质量 PDF 生成\n - TEX → PDF: `xelatex input.tex`\n\n## 方法二:编写临时 Python 脚本(推荐用于复杂场景)\n\n参考 `snippet` 工具中提供的转化脚本示例(已验证正确性),编写临时 Python 脚本:\n\n| 转化类型 | snippet 名称 | 说明 |\n|---------|-------------|------|\n| HTML → PNG | `html_to_png` | 使用 Playwright 渲染并截图 |\n| PDF → PNG | `pdf_to_png` | 使用 pdf2image 分页转换 |\n| PPTX → PNG | `pptx_to_png` | 使用 LibreOffice + pdf2image |\n| SVG → PPTX | `svg_to_pptx` | 转化为可编辑的 PPTX 元素 |\n| STEP → STL | `step_to_stl` | 使用 pythonocc-core 转换 |\n| 合并 STL | `combine_stls` | 使用 gmsh 合并多个 STL |\n\n调用示例:使用 `snippet` 工具获取参考代码,如 `snippet({ title: \"pdf_to_png\" })`\n\n## 解读 PPTX 或 PDF 文档\n\n当用户需要解读 PPTX 或 PDF 文档内容时:\n1. 编写临时 Python 脚本,将 PPTX/PDF 转化为 PNG 图片\n2. 对生成的图片进行视觉分析或内容解读\n3. 完成后删除临时脚本和中间文件\n\n## 注意事项\n\n- 临时脚本执行完成后应删除,除非用户明确要求保留\n- Python 环境已全局安装 `playwright`、`pdf2image`、`python-pptx`、`Pillow`、`pythonocc-core`、`gmsh` 等常用库\n- 如需其他库,可使用 `pip install` 安装"
5
- },
6
- "make_ppt": {
7
- "title": "制作PPT",
8
- "content": "制作PPT的完整步骤如下(可根据当前实际状态,跳过部分已经完成的环节):\n\n1. **规划PPT内容**,存储到markdown文件中:\n - 每页Slide的规划需要包含:内容、布局方式、插图(只有用户明确提出要求时才添加插图)\n - 不同页面应尽可能使用不同的布局方式,避免过于单调,可适当使用图表来呈现信息,例如折线图、柱状图、饼状图等;各正文页面标题样式、背景和文字色调**必须保持一致**。\n - 如果用户未明确提出要求,则页面默认比例为宽1280px、高720px,默认背景为弱渐变的浅灰蓝(#F2F4F7 → #FCFCFC),现代科技感、扁平化风格。\n - 如果需要插入图片,则按照以下方式:\n - 收集图片素材,优先使用用户提供的图片;如未提供,则使用图像生成工具生成合适的图片\n - 将图片素材保存到`images`文件夹中,使用内容和宽高比例作为图片名称,例如`main_background_16_9.png`表示该图片是主背景图,宽高比为16:9;对于用户提供的图片素材,可调用工具解读图片内容\n\n2. **通过SVG代码实现Slides的排版**:\n - 如需Image,统一使用`rect`或`circle`元素进行占位(必须符合图片宽高比例),占位元素应设置合适的位置,可添加浅色填充或边框以便预览时识别\n - 如需Icon,优先使用Emoji,其次使用纯SVG代码的方式绘制\n - 如需Chart,如折线图、柱状图等,应使用纯SVG代码的方式绘制,而不是使用图片占位元素\n - 每页Slide的保存在一个独立HTML文件中,例如`slide_01.html`、`slide_02.html`等。\n\n3. **把SVG转成PPTX文件**:\n - 参考snippet工具中提供的`svg_to_pptx`代码示例,编写临时的python脚本,把svg转化成可编辑的pptx文件,不要遗漏任何元素(例如线条、装饰等)\n - 转化的方法是把svg代码转化成使用python创建pptx中可操作元素的代码,示例中的创建元素的工具函数均可以使用\n - 同时对于每个slide务必创建单独的create_slide函数,例如`create_slide1`、`create_slide2`等\n - **不要使用`BeautifulSoup`这种通用的解析元素的方式,而是逐个元素从svg代码转化为python创建元素的代码**\n - 转换过程中,需要把图片占位元素替换成前面准备的图片素材\n - 每个页面编写一个单独的python脚本进行转化,最后再写一个python脚本,把所有单页的pptx文件合并成一个。\n\n**注意**:完成后**需要保留**规划文档、html页面文件和python转化脚本,方便进一步根据反馈进行修改"
9
- }
10
- }