yuque-ai-mcp 2.7.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.
Files changed (316) hide show
  1. package/dist/board/create-board.d.ts +7 -0
  2. package/dist/board/create-board.js +50 -0
  3. package/dist/board/create-board.js.map +1 -0
  4. package/dist/board/get-board.d.ts +7 -0
  5. package/dist/board/get-board.js +44 -0
  6. package/dist/board/get-board.js.map +1 -0
  7. package/dist/board/index.d.ts +5 -0
  8. package/dist/board/index.js +8 -0
  9. package/dist/board/index.js.map +1 -0
  10. package/dist/board/update-board.d.ts +7 -0
  11. package/dist/board/update-board.js +65 -0
  12. package/dist/board/update-board.js.map +1 -0
  13. package/dist/cli-http.d.ts +2 -0
  14. package/dist/cli-http.js +16 -0
  15. package/dist/cli-http.js.map +1 -0
  16. package/dist/cli.d.ts +2 -0
  17. package/dist/cli.js +15 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/common/api-client.d.ts +27 -0
  20. package/dist/common/api-client.js +198 -0
  21. package/dist/common/api-client.js.map +1 -0
  22. package/dist/common/config.d.ts +46 -0
  23. package/dist/common/config.js +86 -0
  24. package/dist/common/config.js.map +1 -0
  25. package/dist/common/copy-common.d.ts +8 -0
  26. package/dist/common/copy-common.js +13 -0
  27. package/dist/common/copy-common.js.map +1 -0
  28. package/dist/common/errors.d.ts +44 -0
  29. package/dist/common/errors.js +164 -0
  30. package/dist/common/errors.js.map +1 -0
  31. package/dist/common/export-common.d.ts +32 -0
  32. package/dist/common/export-common.js +125 -0
  33. package/dist/common/export-common.js.map +1 -0
  34. package/dist/common/format.d.ts +247 -0
  35. package/dist/common/format.js +199 -0
  36. package/dist/common/format.js.map +1 -0
  37. package/dist/common/register-tools.d.ts +29 -0
  38. package/dist/common/register-tools.js +89 -0
  39. package/dist/common/register-tools.js.map +1 -0
  40. package/dist/common/repo-capacity.d.ts +26 -0
  41. package/dist/common/repo-capacity.js +105 -0
  42. package/dist/common/repo-capacity.js.map +1 -0
  43. package/dist/common/schedule-common.d.ts +38 -0
  44. package/dist/common/schedule-common.js +111 -0
  45. package/dist/common/schedule-common.js.map +1 -0
  46. package/dist/common/text-utils.d.ts +11 -0
  47. package/dist/common/text-utils.js +29 -0
  48. package/dist/common/text-utils.js.map +1 -0
  49. package/dist/common/toc-cache.d.ts +30 -0
  50. package/dist/common/toc-cache.js +109 -0
  51. package/dist/common/toc-cache.js.map +1 -0
  52. package/dist/common/types.d.ts +17 -0
  53. package/dist/common/types.js +3 -0
  54. package/dist/common/types.js.map +1 -0
  55. package/dist/common/validate.d.ts +27 -0
  56. package/dist/common/validate.js +70 -0
  57. package/dist/common/validate.js.map +1 -0
  58. package/dist/common/web-request.d.ts +13 -0
  59. package/dist/common/web-request.js +53 -0
  60. package/dist/common/web-request.js.map +1 -0
  61. package/dist/crawler/extract.d.ts +19 -0
  62. package/dist/crawler/extract.js +220 -0
  63. package/dist/crawler/extract.js.map +1 -0
  64. package/dist/crawler/fetch.d.ts +8 -0
  65. package/dist/crawler/fetch.js +89 -0
  66. package/dist/crawler/fetch.js.map +1 -0
  67. package/dist/crawler/index.d.ts +6 -0
  68. package/dist/crawler/index.js +10 -0
  69. package/dist/crawler/index.js.map +1 -0
  70. package/dist/crawler/save.d.ts +11 -0
  71. package/dist/crawler/save.js +160 -0
  72. package/dist/crawler/save.js.map +1 -0
  73. package/dist/crawler/schedule.d.ts +12 -0
  74. package/dist/crawler/schedule.js +132 -0
  75. package/dist/crawler/schedule.js.map +1 -0
  76. package/dist/doc/batch-get-docs.d.ts +8 -0
  77. package/dist/doc/batch-get-docs.js +100 -0
  78. package/dist/doc/batch-get-docs.js.map +1 -0
  79. package/dist/doc/copy-doc.d.ts +10 -0
  80. package/dist/doc/copy-doc.js +238 -0
  81. package/dist/doc/copy-doc.js.map +1 -0
  82. package/dist/doc/create-doc.d.ts +11 -0
  83. package/dist/doc/create-doc.js +82 -0
  84. package/dist/doc/create-doc.js.map +1 -0
  85. package/dist/doc/delete-doc.d.ts +8 -0
  86. package/dist/doc/delete-doc.js +39 -0
  87. package/dist/doc/delete-doc.js.map +1 -0
  88. package/dist/doc/diff-doc.d.ts +8 -0
  89. package/dist/doc/diff-doc.js +190 -0
  90. package/dist/doc/diff-doc.js.map +1 -0
  91. package/dist/doc/embed-url.d.ts +10 -0
  92. package/dist/doc/embed-url.js +137 -0
  93. package/dist/doc/embed-url.js.map +1 -0
  94. package/dist/doc/export-doc.d.ts +10 -0
  95. package/dist/doc/export-doc.js +135 -0
  96. package/dist/doc/export-doc.js.map +1 -0
  97. package/dist/doc/get-doc.d.ts +8 -0
  98. package/dist/doc/get-doc.js +40 -0
  99. package/dist/doc/get-doc.js.map +1 -0
  100. package/dist/doc/import-file-utils.d.ts +37 -0
  101. package/dist/doc/import-file-utils.js +256 -0
  102. package/dist/doc/import-file-utils.js.map +1 -0
  103. package/dist/doc/import-file.d.ts +13 -0
  104. package/dist/doc/import-file.js +333 -0
  105. package/dist/doc/import-file.js.map +1 -0
  106. package/dist/doc/import-url.d.ts +7 -0
  107. package/dist/doc/import-url.js +245 -0
  108. package/dist/doc/import-url.js.map +1 -0
  109. package/dist/doc/index.d.ts +16 -0
  110. package/dist/doc/index.js +30 -0
  111. package/dist/doc/index.js.map +1 -0
  112. package/dist/doc/list-docs.d.ts +8 -0
  113. package/dist/doc/list-docs.js +44 -0
  114. package/dist/doc/list-docs.js.map +1 -0
  115. package/dist/doc/update-doc.d.ts +8 -0
  116. package/dist/doc/update-doc.js +50 -0
  117. package/dist/doc/update-doc.js.map +1 -0
  118. package/dist/doc/version-detail.d.ts +8 -0
  119. package/dist/doc/version-detail.js +34 -0
  120. package/dist/doc/version-detail.js.map +1 -0
  121. package/dist/doc/versions.d.ts +8 -0
  122. package/dist/doc/versions.js +34 -0
  123. package/dist/doc/versions.js.map +1 -0
  124. package/dist/group/delete-user.d.ts +8 -0
  125. package/dist/group/delete-user.js +39 -0
  126. package/dist/group/delete-user.js.map +1 -0
  127. package/dist/group/index.d.ts +5 -0
  128. package/dist/group/index.js +8 -0
  129. package/dist/group/index.js.map +1 -0
  130. package/dist/group/list-users.d.ts +8 -0
  131. package/dist/group/list-users.js +40 -0
  132. package/dist/group/list-users.js.map +1 -0
  133. package/dist/group/update-user.d.ts +8 -0
  134. package/dist/group/update-user.js +37 -0
  135. package/dist/group/update-user.js.map +1 -0
  136. package/dist/http.d.ts +1 -0
  137. package/dist/http.js +114 -0
  138. package/dist/http.js.map +1 -0
  139. package/dist/index.d.ts +1 -0
  140. package/dist/index.js +27 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/kv/common.d.ts +34 -0
  143. package/dist/kv/common.js +191 -0
  144. package/dist/kv/common.js.map +1 -0
  145. package/dist/kv/delete.d.ts +7 -0
  146. package/dist/kv/delete.js +52 -0
  147. package/dist/kv/delete.js.map +1 -0
  148. package/dist/kv/get.d.ts +7 -0
  149. package/dist/kv/get.js +52 -0
  150. package/dist/kv/get.js.map +1 -0
  151. package/dist/kv/index.d.ts +6 -0
  152. package/dist/kv/index.js +10 -0
  153. package/dist/kv/index.js.map +1 -0
  154. package/dist/kv/list.d.ts +5 -0
  155. package/dist/kv/list.js +42 -0
  156. package/dist/kv/list.js.map +1 -0
  157. package/dist/kv/set.d.ts +7 -0
  158. package/dist/kv/set.js +54 -0
  159. package/dist/kv/set.js.map +1 -0
  160. package/dist/mine/common.d.ts +4 -0
  161. package/dist/mine/common.js +5 -0
  162. package/dist/mine/common.js.map +1 -0
  163. package/dist/mine/editor-center.d.ts +9 -0
  164. package/dist/mine/editor-center.js +57 -0
  165. package/dist/mine/editor-center.js.map +1 -0
  166. package/dist/mine/get-book-stacks.d.ts +8 -0
  167. package/dist/mine/get-book-stacks.js +41 -0
  168. package/dist/mine/get-book-stacks.js.map +1 -0
  169. package/dist/mine/index.d.ts +4 -0
  170. package/dist/mine/index.js +6 -0
  171. package/dist/mine/index.js.map +1 -0
  172. package/dist/note/create-note.d.ts +8 -0
  173. package/dist/note/create-note.js +32 -0
  174. package/dist/note/create-note.js.map +1 -0
  175. package/dist/note/get-note.d.ts +8 -0
  176. package/dist/note/get-note.js +27 -0
  177. package/dist/note/get-note.js.map +1 -0
  178. package/dist/note/index.d.ts +6 -0
  179. package/dist/note/index.js +10 -0
  180. package/dist/note/index.js.map +1 -0
  181. package/dist/note/list-notes.d.ts +8 -0
  182. package/dist/note/list-notes.js +40 -0
  183. package/dist/note/list-notes.js.map +1 -0
  184. package/dist/note/update-note.d.ts +8 -0
  185. package/dist/note/update-note.js +53 -0
  186. package/dist/note/update-note.js.map +1 -0
  187. package/dist/recycle/common.d.ts +4 -0
  188. package/dist/recycle/common.js +5 -0
  189. package/dist/recycle/common.js.map +1 -0
  190. package/dist/recycle/destroy-recycle.d.ts +8 -0
  191. package/dist/recycle/destroy-recycle.js +38 -0
  192. package/dist/recycle/destroy-recycle.js.map +1 -0
  193. package/dist/recycle/index.d.ts +5 -0
  194. package/dist/recycle/index.js +8 -0
  195. package/dist/recycle/index.js.map +1 -0
  196. package/dist/recycle/list-recycles.d.ts +8 -0
  197. package/dist/recycle/list-recycles.js +57 -0
  198. package/dist/recycle/list-recycles.js.map +1 -0
  199. package/dist/recycle/restore-recycle.d.ts +7 -0
  200. package/dist/recycle/restore-recycle.js +32 -0
  201. package/dist/recycle/restore-recycle.js.map +1 -0
  202. package/dist/repo/batch-get-repos.d.ts +8 -0
  203. package/dist/repo/batch-get-repos.js +83 -0
  204. package/dist/repo/batch-get-repos.js.map +1 -0
  205. package/dist/repo/copy-repo.d.ts +7 -0
  206. package/dist/repo/copy-repo.js +137 -0
  207. package/dist/repo/copy-repo.js.map +1 -0
  208. package/dist/repo/create-repo.d.ts +8 -0
  209. package/dist/repo/create-repo.js +49 -0
  210. package/dist/repo/create-repo.js.map +1 -0
  211. package/dist/repo/delete-repo.d.ts +8 -0
  212. package/dist/repo/delete-repo.js +37 -0
  213. package/dist/repo/delete-repo.js.map +1 -0
  214. package/dist/repo/export-graph.d.ts +21 -0
  215. package/dist/repo/export-graph.js +73 -0
  216. package/dist/repo/export-graph.js.map +1 -0
  217. package/dist/repo/export-index.d.ts +26 -0
  218. package/dist/repo/export-index.js +72 -0
  219. package/dist/repo/export-index.js.map +1 -0
  220. package/dist/repo/export-repo.d.ts +14 -0
  221. package/dist/repo/export-repo.js +243 -0
  222. package/dist/repo/export-repo.js.map +1 -0
  223. package/dist/repo/export-toc.d.ts +17 -0
  224. package/dist/repo/export-toc.js +33 -0
  225. package/dist/repo/export-toc.js.map +1 -0
  226. package/dist/repo/get-repo.d.ts +8 -0
  227. package/dist/repo/get-repo.js +32 -0
  228. package/dist/repo/get-repo.js.map +1 -0
  229. package/dist/repo/index.d.ts +10 -0
  230. package/dist/repo/index.js +18 -0
  231. package/dist/repo/index.js.map +1 -0
  232. package/dist/repo/list-repos.d.ts +8 -0
  233. package/dist/repo/list-repos.js +48 -0
  234. package/dist/repo/list-repos.js.map +1 -0
  235. package/dist/repo/update-repo.d.ts +8 -0
  236. package/dist/repo/update-repo.js +48 -0
  237. package/dist/repo/update-repo.js.map +1 -0
  238. package/dist/rss/dedup.d.ts +9 -0
  239. package/dist/rss/dedup.js +21 -0
  240. package/dist/rss/dedup.js.map +1 -0
  241. package/dist/rss/fetch-feed.d.ts +8 -0
  242. package/dist/rss/fetch-feed.js +290 -0
  243. package/dist/rss/fetch-feed.js.map +1 -0
  244. package/dist/rss/index.d.ts +5 -0
  245. package/dist/rss/index.js +8 -0
  246. package/dist/rss/index.js.map +1 -0
  247. package/dist/rss/list-sources.d.ts +8 -0
  248. package/dist/rss/list-sources.js +39 -0
  249. package/dist/rss/list-sources.js.map +1 -0
  250. package/dist/rss/parser.d.ts +27 -0
  251. package/dist/rss/parser.js +87 -0
  252. package/dist/rss/parser.js.map +1 -0
  253. package/dist/rss/schedule.d.ts +14 -0
  254. package/dist/rss/schedule.js +171 -0
  255. package/dist/rss/schedule.js.map +1 -0
  256. package/dist/rss/sources.d.ts +26 -0
  257. package/dist/rss/sources.js +54 -0
  258. package/dist/rss/sources.js.map +1 -0
  259. package/dist/search/index.d.ts +4 -0
  260. package/dist/search/index.js +6 -0
  261. package/dist/search/index.js.map +1 -0
  262. package/dist/search/rag-search-utils.d.ts +28 -0
  263. package/dist/search/rag-search-utils.js +74 -0
  264. package/dist/search/rag-search-utils.js.map +1 -0
  265. package/dist/search/rag-search.d.ts +16 -0
  266. package/dist/search/rag-search.js +103 -0
  267. package/dist/search/rag-search.js.map +1 -0
  268. package/dist/search/search.d.ts +8 -0
  269. package/dist/search/search.js +43 -0
  270. package/dist/search/search.js.map +1 -0
  271. package/dist/statistic/book-statistics.d.ts +7 -0
  272. package/dist/statistic/book-statistics.js +49 -0
  273. package/dist/statistic/book-statistics.js.map +1 -0
  274. package/dist/statistic/doc-statistics.d.ts +7 -0
  275. package/dist/statistic/doc-statistics.js +53 -0
  276. package/dist/statistic/doc-statistics.js.map +1 -0
  277. package/dist/statistic/group-statistics.d.ts +8 -0
  278. package/dist/statistic/group-statistics.js +30 -0
  279. package/dist/statistic/group-statistics.js.map +1 -0
  280. package/dist/statistic/index.d.ts +6 -0
  281. package/dist/statistic/index.js +10 -0
  282. package/dist/statistic/index.js.map +1 -0
  283. package/dist/statistic/member-statistics.d.ts +7 -0
  284. package/dist/statistic/member-statistics.js +49 -0
  285. package/dist/statistic/member-statistics.js.map +1 -0
  286. package/dist/toc/batch-update.d.ts +11 -0
  287. package/dist/toc/batch-update.js +274 -0
  288. package/dist/toc/batch-update.js.map +1 -0
  289. package/dist/toc/get-toc.d.ts +8 -0
  290. package/dist/toc/get-toc.js +33 -0
  291. package/dist/toc/get-toc.js.map +1 -0
  292. package/dist/toc/index.d.ts +5 -0
  293. package/dist/toc/index.js +8 -0
  294. package/dist/toc/index.js.map +1 -0
  295. package/dist/toc/update-toc.d.ts +8 -0
  296. package/dist/toc/update-toc.js +74 -0
  297. package/dist/toc/update-toc.js.map +1 -0
  298. package/dist/upload/index.d.ts +3 -0
  299. package/dist/upload/index.js +4 -0
  300. package/dist/upload/index.js.map +1 -0
  301. package/dist/upload/upload-attachment.d.ts +11 -0
  302. package/dist/upload/upload-attachment.js +162 -0
  303. package/dist/upload/upload-attachment.js.map +1 -0
  304. package/dist/user/get-groups.d.ts +8 -0
  305. package/dist/user/get-groups.js +41 -0
  306. package/dist/user/get-groups.js.map +1 -0
  307. package/dist/user/get-user.d.ts +8 -0
  308. package/dist/user/get-user.js +24 -0
  309. package/dist/user/get-user.js.map +1 -0
  310. package/dist/user/hello.d.ts +8 -0
  311. package/dist/user/hello.js +17 -0
  312. package/dist/user/hello.js.map +1 -0
  313. package/dist/user/index.d.ts +5 -0
  314. package/dist/user/index.js +8 -0
  315. package/dist/user/index.js.map +1 -0
  316. package/package.json +49 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * common/text-utils — 文本处理工具函数
