@page.su/ai-blog-cli 0.1.0-beta.1 → 0.1.0-beta.10

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 (107) hide show
  1. package/dist/cli.js +14 -5
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/comments.js +1 -1
  4. package/dist/commands/comments.js.map +1 -1
  5. package/dist/commands/config.d.ts +12 -0
  6. package/dist/commands/config.d.ts.map +1 -0
  7. package/dist/commands/config.js +128 -0
  8. package/dist/commands/config.js.map +1 -0
  9. package/dist/commands/demo.js +2 -2
  10. package/dist/commands/demo.js.map +1 -1
  11. package/dist/commands/post.d.ts.map +1 -1
  12. package/dist/commands/post.js +30 -3
  13. package/dist/commands/post.js.map +1 -1
  14. package/dist/commands/render-errors.d.ts +4 -0
  15. package/dist/commands/render-errors.d.ts.map +1 -0
  16. package/dist/commands/render-errors.js +22 -0
  17. package/dist/commands/render-errors.js.map +1 -0
  18. package/dist/commands/skills.d.ts.map +1 -1
  19. package/dist/commands/skills.js +67 -19
  20. package/dist/commands/skills.js.map +1 -1
  21. package/dist/commands/syntax.d.ts +4 -0
  22. package/dist/commands/syntax.d.ts.map +1 -0
  23. package/dist/commands/syntax.js +29 -0
  24. package/dist/commands/syntax.js.map +1 -0
  25. package/dist/config.d.ts +84 -8
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +196 -29
  28. package/dist/config.js.map +1 -1
  29. package/dist/config.test.js +150 -19
  30. package/dist/config.test.js.map +1 -1
  31. package/package.json +12 -6
  32. package/dist/index.d.ts +0 -3
  33. package/dist/index.d.ts.map +0 -1
  34. package/dist/index.js +0 -100
  35. package/dist/index.js.map +0 -1
  36. package/dist/prompts/index.d.ts +0 -9
  37. package/dist/prompts/index.d.ts.map +0 -1
  38. package/dist/prompts/index.js +0 -178
  39. package/dist/prompts/index.js.map +0 -1
  40. package/dist/resources/syntax-spec.d.ts +0 -23
  41. package/dist/resources/syntax-spec.d.ts.map +0 -1
  42. package/dist/resources/syntax-spec.js +0 -105
  43. package/dist/resources/syntax-spec.js.map +0 -1
  44. package/dist/resources/syntax-spec.test.d.ts +0 -2
  45. package/dist/resources/syntax-spec.test.d.ts.map +0 -1
  46. package/dist/resources/syntax-spec.test.js +0 -47
  47. package/dist/resources/syntax-spec.test.js.map +0 -1
  48. package/dist/tools/build.d.ts +0 -13
  49. package/dist/tools/build.d.ts.map +0 -1
  50. package/dist/tools/build.js +0 -181
  51. package/dist/tools/build.js.map +0 -1
  52. package/dist/tools/code-repos.d.ts +0 -5
  53. package/dist/tools/code-repos.d.ts.map +0 -1
  54. package/dist/tools/code-repos.js +0 -149
  55. package/dist/tools/code-repos.js.map +0 -1
  56. package/dist/tools/comments.d.ts +0 -12
  57. package/dist/tools/comments.d.ts.map +0 -1
  58. package/dist/tools/comments.js +0 -87
  59. package/dist/tools/comments.js.map +0 -1
  60. package/dist/tools/demos.d.ts +0 -5
  61. package/dist/tools/demos.d.ts.map +0 -1
  62. package/dist/tools/demos.js +0 -98
  63. package/dist/tools/demos.js.map +0 -1
  64. package/dist/tools/glossary.d.ts +0 -4
  65. package/dist/tools/glossary.d.ts.map +0 -1
  66. package/dist/tools/glossary.js +0 -139
  67. package/dist/tools/glossary.js.map +0 -1
  68. package/dist/tools/helpers.d.ts +0 -44
  69. package/dist/tools/helpers.d.ts.map +0 -1
  70. package/dist/tools/helpers.js +0 -65
  71. package/dist/tools/helpers.js.map +0 -1
  72. package/dist/tools/knowledge.d.ts +0 -4
  73. package/dist/tools/knowledge.d.ts.map +0 -1
  74. package/dist/tools/knowledge.js +0 -140
  75. package/dist/tools/knowledge.js.map +0 -1
  76. package/dist/tools/math-concepts.d.ts +0 -4
  77. package/dist/tools/math-concepts.d.ts.map +0 -1
  78. package/dist/tools/math-concepts.js +0 -158
  79. package/dist/tools/math-concepts.js.map +0 -1
  80. package/dist/tools/posts.d.ts +0 -35
  81. package/dist/tools/posts.d.ts.map +0 -1
  82. package/dist/tools/posts.js +0 -278
  83. package/dist/tools/posts.js.map +0 -1
  84. package/dist/tools/scout.d.ts +0 -10
  85. package/dist/tools/scout.d.ts.map +0 -1
  86. package/dist/tools/scout.js +0 -111
  87. package/dist/tools/scout.js.map +0 -1
  88. package/dist/tools/series.d.ts +0 -12
  89. package/dist/tools/series.d.ts.map +0 -1
  90. package/dist/tools/series.js +0 -120
  91. package/dist/tools/series.js.map +0 -1
  92. package/dist/tools/syntax-capabilities.d.ts +0 -15
  93. package/dist/tools/syntax-capabilities.d.ts.map +0 -1
  94. package/dist/tools/syntax-capabilities.js +0 -859
  95. package/dist/tools/syntax-capabilities.js.map +0 -1
  96. package/dist/tools/taxonomy.d.ts +0 -4
  97. package/dist/tools/taxonomy.d.ts.map +0 -1
  98. package/dist/tools/taxonomy.js +0 -73
  99. package/dist/tools/taxonomy.js.map +0 -1
  100. package/dist/tools/uploads.d.ts +0 -15
  101. package/dist/tools/uploads.d.ts.map +0 -1
  102. package/dist/tools/uploads.js +0 -56
  103. package/dist/tools/uploads.js.map +0 -1
  104. package/dist/tools/workflows.d.ts +0 -9
  105. package/dist/tools/workflows.d.ts.map +0 -1
  106. package/dist/tools/workflows.js +0 -249
  107. package/dist/tools/workflows.js.map +0 -1
