@chantezy/mcp-jingwei 1.0.0

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 (32) hide show
  1. package/README.md +69 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +34 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/skill-loader.d.ts +12 -0
  6. package/dist/skill-loader.js +95 -0
  7. package/dist/skill-loader.js.map +1 -0
  8. package/package.json +51 -0
  9. package/skills/doc-to-help-center/README.md +65 -0
  10. package/skills/doc-to-help-center/SKILL.md +115 -0
  11. package/skills/platform-analysis/README.md +70 -0
  12. package/skills/platform-analysis/SKILL.md +194 -0
  13. package/skills/product-discussion/README.md +109 -0
  14. package/skills/product-discussion/SKILL.md +220 -0
  15. package/skills/product-discussion/assets/doc_Information.png +0 -0
  16. package/skills/product-discussion/assets/doc_Recently.png +0 -0
  17. package/skills/product-discussion/assets/doc_collect.png +0 -0
  18. package/skills/product-discussion/assets/doc_dashboard_full.png +0 -0
  19. package/skills/product-discussion/assets/doc_list_page.png +0 -0
  20. package/skills/product-discussion/assets/doc_search.png +0 -0
  21. package/skills/product-discussion/assets/my_tasks.png +0 -0
  22. package/skills/product-discussion/assets/my_team.png +0 -0
  23. package/skills/product-discussion/assets/project_dashboard.png +0 -0
  24. package/skills/product-discussion/assets/task_Details.png +0 -0
  25. package/skills/product-discussion/assets/task_management_Form.png +0 -0
  26. package/skills/product-discussion/assets/task_management_Gantt.png +0 -0
  27. package/skills/product-discussion/assets/task_management_Kanban.png +0 -0
  28. package/skills/product-discussion/references/competitors-docs.md +278 -0
  29. package/skills/product-discussion/references/competitors-pm.md +398 -0
  30. package/skills/product-discussion/references/platform-spec.md +489 -0
  31. package/skills/version-update-description/README.md +68 -0
  32. package/skills/version-update-description/SKILL.md +101 -0
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @chantezy/mcp-jingwei
2
+
3
+ > 精卫平台(4399 内部工具)产品工作流技能集合,以 MCP Server 形式分发。
4
+ > 覆盖需求方案讨论、版本更新文案、竞品/平台拆解分析、需求文档转帮助中心四大场景。
5
+
6
+ ## 这是什么
7
+
8
+ 一个 MCP Server,把精卫平台相关的产品工作流技能打包发布到 npm。各 IDE / AI 客户端通过 `npx` 拉取最新版,调用三个工具即可按需加载技能内容:
9
+
10
+ | 工具 | 作用 |
11
+ |------|------|
12
+ | `list_skills` | 列出所有可用技能(名称 + 描述) |
13
+ | `get_skill` | 获取指定技能的完整内容(剥离 frontmatter 的正文) |
14
+ | `get_reference` | 获取指定技能的参考文档(仅部分技能有 `references/` 目录) |
15
+
16
+ ## 包含技能
17
+
18
+ | 技能 | 方向 | 说明 |
19
+ |------|------|------|
20
+ | `jingwei-product-discussion` | 需求方案讨论 | 文档系统 + 项目管理系统的需求分析、方案发散、竞品参考 |
21
+ | `jingwei-version-update-description` | 版本更新文案 | 按飞书风格生成两句话功能更新介绍 |
22
+ | `product-platform-analysis` | 平台/竞品分析 | 基于链接做产品结构拆解与竞品对标,输出 MD 报告 |
23
+ | `doc-to-help-center` | 文档转帮助中心 | 把 PRD 改写为面向普通用户的帮助中心教程 |
24
+
25
+ ## 在 IDE 中接入
26
+
27
+ 任何支持 MCP 的客户端,配置如下:
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "jingwei": {
33
+ "command": "npx",
34
+ "args": ["--yes", "@chantezy/mcp-jingwei@latest"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ - `--yes`:跳过 npx 首次安装确认
41
+ - `@latest`:强制拉最新版,避免本地缓存旧版本
42
+
43
+ 接入后重启客户端,在对话中输入「列出所有可用的精卫平台技能」即可验证。
44
+
45
+ ## 本地调试
46
+
47
+ 开发时直接调用本地构建产物,无需走 npm:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "jingwei": {
53
+ "command": "node",
54
+ "args": ["/absolute/path/to/mcp-server/dist/index.js"],
55
+ "env": { "DEBUG": "1" }
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ 启动后 stderr 会输出已加载技能数量,便于排查同步问题。
62
+
63
+ ## 更新流程
64
+
65
+ 技能内容随 `git push` 触发 GitHub Actions 自动同步、编译、发布到 npm(通过 Trusted Publisher / OIDC 无 token 发布)。各客户端下次启动时拉 `@latest` 即获取最新版。
66
+
67
+ ## License
68
+
69
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { listSkills, getSkill, getReference } from "./skill-loader.js";
6
+ const server = new McpServer({
7
+ name: "mcp-jingwei",
8
+ version: "1.0.0",
9
+ });
10
+ if (process.env.DEBUG) {
11
+ process.stderr.write(`[mcp-jingwei] 已加载 ${listSkills().length} 个技能\n`);
12
+ }
13
+ server.tool("list_skills", "列出所有可用的精卫平台技能(名称 + 描述),用于了解可加载哪些技能", {}, async () => {
14
+ const skills = listSkills();
15
+ const text = skills.length > 0
16
+ ? skills.map((s) => `- ${s.name}: ${s.description}`).join("\n")
17
+ : "暂无技能";
18
+ return { content: [{ type: "text", text }] };
19
+ });
20
+ server.tool("get_skill", "获取指定技能的完整内容(已剥离 frontmatter 的正文)。技能名称通过 list_skills 查询", { name: z.string().describe("技能名称,如 jingwei-product-discussion") }, async ({ name }) => {
21
+ const skill = getSkill(name);
22
+ return {
23
+ content: [{ type: "text", text: skill?.content || `未找到技能:${name}` }],
24
+ };
25
+ });
26
+ server.tool("get_reference", "获取指定技能的参考文档内容。仅部分技能有 references 目录(如 jingwei-product-discussion)", {
27
+ name: z.string().describe("技能名称"),
28
+ ref: z.string().describe("参考文档文件名(不带 .md 也可),如 platform-spec"),
29
+ }, async ({ name, ref }) => {
30
+ return { content: [{ type: "text", text: getReference(name, ref) }] };
31
+ });
32
+ const transport = new StdioServerTransport();
33
+ await server.connect(transport);
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEvE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,MAAM,QAAQ,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,IAAI,CACT,aAAa,EACb,oCAAoC,EACpC,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,IAAI,GACR,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/D,CAAC,CAAC,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,WAAW,EACX,wDAAwD,EACxD,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC,EAAE,EAClE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC;KAC9E,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,kEAAkE,EAClE;IACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;IACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC/D,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;IACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;AACjF,CAAC,CACF,CAAC;AAEF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface SkillMeta {
2
+ name: string;
3
+ description: string;
4
+ dir: string;
5
+ }
6
+ interface Skill extends SkillMeta {
7
+ content: string;
8
+ }
9
+ export declare function listSkills(): SkillMeta[];
10
+ export declare function getSkill(name: string): Skill | undefined;
11
+ export declare function getReference(name: string, ref: string): string;
12
+ export {};
@@ -0,0 +1,95 @@
1
+ import { readFileSync, readdirSync, existsSync } from "node:fs";
2
+ import { join, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ // dist/ 上一级即包根,skills/ 是包根下的同级目录
6
+ const SKILLS_DIR = join(__dirname, "..", "skills");
7
+ /**
8
+ * 行级解析 YAML frontmatter,只取 name / description 两个字段。
9
+ * 不引入 yaml 依赖;description 取第一个冒号之后的整段值并去引号。
10
+ */
11
+ function parseFrontmatter(md) {
12
+ const lines = md.split(/\r?\n/);
13
+ let name = "";
14
+ let description = "";
15
+ let bodyStart = 0;
16
+ if (lines[0]?.trim() === "---") {
17
+ let i = 1;
18
+ while (i < lines.length && lines[i].trim() !== "---") {
19
+ const line = lines[i];
20
+ const idx = line.indexOf(":");
21
+ if (idx > -1) {
22
+ const key = line.slice(0, idx).trim();
23
+ let value = line.slice(idx + 1).trim();
24
+ if ((value.startsWith('"') && value.endsWith('"')) ||
25
+ (value.startsWith("'") && value.endsWith("'"))) {
26
+ value = value.slice(1, -1);
27
+ }
28
+ if (key === "name")
29
+ name = value;
30
+ else if (key === "description")
31
+ description = value;
32
+ }
33
+ i++;
34
+ }
35
+ bodyStart = i + 1; // 跳过收尾的 ---
36
+ }
37
+ const body = lines.slice(bodyStart).join("\n").replace(/^\n+/, "");
38
+ return { name, description, body };
39
+ }
40
+ let cache = null;
41
+ function loadSkills() {
42
+ if (cache)
43
+ return cache;
44
+ if (!existsSync(SKILLS_DIR)) {
45
+ cache = [];
46
+ return cache;
47
+ }
48
+ const skills = [];
49
+ for (const entry of readdirSync(SKILLS_DIR, { withFileTypes: true })) {
50
+ if (!entry.isDirectory())
51
+ continue;
52
+ const skillMdPath = join(SKILLS_DIR, entry.name, "SKILL.md");
53
+ if (!existsSync(skillMdPath))
54
+ continue;
55
+ const md = readFileSync(skillMdPath, "utf-8");
56
+ const { name, description, body } = parseFrontmatter(md);
57
+ skills.push({
58
+ name: name || entry.name,
59
+ description: description || "",
60
+ dir: entry.name,
61
+ content: body,
62
+ });
63
+ }
64
+ cache = skills;
65
+ return skills;
66
+ }
67
+ export function listSkills() {
68
+ return loadSkills().map(({ name, description, dir }) => ({ name, description, dir }));
69
+ }
70
+ export function getSkill(name) {
71
+ const skills = loadSkills();
72
+ return skills.find((s) => s.name === name || s.dir === name);
73
+ }
74
+ export function getReference(name, ref) {
75
+ const skill = getSkill(name);
76
+ if (!skill)
77
+ return `未找到技能:${name}`;
78
+ const refName = ref.endsWith(".md") ? ref : `${ref}.md`;
79
+ const refPath = join(SKILLS_DIR, skill.dir, "references", refName);
80
+ if (existsSync(refPath)) {
81
+ return readFileSync(refPath, "utf-8");
82
+ }
83
+ // 未命中时列出该技能可用的参考文档,便于调用方自纠
84
+ const refsDir = join(SKILLS_DIR, skill.dir, "references");
85
+ if (existsSync(refsDir)) {
86
+ const files = readdirSync(refsDir, { withFileTypes: true })
87
+ .filter((f) => f.isFile() && f.name.endsWith(".md"))
88
+ .map((f) => f.name);
89
+ if (files.length > 0) {
90
+ return `未找到参考文档:${ref}\n该技能可用参考文档:\n${files.map((f) => `- ${f}`).join("\n")}`;
91
+ }
92
+ }
93
+ return `技能 ${name} 没有参考文档目录`;
94
+ }
95
+ //# sourceMappingURL=skill-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../src/skill-loader.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@chantezy/mcp-jingwei",
3
+ "version": "1.0.0",
4
+ "description": "精卫平台产品工作流技能集合 MCP Server(需求讨论 / 版本文案 / 竞品分析 / 文档转帮助中心)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "mcp-jingwei": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "skills"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "sync": "bash scripts/sync-skills.sh",
17
+ "prepublishOnly": "npm run sync && npm run build"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "skills",
23
+ "jingwei",
24
+ "product-design",
25
+ "ai-agent"
26
+ ],
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/chantezy/project-skills.git",
31
+ "directory": "jingwei/mcp-server"
32
+ },
33
+ "homepage": "https://github.com/chantezy/project-skills/tree/main/jingwei",
34
+ "bugs": {
35
+ "url": "https://github.com/chantezy/project-skills/issues"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.22.0",
42
+ "zod": "^3.24.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.0.0",
46
+ "typescript": "^5.8.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=22.14.0"
50
+ }
51
+ }
@@ -0,0 +1,65 @@
1
+ # doc-to-help-center
2
+
3
+ > 需求文档转帮助中心教程 Skill
4
+ > 把开发者视角的需求文档(PRD)改写为普通用户一看就懂的功能教程,输出 Markdown 文件。
5
+
6
+ ---
7
+
8
+ ## 这是什么
9
+
10
+ 一个部署在 Claude 上的 Skill:给它一份需求文档链接,它会剔除产品逻辑、研发实现、原型说明、评审备注等内部内容,只保留用户能用的功能说明、操作步骤、注意事项,输出一篇可直接放进帮助中心的 Markdown 教程。
11
+
12
+ **使用前提**:必须提供需求文档链接——没给链接时,Skill 会先向你索取,不会凭空撰写。
13
+
14
+ ---
15
+
16
+ ## 文件结构
17
+
18
+ ```
19
+ doc-to-help-center/
20
+ ├── README.md # 本文件
21
+ └── SKILL.md # Skill 主文件(硬性约束、执行流程、文档结构、语言规则、配图规则、自检清单)
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 快速开始
27
+
28
+ ```
29
+ 把这个需求文档整理成帮助中心教程:<文档链接>
30
+ 帮我将这份 PRD 转成面向用户的功能说明:<文档链接>
31
+ ```
32
+
33
+ ---
34
+
35
+ ## 转换规则速览
36
+
37
+ | 规则 | 说明 |
38
+ |------|------|
39
+ | 必须输入 | 需求文档链接,缺失时先索取 |
40
+ | 剔除内容 | 产品逻辑、研发实现、原型说明、评审备注、排期/负责人/版本记录 |
41
+ | 保留内容 | 功能说明、操作步骤、限制条件、注意事项 |
42
+ | 默认结构 | 功能简介 / 功能详情 / 操作流程 / 其他(可按内容自定义) |
43
+ | 语言风格 | 通俗简洁、零术语、以"你"称呼、正式友好中立 |
44
+ | 界面元素 | 按钮/菜单名用「」标注,与原文档命名一致 |
45
+ | 配图标记 | 需要截图处标记 `[图片]`,由你自行补充 |
46
+
47
+ ---
48
+
49
+ ## 输出效果示例
50
+
51
+ **输入**:一份关于"文档评论支持图片框选"的 PRD(含需求背景、技术方案、Figma 链接、二期规划)
52
+
53
+ **输出**:
54
+ ```markdown
55
+ # 评论图片框选
56
+
57
+ ## 功能简介
58
+ 在文档评论中插入图片时,你可以在图片上框选特定区域,让讨论精准定位到图片的具体位置。
59
+
60
+ ## 操作流程
61
+ 第一步:在文档评论框中点击「插入图片」,上传需要讨论的图片 [图片]
62
+ 第二步:在图片上拖动鼠标框选需要讨论的区域,添加评论内容后发送 [图片]
63
+ ```
64
+
65
+ ——原文中的需求背景、技术方案、评审痕迹全部剔除,只保留用户视角的操作指引。
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: doc-to-help-center
3
+ description: 需求文档转帮助中心教程 Skill,将开发者视角的需求文档(PRD)改写为面向普通用户的功能教程文档,输出 Markdown 文件。当用户提供需求文档/PRD 链接并说"转成帮助文档""写个用户教程""整理成帮助中心内容""把这个需求文档转成用户手册"时,必须触发本 Skill。即使用户只丢了一个文档链接并提到"帮助中心",也应立即按本 Skill 流程执行;用户未提供链接时,必须先向用户索取文档链接,不得凭空撰写。
4
+ ---
5
+
6
+ # 需求文档转帮助中心教程
7
+
8
+ 将研发/产品视角的需求文档(PRD),改写为**普通用户一看就懂**的帮助中心教程,输出 Markdown 文件。
9
+
10
+ ---
11
+
12
+ ## 硬性约束(不可违反)
13
+
14
+ 1. **文档链接是必须输入项**:用户未提供链接时,先向用户索取需求文档链接,不开始撰写;严禁凭空编造功能内容
15
+ 2. **只写文档里有的功能**:不补充文档中不存在的功能点;文档未覆盖但用户必然关心的信息(如入口位置),用合理推断写出并避免与原文冲突,不确定则不写
16
+ 3. **输出为 Markdown 格式**:分模块、分步骤、使用小标题
17
+
18
+ ---
19
+
20
+ ## 执行流程
21
+
22
+ 1. **确认链接** → 用户未提供则索取;提供后读取文档全文
23
+ 2. **识别功能范围** → 从 PRD 中提取"用户能做什么":功能点、操作入口、操作路径、限制条件
24
+ 3. **剔除内部内容** → 删除以下类型内容,一个字都不带入正文:
25
+ - 产品逻辑与设计动机("为什么做这个")
26
+ - 研发实现细节(技术方案、字段定义、接口、数据库)
27
+ - 原型说明("点击左上角第三个按钮的交互稿见第 X 页")
28
+ - 评审备注、排期、负责人、版本记录
29
+ - 内部术语、代号、黑话
30
+ 4. **重写为用户语言** → 按下方结构与风格撰写
31
+ 5. **输出 Markdown 文件** → 直接输出完整文档内容
32
+
33
+ ---
34
+
35
+ ## 文档结构
36
+
37
+ 默认按以下四个模块组织,模块下用小标题拆分;**可根据实际内容自定义模块**(如功能单一可合并,功能复杂可拆分):
38
+
39
+ ```markdown
40
+ # 功能名称
41
+
42
+ ## 功能简介
43
+ 一段话说明:这个功能是什么、能帮你做什么、适合什么场景使用。
44
+
45
+ ## 功能详情
46
+ 分点介绍功能的各项能力和规则(限制条件、可见范围、生效时机等)。
47
+
48
+ ## 操作流程
49
+ ### 第一步:……
50
+ 具体操作描述 [图片]
51
+
52
+ ### 第二步:……
53
+ 具体操作描述 [图片]
54
+
55
+ ## 其他
56
+ 注意事项、常见问题、相关功能链接等。
57
+ ```
58
+
59
+ **结构规则**:
60
+ - 「功能简介」只写一段,不超过三句话,先说"是什么"再说"能做什么"
61
+ - 「操作流程」每一步一个小标题,步骤内只写用户要做的动作,不混入功能介绍
62
+ - 步骤数量超过 5 步时,按操作阶段拆成多个小节(如"创建 XX""管理 XX")
63
+ - 「其他」无内容可写时整节省略,不留空标题
64
+
65
+ ---
66
+
67
+ ## 语言与风格规则
68
+
69
+ 1. **零专业术语**:不出现接口、字段、配置项、状态机等词汇;必须提及时换成用户语言("状态"→"当前进度")
70
+ 2. **以"你"称呼用户**,站在使用者立场描述操作:"你可以……""点击……后,即可……"
71
+ 3. **语气正式、友好、中立**:不使用感叹号、营销词(强大/便捷/智能)、口语化表达("搞定""超方便")
72
+ 4. **步骤描述标准化**:动作 + 位置 + 结果,例如"点击页面右上角的「新建文档」,在弹窗中输入标题后即可创建"
73
+ 5. **界面元素加引号**:按钮、菜单、入口名称用「」标注,与原文档中的实际命名保持一致
74
+ 6. **限制条件要明确**:权限要求、数量上限、生效范围等,必须写清楚,不能省略
75
+
76
+ ---
77
+
78
+ ## 配图标记规则
79
+
80
+ - 凡是**文字说不清的空间位置或多步界面操作**,在对应步骤末尾标记 `[图片]`
81
+ - 标记独占一行或紧跟步骤描述末尾,格式固定为 `[图片]`,由用户自行补充截图
82
+ - 纯概念说明(功能简介等)不标记配图
83
+ - 不描述图片内容(不写"[图片:新建按钮位置示意图]"),保持标记简洁统一
84
+
85
+ ---
86
+
87
+ ## 转换对照示例
88
+
89
+ **PRD 原文**:
90
+ > 需求背景:目前文档评论不支持图片,用户在评审设计稿时无法 pinpoint 问题区域,导致沟通效率低。技术方案:复用现有附件上传组件,新增 annotation 字段存储框选坐标。交互稿见 Figma 第 3 页。评审备注:二期考虑支持视频标注。
91
+
92
+ **转换后**:
93
+ > ## 评论图片框选
94
+ >
95
+ > ### 功能简介
96
+ > 在文档评论中插入图片时,你可以在图片上框选特定区域,让讨论精准定位到图片的具体位置。
97
+ >
98
+ > ### 操作流程
99
+ > 第一步:在文档评论框中点击「插入图片」,上传需要讨论的图片 [图片]
100
+ >
101
+ > 第二步:在图片上拖动鼠标框选需要讨论的区域,添加你的评论内容后发送 [图片]
102
+
103
+ (原文中的需求背景、技术方案、Figma 引用、二期规划全部剔除。)
104
+
105
+ ---
106
+
107
+ ## 输出前自检清单
108
+
109
+ - [ ] 是否已拿到用户提供的文档链接?(没有则先索取,未开始撰写)
110
+ - [ ] 正文是否零研发术语、零产品逻辑、零评审痕迹?
111
+ - [ ] 每个功能点是否都能在原文档中找到出处?
112
+ - [ ] 操作步骤是否都是"动作 + 位置 + 结果"?
113
+ - [ ] 界面元素名称是否用「」标注且与原文一致?
114
+ - [ ] 需要配图的步骤是否标记了 `[图片]`?
115
+ - [ ] 语气是否正式友好、无感叹号和营销词?
@@ -0,0 +1,70 @@
1
+ # product-platform-analysis
2
+
3
+ > 产品平台深度拆解与竞品分析 Skill
4
+ > 基于用户提供的链接与资料,对内容/工具平台做系统化产品结构拆解,或对竞品做对标分析,输出 Markdown 分析报告。
5
+
6
+ ---
7
+
8
+ ## 这是什么
9
+
10
+ 一个部署在 Claude 上的 Skill:给它一个平台官网链接(可选附帮助中心、文档、截图等资料),它会用浏览器工具实际探索站点结构,然后输出一份完整的产品分析报告。
11
+
12
+ **两种分析模式**,Skill 会自动判定:
13
+
14
+ | 模式 | 触发方式 | 输出章节 |
15
+ |------|---------|---------|
16
+ | **A. 平台拆解** | "分析一下这个平台""拆解产品结构" | 第一至六章 |
17
+ | **B. 竞品对标** | "做个竞品分析""对比我们和 XX""调研竞品功能" | 第一至七章(追加对标分析) |
18
+
19
+ **报告章节**:
20
+ 1. **产品概述**(定位 / 用户 / 价值 / 差异化,表格)
21
+ 2. **功能架构拆解**(一级功能 → 二级功能 → 功能树)
22
+ 3. **核心业务流程**(用户旅程表格 + 核心任务步骤)
23
+ 4. **信息架构分析**(IA 树 + 三条定性评价)
24
+ 5. **用户角色分析**(角色 × 目标 × 操作 × 权限)
25
+ 6. **总结:亮点与可借鉴点**(含信息来源与局限说明)
26
+ 7. **对标分析**(仅竞品模式:商业模式与定价 / 竞争力评估 / 机会与威胁 / 行动建议)
27
+
28
+ **核心原则**:只基于你提供的链接分析,不编造未观察到的功能;未验证的内容明确标注「未观察到」。
29
+
30
+ ---
31
+
32
+ ## 文件结构
33
+
34
+ ```
35
+ platform-analysis/
36
+ ├── README.md # 本文件
37
+ └── SKILL.md # Skill 主文件(分析模式、硬性约束、输入要求、执行流程、报告框架、风格规则)
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 快速开始
43
+
44
+ **平台拆解**:
45
+ ```
46
+ 帮我拆解一下 https://www.notion.so 的产品结构
47
+ 分析一下这个平台:https://xxx.com
48
+ ```
49
+
50
+ **竞品对标**:
51
+ ```
52
+ 做个 PingCode 的竞品分析,对标我们的项目管理方向:https://xxx.com
53
+ 这是我们竞品的官网链接,出一份竞品分析报告
54
+ 对比一下 https://xxx.com 和我们的文档系统
55
+ ```
56
+
57
+ **输入说明**:
58
+ - 官网地址为**必须项**,缺失会先向你索取
59
+ - 竞品模式下会追问**对比基准**(对标我们哪个产品方向),避免分析写成空泛的通用建议
60
+ - 参考资料(帮助中心/产品文档/截图)可选,提供越多分析越深入
61
+ - 部分功能需登录可见时,报告中会标注「未观察到」并列入信息来源与局限说明
62
+
63
+ ---
64
+
65
+ ## 适用场景
66
+
67
+ - **竞品结构调研**:快速摸清竞品功能版图、IA 设计、商业模式
68
+ - **竞品对标评估**:功能覆盖/易用性/协作/定价四维对比,输出机会与威胁
69
+ - **新平台选型评估**:系统化了解一个 SaaS 产品的能力边界
70
+ - **产品学习参考**:提取成熟平台的功能架构与流程设计作为借鉴