3
+ *
4
+ * 被多个模块共享的文本处理函数:
5
+ * - unescapeHtml:HTML 实体解码
6
+ * - escapeHtml:HTML 转义
7
+ */
8
+ /** HTML 实体 → 原始字符 */
9
+ export function unescapeHtml(text) {
10
+ return text
11
+ .replace(/&/g, "&")
12
+ .replace(/&lt;/g, "<")
13
+ .replace(/&gt;/g, ">")
14
+ .replace(/&quot;/g, '"')
15
+ .replace(/&#39;/g, "'")
16
+ .replace(/&apos;/g, "'")
17
+ .replace(/&#x27;/g, "'")
18
+ .replace(/&#x2F;/g, "/")
19
+ .replace(/&nbsp;/g, " ");
20
+ }
21
+ /** 原始字符 → HTML 实体 */
22
+ export function escapeHtml(str) {
23
+ return str
24
+ .replace(/&/g, "&amp;")
25
+ .replace(/</g, "&lt;")
26
+ .replace(/>/g, "&gt;")
27
+ .replace(/"/g, "&quot;");
28
+ }
29
+ //# sourceMappingURL=text-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-utils.js","sourceRoot":"","sources":["../../src/common/text-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qBAAqB;AACrB,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * common/toc-cache — TOC 缓存与目录操作公共逻辑
3
+ *
4
+ * 职责:TOC 缓存(24h TTL + 定时清理)、目录创建/查找。
5
+ * copy-doc 和 batch-update-toc 共用。
6
+ */
7
+ /** 获取知识库 TOC(优先缓存,24h TTL) */
8
+ export declare function getTocCached(bookId: string): Promise<Array<Record<string, unknown>>>;
9
+ /** 使缓存失效(写操作后调用) */
10
+ export declare function invalidateTocCache(bookId: string): void;
11
+ /** 在 TOC 中查找 TITLE 节点(按名称 + 可选父节点) */
12
+ export declare function findTitleNode(nodes: Array<Record<string, unknown>>, title: string, parentUuid?: string): Record<string, unknown> | undefined;
13
+ /**
14
+ * 确保目录存在:有则复用 uuid,无则创建。
15
+ * PUT 返回完整 TOC,直接从中提取 uuid 并更新缓存,不额外 GET。
16
+ */
17
+ export declare function ensureTitle(bookId: string, title: string, parentUuid?: string): Promise<{
18
+ uuid: string;
19
+ created: boolean;
20
+ }>;
21
+ /**
22
+ * 确保目录路径存在(多层级),返回最末端节点 uuid。
23
+ * 用于 copy-doc 等需要 "Java/Spring/Boot" 路径的场景。
24
+ */
25
+ export declare function ensureDirectoryPath(bookId: string, path: string): Promise<string | null>;
26
+ /** 解析 target:支持 target_uuid 或 target_title */
27
+ export declare function resolveTarget(bookId: string, op: {
28
+ target_uuid?: string;
29
+ target_title?: string;
30
+ }): Promise<string | undefined>;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * common/toc-cache — TOC 缓存与目录操作公共逻辑
3
+ *
4
+ * 职责:TOC 缓存(24h TTL + 定时清理)、目录创建/查找。
5
+ * copy-doc 和 batch-update-toc 共用。
6
+ */
7
+ import { apiGet, apiPut, isErrorResult } from "./api-client.js";
8
+ const tocCache = new Map();
9
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 1 天
10
+ // 每小时清理过期缓存
11
+ const CLEANUP_INTERVAL = 60 * 60 * 1000;
12
+ const cleanupTimer = setInterval(() => {
13
+ const now = Date.now();
14
+ for (const [key, entry] of tocCache) {
15
+ if (entry.expiresAt <= now)
16
+ tocCache.delete(key);
17
+ }
18
+ }, CLEANUP_INTERVAL);
19
+ if (cleanupTimer && typeof cleanupTimer === "object" && "unref" in cleanupTimer) {
20
+ cleanupTimer.unref();
21
+ }
22
+ /** 获取知识库 TOC(优先缓存,24h TTL) */
23
+ export async function getTocCached(bookId) {
24
+ const cached = tocCache.get(bookId);
25
+ if (cached && cached.expiresAt > Date.now()) {
26
+ return cached.nodes;
27
+ }
28
+ const data = await apiGet(`/repos/${bookId}/toc`, undefined, "Get TOC (cached)");
29
+ if (isErrorResult(data)) {
30
+ return [];
31
+ }
32
+ const nodes = data.data || [];
33
+ tocCache.set(bookId, { nodes, expiresAt: Date.now() + CACHE_TTL_MS });
34
+ return nodes;
35
+ }
36
+ /** 使缓存失效(写操作后调用) */
37
+ export function invalidateTocCache(bookId) {
38
+ tocCache.delete(bookId);
39
+ }
40
+ // ─── 目录查找 ────────────────────────────────────────────
41
+ /** 在 TOC 中查找 TITLE 节点(按名称 + 可选父节点) */
42
+ export function findTitleNode(nodes, title, parentUuid) {
43
+ return nodes.find((n) => n.type === "TITLE" &&
44
+ n.title === title &&
45
+ (parentUuid ? n.parent_uuid === parentUuid : !n.parent_uuid));
46
+ }
47
+ // ─── 目录创建/复用 ────────────────────────────────────────
48
+ /**
49
+ * 确保目录存在:有则复用 uuid,无则创建。
50
+ * PUT 返回完整 TOC,直接从中提取 uuid 并更新缓存,不额外 GET。
51
+ */
52
+ export async function ensureTitle(bookId, title, parentUuid) {
53
+ const nodes = await getTocCached(bookId);
54
+ const existing = findTitleNode(nodes, title, parentUuid);
55
+ if (existing) {
56
+ return { uuid: existing.uuid, created: false };
57
+ }
58
+ const payload = {
59
+ action: "appendNode",
60
+ action_mode: "child",
61
+ type: "TITLE",
62
+ title,
63
+ };
64
+ if (parentUuid)
65
+ payload.target_uuid = parentUuid;
66
+ const data = await apiPut(`/repos/${bookId}/toc`, payload, `Create TITLE: ${title}`);
67
+ if (isErrorResult(data)) {
68
+ throw new Error(`创建目录失败: ${title}`);
69
+ }
70
+ const tocNodes = data.data || [];
71
+ tocCache.set(bookId, { nodes: tocNodes, expiresAt: Date.now() + CACHE_TTL_MS });
72
+ const created = tocNodes.find((n) => n.type === "TITLE" && n.title === title &&
73
+ (parentUuid ? n.parent_uuid === parentUuid : !n.parent_uuid));
74
+ if (!created?.uuid)
75
+ throw new Error(`创建目录后找不到: ${title}`);
76
+ return { uuid: created.uuid, created: true };
77
+ }
78
+ /**
79
+ * 确保目录路径存在(多层级),返回最末端节点 uuid。
80
+ * 用于 copy-doc 等需要 "Java/Spring/Boot" 路径的场景。
81
+ */
82
+ export async function ensureDirectoryPath(bookId, path) {
83
+ const parts = path.split("/").filter(Boolean);
84
+ let parentUuid;
85
+ for (const part of parts) {
86
+ try {
87
+ const { uuid } = await ensureTitle(bookId, part, parentUuid);
88
+ parentUuid = uuid;
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ return parentUuid || null;
95
+ }
96
+ /** 解析 target:支持 target_uuid 或 target_title */
97
+ export async function resolveTarget(bookId, op) {
98
+ if (op.target_uuid)
99
+ return op.target_uuid;
100
+ if (op.target_title) {
101
+ const nodes = await getTocCached(bookId);
102
+ const node = findTitleNode(nodes, op.target_title);
103
+ if (!node)
104
+ throw new Error(`找不到 TITLE: ${op.target_title}`);
105
+ return node.uuid;
106
+ }
107
+ return undefined;
108
+ }
109
+ //# sourceMappingURL=toc-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toc-cache.js","sourceRoot":"","sources":["../../src/common/toc-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** 公共类型定义 — 所有工具模块共享 */
2
+ export interface McpTool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema?: {
6
+ type: "object";
7
+ properties: Record<string, any>;
8
+ required?: string[];
9
+ };
10
+ handler(args?: Record<string, unknown>): Promise<{
11
+ content?: Array<{
12
+ type: "text";
13
+ text: string;
14
+ }>;
15
+ isError?: boolean;
16
+ }> | Promise<unknown>;
17
+ }
@@ -0,0 +1,3 @@
1
+ /** 公共类型定义 — 所有工具模块共享 */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,wBAAwB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * validate — 轻量参数校验
3
+ *
4
+ * 不引入 zod/ajv,用简单函数保证运行时安全。
5
+ * 校验失败返回 MCP error 对象,通过返回 null 表示通过。
6
+ * 错误信息:中文 + English 双语。
7
+ */
8
+ type ErrorResult = {
9
+ content: Array<{
10
+ type: "text";
11
+ text: string;
12
+ }>;
13
+ isError: true;
14
+ };
15
+ /** 非空字符串 */
16
+ export declare function requiredString(value: unknown, name: string): ErrorResult | null;
17
+ /** 可选字符串(有值时不能为空) */
18
+ export declare function optionalString(value: unknown, name: string): ErrorResult | null;
19
+ /** 正整数 */
20
+ export declare function positiveInt(value: unknown, name: string): ErrorResult | null;
21
+ /** 数值上限 */
22
+ export declare function maxValue(value: unknown, name: string, max: number): ErrorResult | null;
23
+ /** 枚举值 */
24
+ export declare function oneOf(value: unknown, name: string, allowed: readonly (string | number)[]): ErrorResult | null;
25
+ /** 批量校验,返回第一个失败的结果 */
26
+ export declare function check(...results: (ErrorResult | null)[]): ErrorResult | null;
27
+ export {};
@@ -0,0 +1,70 @@
1
+ /**
2
+ * validate — 轻量参数校验
3
+ *
4
+ * 不引入 zod/ajv,用简单函数保证运行时安全。
5
+ * 校验失败返回 MCP error 对象,通过返回 null 表示通过。
6
+ * 错误信息:中文 + English 双语。
7
+ */
8
+ function fail(msgCn, msgEn) {
9
+ return {
10
+ content: [{ type: "text", text: JSON.stringify({
11
+ error: `${msgCn} / ${msgEn}`,
12
+ hint: "zh/en",
13
+ }, null, 2) }],
14
+ isError: true,
15
+ };
16
+ }
17
+ /** 非空字符串 */
18
+ export function requiredString(value, name) {
19
+ if (value === undefined || value === null)
20
+ return fail(`${name} 是必填参数`, `${name} is required`);
21
+ if (typeof value !== "string")
22
+ return fail(`${name} 必须是字符串`, `${name} must be a string`);
23
+ if (value.trim() === "")
24
+ return fail(`${name} 不能为空`, `${name} cannot be empty`);
25
+ return null;
26
+ }
27
+ /** 可选字符串(有值时不能为空) */
28
+ export function optionalString(value, name) {
29
+ if (value === undefined || value === null)
30
+ return null;
31
+ if (typeof value !== "string")
32
+ return fail(`${name} 必须是字符串`, `${name} must be a string`);
33
+ return null;
34
+ }
35
+ /** 正整数 */
36
+ export function positiveInt(value, name) {
37
+ if (value === undefined || value === null)
38
+ return null;
39
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
40
+ return fail(`${name} 必须是正整数`, `${name} must be a positive integer`);
41
+ }
42
+ return null;
43
+ }
44
+ /** 数值上限 */
45
+ export function maxValue(value, name, max) {
46
+ if (value === undefined || value === null)
47
+ return null;
48
+ if (typeof value !== "number" || value > max) {
49
+ return fail(`${name} 不能超过 ${max}`, `${name} must be ≤ ${max}`);
50
+ }
51
+ return null;
52
+ }
53
+ /** 枚举值 */
54
+ export function oneOf(value, name, allowed) {
55
+ if (value === undefined || value === null)
56
+ return null;
57
+ if (!allowed.includes(value)) {
58
+ return fail(`${name} 取值必须为: ${allowed.join(", ")}`, `${name} must be one of: ${allowed.join(", ")}`);
59
+ }
60
+ return null;
61
+ }
62
+ /** 批量校验,返回第一个失败的结果 */
63
+ export function check(...results) {
64
+ for (const r of results) {
65
+ if (r !== null)
66
+ return r;
67
+ }
68
+ return null;
69
+ }
70
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/common/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * common/web-request — 语雀 Web API 请求(Cookie 认证)
3
+ *
4
+ * 适用于 /api/mine/* 路径的 Web API,需要 Cookie 登录态。
5
+ * 配置:config/config.json 中的 cookie 和 ctoken 字段
6
+ *
7
+ * 统一 mine 和 recycle 域共用的请求层,消除重复代码。
8
+ */
9
+ export declare function webRequest(url: string, opts?: {
10
+ method?: "GET" | "PUT" | "DELETE";
11
+ body?: unknown;
12
+ referer?: string;
13
+ }): Promise<unknown>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * common/web-request — 语雀 Web API 请求(Cookie 认证)
3
+ *
4
+ * 适用于 /api/mine/* 路径的 Web API,需要 Cookie 登录态。
5
+ * 配置:config/config.json 中的 cookie 和 ctoken 字段
6
+ *
7
+ * 统一 mine 和 recycle 域共用的请求层,消除重复代码。
8
+ */
9
+ import { loadConfig } from "./config.js";
10
+ export async function webRequest(url, opts = {}) {
11
+ const cfg = loadConfig();
12
+ const cookie = cfg.cookie || "";
13
+ const ctoken = cfg.ctoken || "";
14
+ if (!cookie || !ctoken) {
15
+ throw new Error("此 API 需要 Cookie 登录态,请在 config/config.json 中配置 cookie 和 ctoken 字段。" +
16
+ "获取方式:浏览器打开 yuque.com 登录 → F12 → Application → Cookies → 复制 _yuque_session 和 yuque_ctoken");
17
+ }
18
+ const headers = {
19
+ "Accept": "application/json",
20
+ "Content-Type": "application/json",
21
+ "Cookie": cookie,
22
+ "x-csrf-token": ctoken,
23
+ "Referer": opts.referer || "https://www.yuque.com/dashboard/books",
24
+ "User-Agent": "Mozilla/5.0",
25
+ };
26
+ const controller = new AbortController();
27
+ const timer = setTimeout(() => controller.abort(), 30_000);
28
+ try {
29
+ const res = await fetch(url, {
30
+ method: opts.method || "GET",
31
+ headers,
32
+ body: opts.body ? JSON.stringify(opts.body) : undefined,
33
+ signal: controller.signal,
34
+ });
35
+ const text = await res.text();
36
+ if (!res.ok) {
37
+ let msg = `语雀 Web API 错误 [${res.status}]`;
38
+ try {
39
+ const err = JSON.parse(text);
40
+ msg += `: ${err.message || text.slice(0, 200)}`;
41
+ }
42
+ catch {
43
+ msg += `: ${text.slice(0, 200)}`;
44
+ }
45
+ throw new Error(msg);
46
+ }
47
+ return JSON.parse(text);
48
+ }
49
+ finally {
50
+ clearTimeout(timer);
51
+ }
52
+ }
53
+ //# sourceMappingURL=web-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-request.js","sourceRoot":"","sources":["../../src/common/web-request.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAW,EACX,OAAgF,EAAE;IAElF,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;IAEhC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,mEAAmE;YACnE,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,QAAQ,EAAE,kBAAkB;QAC5B,cAAc,EAAE,kBAAkB;QAClC,QAAQ,EAAE,MAAM;QAChB,cAAc,EAAE,MAAM;QACtB,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,uCAAuC;QAClE,YAAY,EAAE,aAAa;KAC5B,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;YACvD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,GAAG,GAAG,kBAAkB,GAAG,CAAC,MAAM,GAAG,CAAC;YAC1C,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,GAAG,IAAI,KAAK,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACnC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * crawler/extract — CSS 选择器提取
3
+ *
4
+ * 职责:传入 HTML 字符串 + CSS 选择器,提取文本/属性/HTML。
5
+ * 使用简单的正则 + 字符串解析,不依赖 jsdom(保持零外部依赖)。
6
+ *
7
+ * 支持的选择器:
8
+ * - tag: "div", "p", "a", "h1" 等
9
+ * - .class: ".content", ".article-title"
10
+ * - #id: "#main"
11
+ * - tag.class: "div.content", "a.link"
12
+ * - [attr]: "[href]", "[data-id]"
13
+ * - 组合: "div.content a.link"
14
+ *
15
+ * 限制:不支持伪类 (:nth-child)、属性值匹配 ([attr=val])、兄弟选择器 (+/~)。
16
+ * 复杂场景建议 Agent 用 yuque_crawl_fetch 拿 HTML 后自行解析。
17
+ */
18
+ import type { McpTool } from "../common/types.js";
19
+ export declare const crawlExtract: McpTool;
@@ -0,0 +1,220 @@
1
+ /**
2
+ * crawler/extract — CSS 选择器提取
3
+ *
4
+ * 职责:传入 HTML 字符串 + CSS 选择器,提取文本/属性/HTML。
5
+ * 使用简单的正则 + 字符串解析,不依赖 jsdom(保持零外部依赖)。
6
+ *
7
+ * 支持的选择器:
8
+ * - tag: "div", "p", "a", "h1" 等
9
+ * - .class: ".content", ".article-title"
10
+ * - #id: "#main"
11
+ * - tag.class: "div.content", "a.link"
12
+ * - [attr]: "[href]", "[data-id]"
13
+ * - 组合: "div.content a.link"
14
+ *
15
+ * 限制:不支持伪类 (:nth-child)、属性值匹配 ([attr=val])、兄弟选择器 (+/~)。
16
+ * 复杂场景建议 Agent 用 yuque_crawl_fetch 拿 HTML 后自行解析。
17
+ */
18
+ import { check, requiredString } from "../common/validate.js";
19
+ import { unescapeHtml } from "../common/text-utils.js";
20
+ function parseSelector(selector) {
21
+ return selector
22
+ .split(/\s+/)
23
+ .filter(Boolean)
24
+ .map((part) => {
25
+ const result = { tag: "", cls: "", id: "", attr: "" };
26
+ // [attr]
27
+ const attrMatch = part.match(/^\[([^\]]+)\]$/);
28
+ if (attrMatch) {
29
+ result.attr = attrMatch[1];
30
+ return result;
31
+ }
32
+ // #id
33
+ const idMatch = part.match(/#([\w-]+)/);
34
+ if (idMatch)
35
+ result.id = idMatch[1];
36
+ // .class (可能有多个)
37
+ const clsMatches = part.match(/\.([\w-]+)/g);
38
+ if (clsMatches)
39
+ result.cls = clsMatches.map((c) => c.slice(1)).join(" ");
40
+ // tag
41
+ const tagMatch = part.match(/^([\w-]+)/);
42
+ if (tagMatch)
43
+ result.tag = tagMatch[1].toLowerCase();
44
+ return result;
45
+ });
46
+ }
47
+ /** 检查元素是否匹配选择器片段 */
48
+ function matchesPart(el, part) {
49
+ if (part.tag && !el.startsWith(`<${part.tag}`))
50
+ return false;
51
+ if (part.id && !el.includes(`id="${part.id}"`) && !el.includes(`id='${part.id}'`))
52
+ return false;
53
+ if (part.cls) {
54
+ const clsParts = part.cls.split(" ");
55
+ for (const c of clsParts) {
56
+ if (!el.includes(`class="${c}"`) && !el.includes(`class='${c}'`) &&
57
+ !el.match(new RegExp(`class="[^"]*\\b${c}\\b[^"]*"`)) &&
58
+ !el.match(new RegExp(`class='[^']*\\b${c}\\b[^']*'`))) {
59
+ return false;
60
+ }
61
+ }
62
+ }
63
+ if (part.attr && !el.includes(`${part.attr}=`))
64
+ return false;
65
+ return true;
66
+ }
67
+ /** 提取元素的属性 */
68
+ function extractAttrs(el) {
69
+ const attrs = {};
70
+ const attrRe = /(\w[\w-]*)=["']([^"']*)["']/g;
71
+ let m;
72
+ while ((m = attrRe.exec(el)) !== null) {
73
+ attrs[m[1]] = m[2];
74
+ }
75
+ return attrs;
76
+ }
77
+ /** 提取元素的文本内容(去除标签) */
78
+ function extractText(el) {
79
+ return unescapeHtml(el.replace(/<[^>]*>/g, "")
80
+ .replace(/\s+/g, " ")).trim();
81
+ }
82
+ /**
83
+ * 在 HTML 中查找匹配选择器的所有元素
84
+ * 策略:先按最后一个选择器部分找候选元素,再向上验证父级匹配
85
+ */
86
+ function findAll(html, parts) {
87
+ if (parts.length === 0)
88
+ return [];
89
+ const lastPart = parts[parts.length - 1];
90
+ const parentParts = parts.slice(0, -1);
91
+ // 构建候选元素的正则
92
+ let tagPattern;
93
+ if (lastPart.tag) {
94
+ tagPattern = lastPart.tag;
95
+ }
96
+ else {
97
+ tagPattern = "\\w+";
98
+ }
99
+ const tagRe = new RegExp(`<(${tagPattern})(\\s[^>]*)?>([\\s\\S]*?)</\\1>`, "gi");
100
+ const results = [];
101
+ let m;
102
+ while ((m = tagRe.exec(html)) !== null) {
103
+ const fullTag = m[0];
104
+ if (!matchesPart(fullTag, lastPart))
105
+ continue;
106
+ // 检查父级匹配
107
+ if (parentParts.length > 0) {
108
+ const beforeText = html.substring(0, m.index);
109
+ if (!checkParents(beforeText, parentParts))
110
+ continue;
111
+ }
112
+ results.push(fullTag);
113
+ }
114
+ return results;
115
+ }
116
+ /** 检查 HTML 前缀中是否包含匹配的父级元素 */
117
+ function checkParents(beforeText, parts) {
118
+ // 从后往前匹配父级
119
+ const reversed = [...parts].reverse();
120
+ let remaining = beforeText;
121
+ for (const part of reversed) {
122
+ const tag = part.tag || "\\w+";
123
+ const openRe = new RegExp(`<(${tag})(\\s[^>]*)?>`, "gi");
124
+ const closeRe = new RegExp(`</(${tag})>`, "gi");
125
+ // 从末尾往前找,匹配开闭标签
126
+ let depth = 0;
127
+ let found = false;
128
+ const markers = [];
129
+ let m;
130
+ while ((m = openRe.exec(remaining)) !== null) {
131
+ markers.push({ pos: m.index, isOpen: true, raw: m[0] });
132
+ }
133
+ while ((m = closeRe.exec(remaining)) !== null) {
134
+ markers.push({ pos: m.index, isOpen: false, raw: m[0] });
135
+ }
136
+ markers.sort((a, b) => b.pos - a.pos); // 从后往前
137
+ for (const mk of markers) {
138
+ if (mk.isOpen) {
139
+ if (depth === 0 && matchesPart(mk.raw, part)) {
140
+ remaining = remaining.substring(0, mk.pos);
141
+ found = true;
142
+ break;
143
+ }
144
+ depth--;
145
+ }
146
+ else {
147
+ depth++;
148
+ }
149
+ }
150
+ if (!found)
151
+ return false;
152
+ }
153
+ return true;
154
+ }
155
+ export const crawlExtract = {
156
+ name: "yuque_crawl_extract",
157
+ description: "Extract content from HTML using CSS selectors (tag, .class, #id, [attr]). Returns text/html/attrs for each match. For complex selectors (:nth-child, etc.), Agent should parse raw HTML from yuque_crawl_fetch. 详见 references/api/extended_api.md",
158
+ inputSchema: {
159
+ type: "object",
160
+ properties: {
161
+ html: { type: "string", description: "Raw HTML string to extract from" },
162
+ selector: { type: "string", description: "CSS selector, e.g. 'div.content a.link', '.article-title', '#main'" },
163
+ attr: { type: "string", description: "Extract specific attribute value instead of text, e.g. 'href', 'src'" },
164
+ limit: { type: "number", description: "Max items to return (default 50, max 200)" },
165
+ raw: { type: "boolean", description: "Return raw full JSON (default false, returns summary)" },
166
+ },
167
+ required: ["html", "selector"],
168
+ },
169
+ async handler(args) {
170
+ const __v = check(requiredString(args?.html, "html"), requiredString(args?.selector, "selector"));
171
+ if (__v)
172
+ return __v;
173
+ const html = args?.html;
174
+ const selector = args?.selector;
175
+ const attr = args?.attr;
176
+ const limit = Math.min(args?.limit ?? 50, 200);
177
+ const parts = parseSelector(selector);
178
+ if (parts.length === 0) {
179
+ return {
180
+ content: [{ type: "text", text: JSON.stringify({
181
+ error: "INVALID_SELECTOR",
182
+ message: `无法解析选择器: ${selector}`,
183
+ }, null, 2) }],
184
+ isError: true,
185
+ };
186
+ }
187
+ const elements = findAll(html, parts).slice(0, limit);
188
+ const items = elements.map((el) => {
189
+ const attrs = extractAttrs(el);
190
+ return {
191
+ text: extractText(el),
192
+ html: el,
193
+ attrs,
194
+ };
195
+ });
196
+ // 如果指定了 attr,只返回属性值
197
+ if (attr) {
198
+ const attrItems = items.map((item) => item.attrs[attr] || null).filter(Boolean);
199
+ return {
200
+ content: [{
201
+ type: "text",
202
+ text: JSON.stringify({
203
+ selector,
204
+ attr,
205
+ count: attrItems.length,
206
+ values: attrItems,
207
+ }, null, 2),
208
+ }],
209
+ };
210
+ }
211
+ const result = { selector, count: items.length, items };
212
+ return {
213
+ content: [{
214
+ type: "text",
215
+ text: JSON.stringify(result, null, 2),
216
+ }],
217
+ };
218
+ },
219
+ };
220
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/crawler/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * crawler/fetch — HTTP 请求抓取网页原始 HTML
3
+ *
4
+ * 职责:发 HTTP GET 请求,返回原始 HTML + 响应头 + 状态码。
5
+ * 不做任何解析、提取、清洗。Agent 拿到原始 HTML 后自行决定下一步。
6
+ */
7
+ import type { McpTool } from "../common/types.js";
8
+ export declare const crawlFetch: McpTool;