package/package.json CHANGED
@@ -1,10 +1,16 @@
1
1
  {
2
2
  "name": "@page.su/ai-blog-cli",
3
- "version": "0.1.0-beta.1",
3
+ "version": "0.1.0-beta.10",
4
4
  "private": false,
5
5
  "description": "CLI tool for AI agents to write, manage, and publish posts on ai-blog.",
6
6
  "license": "MIT",
7
- "keywords": ["cli", "blog", "ai", "agent", "markdown"],
7
+ "keywords": [
8
+ "cli",
9
+ "blog",
10
+ "ai",
11
+ "agent",
12
+ "markdown"
13
+ ],
8
14
  "author": "苏培森",
9
15
  "engines": {
10
16
  "node": ">=18"
@@ -29,13 +35,13 @@
29
35
  "prepublishOnly": "pnpm build && pnpm test"
30
36
  },
31
37
  "dependencies": {
32
- "commander": "^12.1.0",
33
- "zod": "^3.23.8"
38
+ "commander": "^12.1.0"
34
39
  },
35
40
  "devDependencies": {
36
41
  "@types/node": "^20.0.0",
37
42
  "tsx": "^4.19.2",
38
43
  "typescript": "^5.5.4",
39
44
  "vitest": "^4.1.0"
40
- }
41
- }
45
+ },
46
+ "repository": "https://debian.hellosu.top:3000/supeisen/ai-blog.git"
47
+ }
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js DELETED
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env node
2
- import { readFileSync } from "node:fs";
3
- import { fileURLToPath } from "node:url";
4
- import { dirname, resolve } from "node:path";
5
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
- import { createApiClient } from "./api-client.js";
8
- import { loadMcpServerConfig } from "./config.js";
9
- /**
10
- * 从和入口同级的 package.json 读取版本号(编译后 dist/index.js 位于 dist/,
11
- * package.json 在其上一级目录)。这样后续发新版时只需改 package.json 一处。
12
- */
13
- function readOwnVersion() {
14
- const distDir = dirname(fileURLToPath(import.meta.url));
15
- const pkgPath = resolve(distDir, "..", "package.json");
16
- try {
17
- const raw = readFileSync(pkgPath, "utf-8");
18
- const pkg = JSON.parse(raw);
19
- return pkg.version ?? "0.0.0";
20
- }
21
- catch {
22
- return "0.0.0";
23
- }
24
- }
25
- import { registerBuildTools } from "./tools/build.js";
26
- import { registerCommentTools } from "./tools/comments.js";
27
- import { registerDemoTools } from "./tools/demos.js";
28
- import { registerPostTools } from "./tools/posts.js";
29
- import { registerTaxonomyTools } from "./tools/taxonomy.js";
30
- import { registerUploadTools } from "./tools/uploads.js";
31
- import { registerKnowledgeTools } from "./tools/knowledge.js";
32
- import { registerScoutTools } from "./tools/scout.js";
33
- import { registerSeriesTools } from "./tools/series.js";
34
- import { registerCodeRepoTools } from "./tools/code-repos.js";
35
- import { registerSyntaxCapabilitiesTools } from "./tools/syntax-capabilities.js";
36
- import { registerWorkflowTools } from "./tools/workflows.js";
37
- import { registerSyntaxSpecResources } from "./resources/syntax-spec.js";
38
- import { registerPrompts } from "./prompts/index.js";
39
- /**
40
- * ai-blog MCP server 入口(stdio)。
41
- *
42
- * 启动流程:
43
- * 1. 读取环境变量配置(缺失即直接退出,避免半残运行)
44
- * 2. 实例化 McpServer,注册 tools / resources
45
- * 3. 通过 StdioServerTransport 接管 stdin / stdout,进入消息循环
46
- *
47
- * 任何运行期错误都会写到 stderr —— 务必避免污染 stdout,
48
- * 否则会破坏 MCP JSON-RPC 协议帧。
49
- */
50
- async function main() {
51
- const config = loadMcpServerConfig();
52
- const api = createApiClient(config);
53
- const serverVersion = readOwnVersion();
54
- const server = new McpServer({
55
- name: "ai-blog-mcp-server",
56
- version: serverVersion,
57
- }, {
58
- capabilities: {
59
- tools: {},
60
- resources: {},
61
- prompts: {},
62
- },
63
- });
64
- // 注册 tools
65
- registerPostTools(server, api);
66
- registerDemoTools(server, api);
67
- registerCommentTools(server, api);
68
- registerTaxonomyTools(server, api);
69
- registerKnowledgeTools(server, api);
70
- registerBuildTools(server, api);
71
- registerUploadTools(server, api);
72
- registerScoutTools(server, api);
73
- registerSeriesTools(server, api);
74
- registerCodeRepoTools(server, api);
75
- registerSyntaxCapabilitiesTools(server);
76
- registerWorkflowTools(server);
77
- // 注册 resources
78
- registerSyntaxSpecResources(server, api);
79
- // 注册 prompts(写作模板)
80
- registerPrompts(server);
81
- const transport = new StdioServerTransport();
82
- await server.connect(transport);
83
- // 友好的退出处理:收到信号时先 close 再退出
84
- const shutdown = async (signal) => {
85
- process.stderr.write(`[ai-blog-mcp] received ${signal}, shutting down...\n`);
86
- try {
87
- await server.close();
88
- }
89
- finally {
90
- process.exit(0);
91
- }
92
- };
93
- process.on("SIGINT", () => void shutdown("SIGINT"));
94
- process.on("SIGTERM", () => void shutdown("SIGTERM"));
95
- }
96
- main().catch((error) => {
97
- process.stderr.write(`[ai-blog-mcp] fatal: ${error instanceof Error ? error.message : String(error)}\n`);
98
- process.exit(1);
99
- });
100
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;GAGG;AACH,SAAS,cAAc;IACrB,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACpD,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AACD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;IAEvC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,aAAa;KACvB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;SACZ;KACF,CACF,CAAC;IAEF,WAAW;IACX,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACxC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9B,eAAe;IACf,2BAA2B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEzC,mBAAmB;IACnB,eAAe,CAAC,MAAM,CAAC,CAAC;IAExB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,MAAM,sBAAsB,CAAC,CAAC;QAC7E,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1,9 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- /**
3
- * 写作辅助类 MCP Prompts。
4
- *
5
- * 每个模板在 messages 开头都引导 AI 先调 `describe_workflows` 获取完整工作流路线图,
6
- * 再按推荐步骤执行。大文章场景引导使用 outline/section 精准读写工作流。
7
- */
8
- export declare function registerPrompts(server: McpServer): void;
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4LvD"}
@@ -1,178 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * 写作辅助类 MCP Prompts。
4
- *
5
- * 每个模板在 messages 开头都引导 AI 先调 `describe_workflows` 获取完整工作流路线图,
6
- * 再按推荐步骤执行。大文章场景引导使用 outline/section 精准读写工作流。
7
- */
8
- export function registerPrompts(server) {
9
- // ─── write-tutorial-post ────────────────────────────────────────────────
10
- server.registerPrompt("write-tutorial-post", {
11
- title: "Write a tutorial post",
12
- description: "技术教程模板:含 callout 提醒、live-demo 多文件代码沙箱、图片配图。",
13
- argsSchema: {
14
- topic: z.string().describe("教程主题,例如 'React Server Components 入门'"),
15
- audience: z
16
- .string()
17
- .describe("目标读者画像,例如 '有 1-2 年前端经验的工程师'")
18
- .optional(),
19
- },
20
- }, ({ topic, audience }) => ({
21
- messages: [
22
- {
23
- role: "user",
24
- content: {
25
- type: "text",
26
- text: [
27
- `请写一篇技术教程文章:${topic}。`,
28
- audience ? `目标读者:${audience}。` : "",
29
- "",
30
- "准备工作(按顺序执行):",
31
- "0) 先调用 `describe_workflows` 获取完整工作流指南,按 'create-post' 工作流执行。",
32
- "1) 调用 `post.describe_syntax_capabilities` 了解 14 类高级 Markdown 语法(首次写文章时)。",
33
- "2) 调用 `taxonomy.list` 获取合法的 tagIds / categoryIds。",
34
- "3) 可选:调用 `knowledge.find_or_suggest` 查找正文涉及的术语。",
35
- "4) 可选:调用 `scout.search_items` 搜索相关参考资料。",
36
- "",
37
- "写作约束:",
38
- "- 参考语法资源:mcp://syntax-spec/overview、callout、live-demo、image-attributes、checklist",
39
- "- 文章结构推荐:背景动机 → 核心概念 → 渐进式示例(含 ```live-demo) → 常见坑(用 callout) → 总结",
40
- "- 超长文章(>10000字):先 `post.create` 创建骨架,再用 `post.append_content` 分批追加章节",
41
- "- 写好正文后必须 `post.validate_markdown` 校验,errors 必须修复",
42
- "- 创建为 `status=draft`,让作者决定何时发布",
43
- ]
44
- .filter(Boolean)
45
- .join("\n"),
46
- },
47
- },
48
- ],
49
- }));
50
- // ─── write-deep-dive ────────────────────────────────────────────────────
51
- server.registerPrompt("write-deep-dive", {
52
- title: "Write a deep-dive analysis",
53
- description: "深度解析模板:含 mermaid 架构图、KaTeX 数学公式、参考文献引用。",
54
- argsSchema: {
55
- topic: z.string().describe("深度解析的主题"),
56
- depthHint: z
57
- .string()
58
- .describe("希望深入的方向,例如 '内部数据结构与时间复杂度'")
59
- .optional(),
60
- },
61
- }, ({ topic, depthHint }) => ({
62
- messages: [
63
- {
64
- role: "user",
65
- content: {
66
- type: "text",
67
- text: [
68
- `请写一篇深度解析文章:${topic}。`,
69
- depthHint ? `重点方向:${depthHint}。` : "",
70
- "",
71
- "准备工作(按顺序执行):",
72
- "0) 先调用 `describe_workflows` 获取完整工作流指南,按 'create-post' 工作流执行。",
73
- "1) 参考语法资源:mcp://syntax-spec/mermaid、math、footnote、site-post-reference",
74
- "2) 调用 `taxonomy.list` 获取分类和标签。",
75
- "3) 调用 `scout.search_items` 搜索相关论文/文档作为参考资料。",
76
- "",
77
- "写作约束:",
78
- "- 至少包含一个 mermaid 图与一组数学公式",
79
- "- 引用论文/文档用 ```ref 参考文献语法(用 `post.build_reference` 构造),不要用 GFM 脚注",
80
- "- 站内引用前先用 `post.list_for_reference` 校验 slug 存在",
81
- "- 超长文章:先创建骨架,再用 `post.append_content` 分批追加",
82
- "- 写完后 `post.validate_markdown` 校验",
83
- "- 创建为 `status=draft`",
84
- ]
85
- .filter(Boolean)
86
- .join("\n"),
87
- },
88
- },
89
- ],
90
- }));
91
- // ─── write-changelog ────────────────────────────────────────────────────
92
- server.registerPrompt("write-changelog", {
93
- title: "Write a changelog post",
94
- description: "变更说明模板:版本号 + 三段式(新增/优化/修复)+ 站内引用相关文档。",
95
- argsSchema: {
96
- version: z.string().describe("版本号,例如 v1.4.0"),
97
- highlights: z.string().describe("本次发布要点,逗号或换行分隔").optional(),
98
- },
99
- }, ({ version, highlights }) => ({
100
- messages: [
101
- {
102
- role: "user",
103
- content: {
104
- type: "text",
105
- text: [
106
- `请写一篇 ${version} 的变更说明(changelog)。`,
107
- highlights ? `本次要点:${highlights}` : "",
108
- "",
109
- "准备工作:",
110
- "0) 先调用 `describe_workflows` 获取工作流指南。",
111
- "1) 调用 `taxonomy.list` 获取分类和标签。",
112
- "2) 调用 `post.list_for_reference` 获取站内文章 slug 列表。",
113
- "",
114
- "写作约束:",
115
- "- 标题形如 \"vX.Y.Z 变更说明\";slug 必须包含版本号",
116
- "- 三段式结构:✨ 新增 / ♻️ 优化 / 🐛 修复,使用三级标题",
117
- "- 涉及到本站文章时,用 [标题](../posts/<slug>) 站内引用(slug 必须从 list_for_reference 获取)",
118
- "- 仅在解释复杂行为变更时插入 callout;其它用项目符号",
119
- "- 创建为 `status=draft`",
120
- ]
121
- .filter(Boolean)
122
- .join("\n"),
123
- },
124
- },
125
- ],
126
- }));
127
- // ─── rewrite-existing-post ──────────────────────────────────────────────
128
- server.registerPrompt("rewrite-existing-post", {
129
- title: "Rewrite an existing post",
130
- description: "重写已有文章:支持全量重写和章节级精准修改两种模式。",
131
- argsSchema: {
132
- postId: z.string().describe("要重写的文章 id (uuid)"),
133
- intent: z
134
- .string()
135
- .describe("重写意图,例如 '让结构更清晰,补充 2025 年的最新进展'")
136
- .optional(),
137
- },
138
- }, ({ postId, intent }) => ({
139
- messages: [
140
- {
141
- role: "user",
142
- content: {
143
- type: "text",
144
- text: [
145
- `请重写文章(id=${postId})。`,
146
- intent ? `重写目标:${intent}` : "",
147
- "",
148
- "准备工作:",
149
- "0) 先调用 `describe_workflows` 获取工作流指南。",
150
- "1) 调用 `post.get_outline` 查看文章结构和各章节大小。",
151
- "",
152
- "选择执行模式:",
153
- "",
154
- "【模式 A:章节级精准修改】(推荐,适用于只改部分章节)",
155
- "- 按 'update-section' 工作流执行",
156
- "- 用 `post.get_section(index)` 读取需要修改的章节",
157
- "- 用 `post.replace_section(sectionIndex)` 替换修改后的章节",
158
- "- 用 `post.insert_section` 在指定位置插入新章节",
159
- "- 可重复以上步骤修改多个章节",
160
- "",
161
- "【模式 B:全量重写】(适用于结构大改、整体推翻重来)",
162
- "- 按 'rewrite-post' 工作流执行",
163
- "- 用 `post.get` 读取完整原文",
164
- "- 改写后用 `post.update` 提交完整新版本",
165
- "",
166
- "通用约束:",
167
- "- 保留原 slug 不变(避免外链失效)",
168
- "- 写完后 `post.validate_markdown` 校验,errors 必须 0",
169
- "- 不要主动 update_status 到 published",
170
- ]
171
- .filter(Boolean)
172
- .join("\n"),
173
- },
174
- },
175
- ],
176
- }));
177
- }
178
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApiClient } from "../api-client.js";
3
- /**
4
- * 把 docs/markdown-advanced-syntax-spec.md 的 13 个章节挂载为 MCP resource。
5
- *
6
- * 实现:
7
- * - mcp-server 仅注册 URI(如 mcp://syntax-spec/live-demo),不内置文档内容
8
- * - 内容来自 ai-blog 后端的 `/api/mcp/syntax-spec/<section>` 端点(按需读取)
9
- * - 这样保证 ai-blog 仓库里的 spec 文档变更后,MCP 客户端无需重装 mcp-server
10
- */
11
- /** spec 章节定义;section 字段对应 ai-blog 端 `/api/mcp/syntax-spec/<section>` 的最后一段 */
12
- interface SyntaxSpecSection {
13
- uri: string;
14
- section: string;
15
- name: string;
16
- description: string;
17
- }
18
- /** 把全部 syntax-spec 章节注册为静态 MCP resource */
19
- export declare function registerSyntaxSpecResources(server: McpServer, api: ApiClient): void;
20
- /** 测试用:导出全部章节列表,便于单测断言注册数量与 URI 完整性 */
21
- export declare const SYNTAX_SPEC_SECTIONS_FOR_TEST: readonly SyntaxSpecSection[];
22
- export {};
23
- //# sourceMappingURL=syntax-spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syntax-spec.d.ts","sourceRoot":"","sources":["../../src/resources/syntax-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;GAOG;AAEH,8EAA8E;AAC9E,UAAU,iBAAiB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAoFD,2CAA2C;AAC3C,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAwBnF;AAED,uCAAuC;AACvC,eAAO,MAAM,6BAA6B,8BAAuB,CAAC"}
@@ -1,105 +0,0 @@
1
- /** 13 个章节(spec 主文档 + checklist 附录) */
2
- const SYNTAX_SPEC_SECTIONS = [
3
- {
4
- uri: "mcp://syntax-spec/overview",
5
- section: "overview",
6
- name: "syntax-spec / overview",
7
- description: "ai-blog 12 类非标准语法总览(不超过 800 字)",
8
- },
9
- {
10
- uri: "mcp://syntax-spec/frontmatter",
11
- section: "frontmatter",
12
- name: "syntax-spec / frontmatter",
13
- description: "§1 Frontmatter(YAML)规范",
14
- },
15
- {
16
- uri: "mcp://syntax-spec/callout",
17
- section: "callout",
18
- name: "syntax-spec / callout",
19
- description: "§2 Callout(>[!TIP] 等)规范",
20
- },
21
- {
22
- uri: "mcp://syntax-spec/mermaid",
23
- section: "mermaid",
24
- name: "syntax-spec / mermaid",
25
- description: "§4 Mermaid 图表代码块规范",
26
- },
27
- {
28
- uri: "mcp://syntax-spec/live-demo",
29
- section: "live-demo",
30
- name: "syntax-spec / live-demo",
31
- description: "§5 Live Demo 多文件代码块规范(含 tailwind / cdn meta)",
32
- },
33
- {
34
- uri: "mcp://syntax-spec/math",
35
- section: "math",
36
- name: "syntax-spec / math",
37
- description: "§6 数学公式 $..$ / $$..$$ 规范",
38
- },
39
- {
40
- uri: "mcp://syntax-spec/image-attributes",
41
- section: "image-attributes",
42
- name: "syntax-spec / image-attributes",
43
- description: "§7 图片扩展属性(title 编码 w= / align= / ratio= 等)",
44
- },
45
- {
46
- uri: "mcp://syntax-spec/image-gallery",
47
- section: "image-gallery",
48
- name: "syntax-spec / image-gallery",
49
- description: "§8 图片宫格自动检测规则",
50
- },
51
- {
52
- uri: "mcp://syntax-spec/image-whitelist",
53
- section: "image-whitelist",
54
- name: "syntax-spec / image-whitelist",
55
- description: "§9 图片 src 白名单(前台严格模式)",
56
- },
57
- {
58
- uri: "mcp://syntax-spec/url-whitelist",
59
- section: "url-whitelist",
60
- name: "syntax-spec / url-whitelist",
61
- description: "§10 URL 协议白名单(链接)",
62
- },
63
- {
64
- uri: "mcp://syntax-spec/footnote",
65
- section: "footnote",
66
- name: "syntax-spec / footnote",
67
- description: "§11 GFM 脚注规范",
68
- },
69
- {
70
- uri: "mcp://syntax-spec/site-post-reference",
71
- section: "site-post-reference",
72
- name: "syntax-spec / site-post-reference",
73
- description: "§12 站内文章引用 [标题](../posts/<slug>) 规范",
74
- },
75
- {
76
- uri: "mcp://syntax-spec/checklist",
77
- section: "checklist",
78
- name: "syntax-spec / checklist",
79
- description: "附录 D:保存前 Checklist(AI 自检清单)",
80
- },
81
- ];
82
- /** 把全部 syntax-spec 章节注册为静态 MCP resource */
83
- export function registerSyntaxSpecResources(server, api) {
84
- for (const section of SYNTAX_SPEC_SECTIONS) {
85
- server.registerResource(section.name, section.uri, {
86
- title: section.name,
87
- description: section.description,
88
- mimeType: "text/markdown",
89
- }, async (uri) => {
90
- const text = await api.getText(`/api/mcp/syntax-spec/${section.section}`);
91
- return {
92
- contents: [
93
- {
94
- uri: uri.href,
95
- mimeType: "text/markdown",
96
- text,
97
- },
98
- ],
99
- };
100
- });
101
- }
102
- }
103
- /** 测试用:导出全部章节列表,便于单测断言注册数量与 URI 完整性 */
104
- export const SYNTAX_SPEC_SECTIONS_FOR_TEST = SYNTAX_SPEC_SECTIONS;
105
- //# sourceMappingURL=syntax-spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syntax-spec.js","sourceRoot":"","sources":["../../src/resources/syntax-spec.ts"],"names":[],"mappings":"AAoBA,sCAAsC;AACtC,MAAM,oBAAoB,GAAiC;IACzD;QACE,GAAG,EAAE,4BAA4B;QACjC,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,gCAAgC;KAC9C;IACD;QACE,GAAG,EAAE,+BAA+B;QACpC,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,wBAAwB;KACtC;IACD;QACE,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,yBAAyB;KACvC;IACD;QACE,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,oBAAoB;KAClC;IACD;QACE,GAAG,EAAE,6BAA6B;QAClC,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,8CAA8C;KAC5D;IACD;QACE,GAAG,EAAE,wBAAwB;QAC7B,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,0BAA0B;KACxC;IACD;QACE,GAAG,EAAE,oCAAoC;QACzC,OAAO,EAAE,kBAAkB;QAC3B,IAAI,EAAE,gCAAgC;QACtC,WAAW,EAAE,4CAA4C;KAC1D;IACD;QACE,GAAG,EAAE,iCAAiC;QACtC,OAAO,EAAE,eAAe;QACxB,IAAI,EAAE,6BAA6B;QACnC,WAAW,EAAE,eAAe;KAC7B;IACD;QACE,GAAG,EAAE,mCAAmC;QACxC,OAAO,EAAE,iBAAiB;QAC1B,IAAI,EAAE,+BAA+B;QACrC,WAAW,EAAE,uBAAuB;KACrC;IACD;QACE,GAAG,EAAE,iCAAiC;QACtC,OAAO,EAAE,eAAe;QACxB,IAAI,EAAE,6BAA6B;QACnC,WAAW,EAAE,mBAAmB;KACjC;IACD;QACE,GAAG,EAAE,4BAA4B;QACjC,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,cAAc;KAC5B;IACD;QACE,GAAG,EAAE,uCAAuC;QAC5C,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,qCAAqC;KACnD;IACD;QACE,GAAG,EAAE,6BAA6B;QAClC,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,6BAA6B;KAC3C;CACF,CAAC;AAEF,2CAA2C;AAC3C,MAAM,UAAU,2BAA2B,CAAC,MAAiB,EAAE,GAAc;IAC3E,KAAK,MAAM,OAAO,IAAI,oBAAoB,EAAE,CAAC;QAC3C,MAAM,CAAC,gBAAgB,CACrB,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,GAAG,EACX;YACE,KAAK,EAAE,OAAO,CAAC,IAAI;YACnB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,eAAe;SAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1E,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,QAAQ,EAAE,eAAe;wBACzB,IAAI;qBACL;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,uCAAuC;AACvC,MAAM,CAAC,MAAM,6BAA6B,GAAG,oBAAoB,CAAC"}
@@ -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"}