@page.su/ai-blog-cli 0.1.0-beta.4 → 0.1.0-beta.5

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 (86) hide show
  1. package/dist/cli.js +2 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/skills.d.ts.map +1 -1
  4. package/dist/commands/skills.js +44 -11
  5. package/dist/commands/skills.js.map +1 -1
  6. package/dist/commands/syntax.d.ts +4 -0
  7. package/dist/commands/syntax.d.ts.map +1 -0
  8. package/dist/commands/syntax.js +29 -0
  9. package/dist/commands/syntax.js.map +1 -0
  10. package/package.json +4 -3
  11. package/dist/index.d.ts +0 -3
  12. package/dist/index.d.ts.map +0 -1
  13. package/dist/index.js +0 -100
  14. package/dist/index.js.map +0 -1
  15. package/dist/prompts/index.d.ts +0 -9
  16. package/dist/prompts/index.d.ts.map +0 -1
  17. package/dist/prompts/index.js +0 -178
  18. package/dist/prompts/index.js.map +0 -1
  19. package/dist/resources/syntax-spec.d.ts +0 -23
  20. package/dist/resources/syntax-spec.d.ts.map +0 -1
  21. package/dist/resources/syntax-spec.js +0 -105
  22. package/dist/resources/syntax-spec.js.map +0 -1
  23. package/dist/resources/syntax-spec.test.d.ts +0 -2
  24. package/dist/resources/syntax-spec.test.d.ts.map +0 -1
  25. package/dist/resources/syntax-spec.test.js +0 -47
  26. package/dist/resources/syntax-spec.test.js.map +0 -1
  27. package/dist/tools/build.d.ts +0 -13
  28. package/dist/tools/build.d.ts.map +0 -1
  29. package/dist/tools/build.js +0 -181
  30. package/dist/tools/build.js.map +0 -1
  31. package/dist/tools/code-repos.d.ts +0 -5
  32. package/dist/tools/code-repos.d.ts.map +0 -1
  33. package/dist/tools/code-repos.js +0 -149
  34. package/dist/tools/code-repos.js.map +0 -1
  35. package/dist/tools/comments.d.ts +0 -12
  36. package/dist/tools/comments.d.ts.map +0 -1
  37. package/dist/tools/comments.js +0 -87
  38. package/dist/tools/comments.js.map +0 -1
  39. package/dist/tools/demos.d.ts +0 -5
  40. package/dist/tools/demos.d.ts.map +0 -1
  41. package/dist/tools/demos.js +0 -98
  42. package/dist/tools/demos.js.map +0 -1
  43. package/dist/tools/glossary.d.ts +0 -4
  44. package/dist/tools/glossary.d.ts.map +0 -1
  45. package/dist/tools/glossary.js +0 -139
  46. package/dist/tools/glossary.js.map +0 -1
  47. package/dist/tools/helpers.d.ts +0 -44
  48. package/dist/tools/helpers.d.ts.map +0 -1
  49. package/dist/tools/helpers.js +0 -65
  50. package/dist/tools/helpers.js.map +0 -1
  51. package/dist/tools/knowledge.d.ts +0 -4
  52. package/dist/tools/knowledge.d.ts.map +0 -1
  53. package/dist/tools/knowledge.js +0 -140
  54. package/dist/tools/knowledge.js.map +0 -1
  55. package/dist/tools/math-concepts.d.ts +0 -4
  56. package/dist/tools/math-concepts.d.ts.map +0 -1
  57. package/dist/tools/math-concepts.js +0 -158
  58. package/dist/tools/math-concepts.js.map +0 -1
  59. package/dist/tools/posts.d.ts +0 -35
  60. package/dist/tools/posts.d.ts.map +0 -1
  61. package/dist/tools/posts.js +0 -278
  62. package/dist/tools/posts.js.map +0 -1
  63. package/dist/tools/scout.d.ts +0 -10
  64. package/dist/tools/scout.d.ts.map +0 -1
  65. package/dist/tools/scout.js +0 -111
  66. package/dist/tools/scout.js.map +0 -1
  67. package/dist/tools/series.d.ts +0 -12
  68. package/dist/tools/series.d.ts.map +0 -1
  69. package/dist/tools/series.js +0 -120
  70. package/dist/tools/series.js.map +0 -1
  71. package/dist/tools/syntax-capabilities.d.ts +0 -15
  72. package/dist/tools/syntax-capabilities.d.ts.map +0 -1
  73. package/dist/tools/syntax-capabilities.js +0 -859
  74. package/dist/tools/syntax-capabilities.js.map +0 -1
  75. package/dist/tools/taxonomy.d.ts +0 -4
  76. package/dist/tools/taxonomy.d.ts.map +0 -1
  77. package/dist/tools/taxonomy.js +0 -73
  78. package/dist/tools/taxonomy.js.map +0 -1
  79. package/dist/tools/uploads.d.ts +0 -15
  80. package/dist/tools/uploads.d.ts.map +0 -1
  81. package/dist/tools/uploads.js +0 -56
  82. package/dist/tools/uploads.js.map +0 -1
  83. package/dist/tools/workflows.d.ts +0 -9
  84. package/dist/tools/workflows.d.ts.map +0 -1
  85. package/dist/tools/workflows.js +0 -249
  86. package/dist/tools/workflows.js.map +0 -1
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=syntax-spec.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syntax-spec.test.d.ts","sourceRoot":"","sources":["../../src/resources/syntax-spec.test.ts"],"names":[],"mappings":""}
@@ -1,47 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { SYNTAX_SPEC_SECTIONS_FOR_TEST } from "./syntax-spec.js";
3
- /**
4
- * 验证 syntax-spec resource 列表:
5
- * - 共 13 条(与 spec 文档章节一一对应)
6
- * - URI 形如 mcp://syntax-spec/<section>
7
- * - section slug 在 ai-blog 后端的 SECTION_HEADING_MAP 范围内
8
- *
9
- * 这里不做"读真实文档"的端到端测试(属于 P1.5 集成测试范畴),
10
- * 仅做静态契约校验,确保两端 section 定义不漂移。
11
- */
12
- const EXPECTED_SLUGS = [
13
- "overview",
14
- "frontmatter",
15
- "callout",
16
- "mermaid",
17
- "live-demo",
18
- "math",
19
- "image-attributes",
20
- "image-gallery",
21
- "image-whitelist",
22
- "url-whitelist",
23
- "footnote",
24
- "site-post-reference",
25
- "checklist",
26
- ];
27
- describe("SYNTAX_SPEC_SECTIONS_FOR_TEST", () => {
28
- it("正好 13 个章节", () => {
29
- expect(SYNTAX_SPEC_SECTIONS_FOR_TEST).toHaveLength(13);
30
- });
31
- it("section slug 与后端 SECTION_HEADING_MAP 完全一致", () => {
32
- const slugs = SYNTAX_SPEC_SECTIONS_FOR_TEST.map((section) => section.section);
33
- expect(slugs.sort()).toEqual([...EXPECTED_SLUGS].sort());
34
- });
35
- it("URI 形如 mcp://syntax-spec/<section>", () => {
36
- for (const section of SYNTAX_SPEC_SECTIONS_FOR_TEST) {
37
- expect(section.uri).toBe(`mcp://syntax-spec/${section.section}`);
38
- }
39
- });
40
- it("name / description 都非空", () => {
41
- for (const section of SYNTAX_SPEC_SECTIONS_FOR_TEST) {
42
- expect(section.name.length).toBeGreaterThan(0);
43
- expect(section.description.length).toBeGreaterThan(0);
44
- }
45
- });
46
- });
47
- //# sourceMappingURL=syntax-spec.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syntax-spec.test.js","sourceRoot":"","sources":["../../src/resources/syntax-spec.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;;;;;;;GAQG;AAEH,MAAM,cAAc,GAAG;IACrB,UAAU;IACV,aAAa;IACb,SAAS;IACT,SAAS;IACT,WAAW;IACX,MAAM;IACN,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,eAAe;IACf,UAAU;IACV,qBAAqB;IACrB,WAAW;CACZ,CAAC;AAEF,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACnB,MAAM,CAAC,6BAA6B,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,KAAK,GAAG,6BAA6B,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9E,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,KAAK,MAAM,OAAO,IAAI,6BAA6B,EAAE,CAAC;YACpD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,KAAK,MAAM,OAAO,IAAI,6BAA6B,EAAE,CAAC;YACpD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,13 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApiClient } from "../api-client.js";
3
- /**
4
- * 高级语法构造工具:post.build_frontmatter / build_live_demo / build_image
5
- *
6
- * 设计要点:
7
- * - mcp-server **不直接 import** ai-blog 项目里的 ts 文件(避免路径耦合 + 打包难题)
8
- * - 全部通过 HTTP 调用 ai-blog 后端的 `/api/mcp/build/*` 端点,复用真正的
9
- * `buildLiveDemoBlockText` / `serializeImageAttributes` 等函数
10
- * - 工具返回的字符串是"可以原样写进文章"的 markdown 片段
11
- */
12
- export declare function registerBuildTools(server: McpServer, api: ApiClient): void;
13
- //# sourceMappingURL=build.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/tools/build.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAyN1E"}
@@ -1,181 +0,0 @@
1
- import { z } from "zod";
2
- import { toolReplyHelpers } from "./posts.js";
3
- /**
4
- * 高级语法构造工具:post.build_frontmatter / build_live_demo / build_image
5
- *
6
- * 设计要点:
7
- * - mcp-server **不直接 import** ai-blog 项目里的 ts 文件(避免路径耦合 + 打包难题)
8
- * - 全部通过 HTTP 调用 ai-blog 后端的 `/api/mcp/build/*` 端点,复用真正的
9
- * `buildLiveDemoBlockText` / `serializeImageAttributes` 等函数
10
- * - 工具返回的字符串是"可以原样写进文章"的 markdown 片段
11
- */
12
- export function registerBuildTools(server, api) {
13
- // ─── post.build_frontmatter ────────────────────────────────────────────
14
- server.registerTool("post.build_frontmatter", {
15
- title: "Build frontmatter block",
16
- description: "把字段拼装成合法的 YAML frontmatter(含起止 ---)。字段顺序与编辑器 MARKDOWN_METADATA_FIELDS 一致。返回字符串可直接拼到文章正文最前面。",
17
- inputSchema: {
18
- title: z.string().min(1),
19
- slug: z.string().optional(),
20
- excerpt: z.string().optional(),
21
- status: z.enum(["draft", "published"]),
22
- publishedAt: z.string().describe("ISO 字符串").optional(),
23
- coverImage: z.string().optional(),
24
- tags: z.array(z.string()).optional(),
25
- seoTitle: z.string().optional(),
26
- seoDescription: z.string().optional(),
27
- canonicalUrl: z.string().optional(),
28
- },
29
- }, async (args) => toolReplyHelpers.safe(() => api.post("/api/mcp/build/frontmatter", args)));
30
- // ─── post.build_live_demo ──────────────────────────────────────────────
31
- server.registerTool("post.build_live_demo", {
32
- title: "Build live-demo code block",
33
- description: "构造一段合法的 ```live-demo 代码块,包含 fence meta(title / tailwind / cdn)和多文件 @file 标记。直接调用项目内 buildLiveDemoBlockText,输出可直接写入文章。",
34
- inputSchema: {
35
- title: z.string().describe("代码块右上角显示的标题"),
36
- files: z
37
- .array(z.object({
38
- name: z.string().describe("文件名,含扩展名,如 index.html / app.tsx"),
39
- content: z.string().describe("文件内容;保留原样缩进与换行"),
40
- }))
41
- .min(1),
42
- tailwind: z.boolean().describe("是否在 iframe 内启用 Tailwind Play CDN").optional(),
43
- cdn: z
44
- .array(z.string())
45
- .describe("外部 CDN URL(必须 https://),按顺序注入")
46
- .optional(),
47
- height: z
48
- .number()
49
- .int()
50
- .min(80)
51
- .max(720)
52
- .describe("iframe 初始高度(像素),避免内容加载后页面跳动。范围 80-720")
53
- .optional(),
54
- },
55
- }, async (args) => toolReplyHelpers.safe(() => api.post("/api/mcp/build/live-demo", args)));
56
- // ─── post.build_reference ──────────────────────────────────────────────
57
- server.registerTool("post.build_reference", {
58
- title: "Build reference (```ref) block",
59
- description: "构造一段合法的 ```ref 代码块,用于定义结构化参考文献 / 引用(论文 / 文档 / 仓库 / 视频等)。" +
60
- "正文用 [ref:key] 行内标记引用它,渲染成可 hover 的上标角标 + 文末参考文献区。" +
61
- "直接调用项目内 buildReferenceBlockText,输出可直接写入文章。引用外部资料首选此工具,体验优于 GFM 脚注。",
62
- inputSchema: {
63
- key: z
64
- .string()
65
- .describe("引用唯一标识,仅字母/数字/连字符/下划线;正文用 [ref:key] 引用它"),
66
- title: z.string().describe("引用资料标题(必填)"),
67
- authors: z.string().describe("作者 / 团队,如 'Vaswani et al.'").optional(),
68
- source: z.string().describe("出处 / venue / 站点名,如 'NeurIPS 2017'").optional(),
69
- url: z.string().describe("原文链接").optional(),
70
- type: z
71
- .enum(["paper", "blog", "doc", "repo", "video", "spec", "link"])
72
- .describe("引用类型,决定图标与标签;默认 link")
73
- .optional(),
74
- note: z.string().describe("补充说明").optional(),
75
- },
76
- }, async (args) => toolReplyHelpers.safe(() => api.post("/api/mcp/build/reference", args)));
77
- // ─── post.build_image ──────────────────────────────────────────────────
78
- server.registerTool("post.build_image", {
79
- title: "Build markdown image syntax",
80
- description: "根据 url / alt / 扩展属性(width / align / ratio / rounded)构造合法的 markdown 图片语法。属性会被序列化进 title 字段(双引号、空格分隔)。直接调用 serializeImageAttributes + buildMarkdownImageSyntax。",
81
- inputSchema: {
82
- url: z.string().describe("图片 URL;推荐站内 /api/assets/oss/... 或合规 https"),
83
- alt: z.string(),
84
- width: z
85
- .number()
86
- .int()
87
- .min(1)
88
- .max(100)
89
- .describe("百分比,预设 25 / 33 / 50 / 66 / 75 / 100")
90
- .optional(),
91
- align: z.enum(["left", "center", "right"]).optional(),
92
- ratio: z.string().describe("如 16:9 / 4:3 / 1:1,用于骨架屏防抖").optional(),
93
- rounded: z.boolean().describe("false 输出 no-rounded;true 不输出(默认就是有圆角)").optional(),
94
- },
95
- }, async (args) => toolReplyHelpers.safe(() => api.post("/api/mcp/build/image", args)));
96
- // ─── post.build_code_group ─────────────────────────────────────────────
97
- server.registerTool("post.build_code_group", {
98
- title: "Build code-group block",
99
- description: "构造一段合法的 ```code-group 代码块,包含多个 /* @tab */ 标记的语言 tab。" +
100
- "适用于展示同一功能在不同语言中的实现(如 Python / JavaScript / cURL)。" +
101
- "输出可直接写入文章。",
102
- inputSchema: {
103
- tabs: z
104
- .array(z.object({
105
- label: z.string().describe("Tab 显示标签,如 'Python'、'JavaScript'"),
106
- lang: z
107
- .string()
108
- .describe("高亮语言(可选),如 'python'。不传则从 label 自动推断")
109
- .optional(),
110
- code: z.string().describe("该 tab 的代码内容"),
111
- }))
112
- .min(2, "至少需要 2 个 tab"),
113
- },
114
- }, async ({ tabs }) => {
115
- const inner = tabs
116
- .map((tab) => {
117
- const langAttr = tab.lang ? ` lang=${tab.lang}` : "";
118
- return `/* @tab ${tab.label}${langAttr} */\n${tab.code}`;
119
- })
120
- .join("\n\n");
121
- const block = "```code-group\n" + inner + "\n```";
122
- return toolReplyHelpers.toToolText(block);
123
- });
124
- // ─── post.build_details ────────────────────────────────────────────────
125
- server.registerTool("post.build_details", {
126
- title: "Build details block",
127
- description: "构造一段合法的 :::details 折叠块,基于 HTML5 <details>/<summary> 原生标签。" +
128
- "适用于补充说明、FAQ、技术细节等可选内容。" +
129
- "输出可直接写入文章。",
130
- inputSchema: {
131
- title: z.string().describe("折叠块的标题,显示在 summary 区域"),
132
- content: z.string().describe("折叠内容(支持完整 Markdown)"),
133
- defaultOpen: z
134
- .boolean()
135
- .describe("是否默认展开;true 添加 {open} 标记,false 默认收起")
136
- .optional(),
137
- },
138
- }, async ({ title, content, defaultOpen }) => {
139
- const openAttr = defaultOpen ? "{open}" : "";
140
- const block = `:::details[${title}]${openAttr}\n${content}\n:::`;
141
- return toolReplyHelpers.toToolText(block);
142
- });
143
- // ─── post.build_timeline ───────────────────────────────────────────────
144
- server.registerTool("post.build_timeline", {
145
- title: "Build timeline block",
146
- description: "构造一段合法的 :::timeline 时间轴块,展示项目里程碑、版本历史、事件发展等。" +
147
- "每个事件用列表项格式定义,支持激活状态标记。" +
148
- "输出可直接写入文章。",
149
- inputSchema: {
150
- events: z
151
- .array(z.object({
152
- time: z.string().describe("事件发生的时间,如 '2024-01'、'2024-Q1'"),
153
- title: z.string().describe("事件的简短标题"),
154
- content: z.string().describe("事件的详细描述(可选)").optional(),
155
- active: z
156
- .boolean()
157
- .describe("是否标记为激活状态(实心圆点 + 高亮)")
158
- .optional(),
159
- }))
160
- .min(1, "至少需要 1 个事件"),
161
- },
162
- }, async ({ events }) => {
163
- const eventLines = events
164
- .map((event) => {
165
- const activeMarker = event.active ? " [active]" : "";
166
- const titleLine = `- ${event.time} | ${event.title}${activeMarker}`;
167
- if (event.content) {
168
- const contentLines = event.content
169
- .split("\n")
170
- .map((line) => ` ${line}`)
171
- .join("\n");
172
- return `${titleLine}\n${contentLines}`;
173
- }
174
- return titleLine;
175
- })
176
- .join("\n\n");
177
- const block = `:::timeline\n${eventLines}\n:::`;
178
- return toolReplyHelpers.toToolText(block);
179
- });
180
- }
181
- //# sourceMappingURL=build.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/tools/build.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApiClient } from "../api-client.js";
3
- /** 注册全部代码仓库相关工具 */
4
- export declare function registerCodeRepoTools(server: McpServer, api: ApiClient): void;
5
- //# sourceMappingURL=code-repos.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-repos.d.ts","sourceRoot":"","sources":["../../src/tools/code-repos.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiBlD,mBAAmB;AACnB,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CA2L7E"}
@@ -1,149 +0,0 @@
1
- import { z } from "zod";
2
- import { toolReplyHelpers } from "./helpers.js";
3
- /**
4
- * 代码仓库相关 MCP 工具:
5
- * post.get_code_repo / post.upsert_code_repo / post.delete_code_repo / post.patch_code_file
6
- * code_repo.list / post.link_code_repo / code_repo.get_links
7
- *
8
- * 设计原则:
9
- * - 工具的入参 schema 用 zod raw shape 形态
10
- * - upsert_code_repo 是幂等操作,文章已有关联仓库则更新,否则创建新仓库并关联
11
- * - 一篇文章最多关联一个仓库,一个仓库可被多篇文章共享
12
- * - code_repo.list + post.link_code_repo 让 Agent 可搜索并复用已有仓库
13
- * - tool 的返回统一打包为 { content: [{ type: "text", text: <json> }] }
14
- */
15
- const { safe } = toolReplyHelpers;
16
- /** 注册全部代码仓库相关工具 */
17
- export function registerCodeRepoTools(server, api) {
18
- // ─── post.get_code_repo ───────────────────────────────────────────────
19
- server.registerTool("post.get_code_repo", {
20
- title: "Get code repository",
21
- description: "获取指定文章关联的代码仓库,包含所有文件的完整内容。" +
22
- "一篇文章最多关联一个代码仓库,一个仓库可被多篇文章共享。" +
23
- "返回的 files 数组中每项包含 path(支持文件夹层级)和 content。",
24
- inputSchema: {
25
- id: z.string().describe("文章 id (uuid)"),
26
- },
27
- }, async ({ id }) => safe(() => api.get(`/api/mcp/posts/${encodeURIComponent(id)}/code`)));
28
- // ─── post.upsert_code_repo ────────────────────────────────────────────
29
- server.registerTool("post.upsert_code_repo", {
30
- title: "Create or update code repository",
31
- description: "创建或更新文章关联的代码仓库。如果该文章已有关联仓库则更新,否则创建新仓库并关联。" +
32
- "一篇文章最多关联一个仓库。files 数组中每项的 path 支持文件夹层级(如 'src/components/Button.tsx')。" +
33
- "⚠️ path 必须为相对路径,禁止以 / 开头或包含 ..。" +
34
- "💡 如果想复用已有仓库而非创建新的,请先用 code_repo.list 搜索,再用 post.link_code_repo 关联。",
35
- inputSchema: {
36
- id: z.string().describe("文章 id (uuid)"),
37
- title: z.string().max(255).optional().describe("仓库展示名称"),
38
- description: z.string().optional().describe("仓库描述"),
39
- defaultFilePath: z
40
- .string()
41
- .optional()
42
- .describe("默认打开的文件路径,如 'README.md'"),
43
- meta: z
44
- .object({
45
- branch: z.string().optional().describe("展示用分支名"),
46
- license: z.string().optional().describe("展示用许可证"),
47
- repoUrl: z.string().optional().describe("关联的外部仓库链接"),
48
- })
49
- .optional()
50
- .describe("仓库元信息"),
51
- files: z
52
- .array(z.object({
53
- path: z
54
- .string()
55
- .describe("文件相对路径,如 'src/index.ts'(禁止绝对路径或 ..)"),
56
- content: z.string().describe("文件内容"),
57
- }))
58
- .min(1)
59
- .describe("代码文件列表,至少包含一个文件"),
60
- },
61
- }, async ({ id, title, description, defaultFilePath, meta, files }) => safe(() => api.post(`/api/mcp/posts/${encodeURIComponent(id)}/code`, {
62
- title,
63
- description,
64
- defaultFilePath,
65
- meta,
66
- files,
67
- })));
68
- // ─── post.delete_code_repo ────────────────────────────────────────────
69
- server.registerTool("post.delete_code_repo", {
70
- title: "Delete code repository",
71
- description: "解除文章与代码仓库的关联。若文章是仓库的唯一所有者,则同时删除仓库。文章本身不受影响。" +
72
- "💡 解除前可用 code_repo.get_links 确认是否有其他文章共享此仓库。",
73
- inputSchema: {
74
- id: z.string().describe("文章 id (uuid)"),
75
- },
76
- }, async ({ id }) => safe(() => api.delete(`/api/mcp/posts/${encodeURIComponent(id)}/code`)));
77
- // ─── code_repo.list ─────────────────────────────────────────────────────
78
- server.registerTool("code_repo.list", {
79
- title: "List code repositories",
80
- description: "列出所有代码仓库(支持搜索和分页)。" +
81
- "用于发现可复用的已有仓库,避免重复创建。" +
82
- "返回每个仓库的 id、标题、文件数和被关联的文章数量。",
83
- inputSchema: {
84
- search: z.string().optional().describe("按标题模糊搜索"),
85
- page: z.number().int().min(1).optional().describe("页码,默认 1"),
86
- pageSize: z
87
- .number()
88
- .int()
89
- .min(1)
90
- .max(50)
91
- .optional()
92
- .describe("每页条数,默认 20"),
93
- },
94
- }, async ({ search, page, pageSize }) => {
95
- const params = new URLSearchParams();
96
- if (search)
97
- params.set("search", search);
98
- if (page)
99
- params.set("page", String(page));
100
- if (pageSize)
101
- params.set("pageSize", String(pageSize));
102
- const qs = params.toString();
103
- return safe(() => api.get(`/api/mcp/code-repos${qs ? `?${qs}` : ""}`));
104
- });
105
- // ─── post.link_code_repo ────────────────────────────────────────────────
106
- server.registerTool("post.link_code_repo", {
107
- title: "Link article to existing code repository",
108
- description: "将文章关联到一个已有的代码仓库(不创建新仓库)。" +
109
- "适用于系列文章共享同一个代码库的场景。" +
110
- "一篇文章最多关联一个仓库,若已有关联需先解除。" +
111
- "先用 code_repo.list 搜索可复用的仓库,再用此工具关联。",
112
- inputSchema: {
113
- id: z.string().describe("文章 id (uuid)"),
114
- codeRepoId: z
115
- .string()
116
- .describe("要关联的仓库 id (uuid),从 code_repo.list 获取"),
117
- },
118
- }, async ({ id, codeRepoId }) => safe(() => api.post(`/api/mcp/posts/${encodeURIComponent(id)}/code/link`, {
119
- codeRepoId,
120
- })));
121
- // ─── code_repo.get_links ────────────────────────────────────────────────
122
- server.registerTool("code_repo.get_links", {
123
- title: "Get articles linked to a code repository",
124
- description: "查看某个代码仓库被哪些文章关联。" +
125
- "用于了解仓库的共享情况,避免误删正在被使用的仓库。",
126
- inputSchema: {
127
- repoId: z.string().describe("仓库 id (uuid)"),
128
- },
129
- }, async ({ repoId }) => safe(() => api.get(`/api/mcp/code-repos/${encodeURIComponent(repoId)}/links`)));
130
- // ─── post.patch_code_file ─────────────────────────────────────────────
131
- server.registerTool("post.patch_code_file", {
132
- title: "Update a single file in code repository",
133
- description: "更新代码仓库中的单个文件内容(不影响其他文件)。" +
134
- "⚠️ 修改单个文件的首选方式,无需重传整个仓库。" +
135
- "先用 post.get_code_repo 查看现有文件列表,修改后用此工具写回。",
136
- inputSchema: {
137
- id: z.string().describe("文章 id (uuid)"),
138
- filePath: z
139
- .string()
140
- .min(1)
141
- .describe("要更新的文件路径(与仓库中的 path 一致),如 'src/index.ts'"),
142
- content: z.string().describe("该文件的新内容"),
143
- },
144
- }, async ({ id, filePath, content }) => safe(() => api.patch(`/api/mcp/posts/${encodeURIComponent(id)}/code/file`, {
145
- filePath,
146
- content,
147
- })));
148
- }
149
- //# sourceMappingURL=code-repos.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-repos.js","sourceRoot":"","sources":["../../src/tools/code-repos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC;AAElC,mBAAmB;AACnB,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,GAAc;IACrE,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,4BAA4B;YAC5B,8BAA8B;YAC9B,2CAA2C;QAC7C,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SACxC;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CACf,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAkB,kBAAkB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CACvE,CAAC;IAEF,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,2CAA2C;YAC3C,wEAAwE;YACxE,iCAAiC;YACjC,qEAAqE;QACvE,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YACnD,eAAe,EAAE,CAAC;iBACf,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yBAAyB,CAAC;YACtC,IAAI,EAAE,CAAC;iBACJ,MAAM,CAAC;gBACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAChD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;aACrD,CAAC;iBACD,QAAQ,EAAE;iBACV,QAAQ,CAAC,OAAO,CAAC;YACpB,KAAK,EAAE,CAAC;iBACL,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,IAAI,EAAE,CAAC;qBACJ,MAAM,EAAE;qBACR,QAAQ,CAAC,qCAAqC,CAAC;gBAClD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;aACrC,CAAC,CACH;iBACA,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,iBAAiB,CAAC;SAC/B;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CACjE,IAAI,CAAC,GAAG,EAAE,CACR,GAAG,CAAC,IAAI,CAAC,kBAAkB,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QACxD,KAAK;QACL,WAAW;QACX,eAAe;QACf,IAAI;QACJ,KAAK;KACN,CAAC,CACH,CACJ,CAAC;IAEF,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,6CAA6C;YAC7C,8CAA8C;QAChD,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SACxC;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CACf,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,kBAAkB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAC1E,CAAC;IAEF,2EAA2E;IAC3E,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,oBAAoB;YACpB,sBAAsB;YACtB,6BAA6B;QAC/B,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5D,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,EAAE;iBACV,QAAQ,CAAC,YAAY,CAAC;SAC1B;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,IAAI,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC,CACF,CAAC;IAEF,2EAA2E;IAC3E,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,0CAA0C;QACjD,WAAW,EACT,0BAA0B;YAC1B,qBAAqB;YACrB,yBAAyB;YACzB,qCAAqC;QACvC,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACvC,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,sCAAsC,CAAC;SACpD;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAC3B,IAAI,CAAC,GAAG,EAAE,CACR,GAAG,CAAC,IAAI,CAAC,kBAAkB,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE;QAC7D,UAAU;KACX,CAAC,CACH,CACJ,CAAC;IAEF,2EAA2E;IAC3E,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,0CAA0C;QACjD,WAAW,EACT,kBAAkB;YAClB,2BAA2B;QAC7B,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC5C;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CACnB,IAAI,CAAC,GAAG,EAAE,CACR,GAAG,CAAC,GAAG,CACL,uBAAuB,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAC1D,CACF,CACJ,CAAC;IAEF,yEAAyE;IACzE,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,yCAAyC;QAChD,WAAW,EACT,0BAA0B;YAC1B,0BAA0B;YAC1B,2CAA2C;QAC7C,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACvC,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,0CAA0C,CAAC;YACvD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;SACxC;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAClC,IAAI,CAAC,GAAG,EAAE,CACR,GAAG,CAAC,KAAK,CAAC,kBAAkB,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE;QAC9D,QAAQ;QACR,OAAO;KACR,CAAC,CACH,CACJ,CAAC;AACJ,CAAC"}
@@ -1,12 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApiClient } from "../api-client.js";
3
- /**
4
- * 评论相关 MCP 工具:comment.create。
5
- *
6
- * 支持:
7
- * - 在指定文章下创建一级评论(仅传 postId + content)
8
- * - 回复指定评论(额外传 parentId)
9
- */
10
- /** 注册评论相关 MCP 工具 */
11
- export declare function registerCommentTools(server: McpServer, api: ApiClient): void;
12
- //# sourceMappingURL=comments.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;GAMG;AAEH,oBAAoB;AACpB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAiG5E"}
@@ -1,87 +0,0 @@
1
- import { z } from "zod";
2
- import { safe } from "./helpers.js";
3
- /**
4
- * 评论相关 MCP 工具:comment.create。
5
- *
6
- * 支持:
7
- * - 在指定文章下创建一级评论(仅传 postId + content)
8
- * - 回复指定评论(额外传 parentId)
9
- */
10
- /** 注册评论相关 MCP 工具 */
11
- export function registerCommentTools(server, api) {
12
- // ─── comment.create ────────────────────────────────────────────────────
13
- server.registerTool("comment.create", {
14
- title: "Create comment",
15
- description: "在指定文章下创建一级评论,或回复已有评论。" +
16
- "创建一级评论只需传 postId + content;" +
17
- "回复某条评论需额外传 parentId(被回复评论的 UUID)。" +
18
- "content 支持 Markdown 格式,长度 1-5000 字符。",
19
- inputSchema: {
20
- postId: z.string().uuid().describe("目标文章 ID(UUID)"),
21
- parentId: z
22
- .string()
23
- .uuid()
24
- .nullable()
25
- .describe("要回复的评论 ID(UUID);创建一级评论时传 null 或不传")
26
- .optional(),
27
- content: z
28
- .string()
29
- .min(1)
30
- .max(5000)
31
- .describe("评论内容,支持 Markdown,1-5000 字符"),
32
- },
33
- }, async ({ postId, parentId, content }) => safe(() => api.post("/api/mcp/comments", {
34
- postId,
35
- parentId: parentId ?? null,
36
- content,
37
- })));
38
- // ─── comment.ai_generate ──────────────────────────────────────────────
39
- server.registerTool("comment.ai_generate", {
40
- title: "Generate AI comment",
41
- description: "使用指定的 AI Bot 对文章生成一条评论。" +
42
- "可通过 botId(UUID)或 botSlug(如 tech-observer)指定机器人。" +
43
- "生成的评论默认为草稿状态(需后台审核),除非 Bot 配置了自动发布或传入 autoApprove=true。" +
44
- "可选传入 instruction 引导评论方向,parentId 可回复已有评论。",
45
- inputSchema: {
46
- botId: z
47
- .string()
48
- .uuid()
49
- .optional()
50
- .describe("Bot UUID。与 botSlug 二选一"),
51
- botSlug: z
52
- .string()
53
- .optional()
54
- .describe("Bot slug(如 tech-observer)。与 botId 二选一"),
55
- postId: z.string().uuid().describe("目标文章 ID(UUID)"),
56
- instruction: z
57
- .string()
58
- .max(500)
59
- .optional()
60
- .describe("额外指令,引导 AI 评论方向(可选)"),
61
- parentId: z
62
- .string()
63
- .uuid()
64
- .nullable()
65
- .optional()
66
- .describe("要回复的评论 ID(UUID);对文章直接评论时不传"),
67
- autoApprove: z
68
- .boolean()
69
- .optional()
70
- .describe("是否跳过审核直接发布(覆盖 Bot 默认配置)"),
71
- },
72
- }, async ({ botId, botSlug, postId, instruction, parentId, autoApprove }) => safe(() => api.post("/api/mcp/ai-comments", {
73
- botId,
74
- botSlug,
75
- postId,
76
- instruction,
77
- parentId: parentId ?? null,
78
- autoApprove,
79
- })));
80
- // ─── comment.ai_list_bots ─────────────────────────────────────────────
81
- server.registerTool("comment.ai_list_bots", {
82
- title: "List AI bots",
83
- description: "列出所有已启用的 AI 评论机器人,返回 id / slug / name / provider / model。",
84
- inputSchema: {},
85
- }, async () => safe(() => api.get("/api/mcp/ai-comments")));
86
- }
87
- //# sourceMappingURL=comments.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApiClient } from "../api-client.js";
3
- /** 注册全部 Demo 相关工具 */
4
- export declare function registerDemoTools(server: McpServer, api: ApiClient): void;
5
- //# sourceMappingURL=demos.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"demos.d.ts","sourceRoot":"","sources":["../../src/tools/demos.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAalD,qBAAqB;AACrB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAsIzE"}