@aigne/doc-smith 0.9.10 → 0.9.11-beta

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 (308) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +189 -219
  3. package/README.zh.md +270 -0
  4. package/agents/bash-executor/index.mjs +347 -0
  5. package/agents/clear/ai/intent.md +142 -0
  6. package/agents/clear/choose-contents.mjs +13 -65
  7. package/agents/clear/clear-auth-tokens.mjs +17 -21
  8. package/agents/clear/clear-deployment-config.mjs +33 -24
  9. package/agents/clear/index.yaml +1 -9
  10. package/agents/content-checker/ai/intent.md +209 -0
  11. package/agents/content-checker/clean-invalid-docs.mjs +254 -0
  12. package/agents/content-checker/index.mjs +191 -0
  13. package/agents/content-checker/validate-content.mjs +983 -0
  14. package/agents/generate-images/generate-image.yaml +75 -0
  15. package/agents/generate-images/generate-summary.mjs +213 -0
  16. package/agents/generate-images/index.yaml +39 -0
  17. package/agents/generate-images/prepare-generation.mjs +286 -0
  18. package/agents/generate-images/prepare-image-generation.mjs +130 -0
  19. package/{prompts/detail/diagram/generate-image-system.md → agents/generate-images/prompts/system.md} +22 -56
  20. package/agents/generate-images/prompts/user.md +85 -0
  21. package/agents/generate-images/save-image-result.mjs +247 -0
  22. package/agents/generate-images/scan-image-slots.mjs +247 -0
  23. package/agents/localize/index.yaml +19 -42
  24. package/{prompts/translate → agents/localize/prompts}/translate-document.md +0 -139
  25. package/agents/localize/translate-documents/generate-summary.mjs +163 -0
  26. package/agents/localize/translate-documents/load-glossary.mjs +52 -0
  27. package/agents/localize/translate-documents/prepare-translation.mjs +249 -0
  28. package/agents/localize/translate-documents/save-translation.mjs +171 -0
  29. package/agents/localize/translate-documents/translate-document-to-language.mjs +209 -0
  30. package/agents/localize/translate-documents/translate-document.yaml +23 -0
  31. package/agents/localize/translate-documents/translate-to-languages.yaml +10 -0
  32. package/agents/localize/translate-images/check-image-translation.mjs +225 -0
  33. package/agents/localize/translate-images/detect-text/detect-and-update-shared.mjs +148 -0
  34. package/agents/localize/translate-images/detect-text/detect-image-text.yaml +44 -0
  35. package/agents/localize/translate-images/detect-text/detect-images-text.yaml +21 -0
  36. package/agents/localize/translate-images/detect-text/prompts/detect-image-text-system.md +43 -0
  37. package/agents/localize/translate-images/detect-text/prompts/detect-image-text-user.md +14 -0
  38. package/agents/localize/translate-images/detect-text/save-text-detection.mjs +105 -0
  39. package/agents/localize/translate-images/prepare-image-input.mjs +124 -0
  40. package/agents/localize/translate-images/save-image-translation.mjs +172 -0
  41. package/agents/localize/translate-images/scan-doc-images.mjs +165 -0
  42. package/agents/localize/translate-images/translate-doc-images.yaml +24 -0
  43. package/agents/localize/{translate-diagram.yaml → translate-images/translate-image.yaml} +25 -14
  44. package/agents/publish/ai/intent.md +182 -0
  45. package/agents/publish/check.mjs +107 -0
  46. package/agents/publish/index.yaml +9 -14
  47. package/agents/publish/publish-docs.mjs +81 -61
  48. package/agents/publish/translate-meta.mjs +79 -58
  49. package/agents/save-document/index.mjs +260 -0
  50. package/agents/structure-checker/index.mjs +307 -0
  51. package/agents/structure-checker/validate-structure.mjs +477 -0
  52. package/agents/update-image/analyze-feedback.yaml +37 -0
  53. package/agents/update-image/index.yaml +78 -0
  54. package/agents/update-image/load-existing-image.mjs +211 -0
  55. package/agents/update-image/prompts/analyze-feedback-system.md +43 -0
  56. package/agents/update-image/prompts/analyze-feedback-user.md +15 -0
  57. package/aigne.yaml +26 -139
  58. package/package.json +16 -48
  59. package/scripts/README.md +90 -0
  60. package/scripts/install.sh +86 -0
  61. package/scripts/uninstall.sh +52 -0
  62. package/skills/doc-smith/SKILL.md +285 -0
  63. package/skills/doc-smith/ai/intent/sources-improve.md +290 -0
  64. package/skills/doc-smith/references/changeset-guide.md +171 -0
  65. package/skills/doc-smith/references/document-content-guide.md +214 -0
  66. package/skills/doc-smith/references/document-structure-schema.md +138 -0
  67. package/skills/doc-smith/references/patch-guide.md +96 -0
  68. package/skills/doc-smith/references/structure-confirmation-guide.md +133 -0
  69. package/skills/doc-smith/references/structure-planning-guide.md +149 -0
  70. package/skills/doc-smith/references/update-workflow.md +108 -0
  71. package/skills/doc-smith/references/user-intent-guide.md +175 -0
  72. package/skills/doc-smith/references/workspace-initialization.md +376 -0
  73. package/skills/doc-smith-docs-detail/SKILL.md +356 -0
  74. package/skills/doc-smith-docs-detail/ai/intent.md +271 -0
  75. package/skills-entry/doc-smith/ai/intent.md +260 -0
  76. package/skills-entry/doc-smith/index.mjs +66 -0
  77. package/skills-entry/doc-smith/prompt.md +57 -0
  78. package/skills-entry/doc-smith/utils.mjs +27 -0
  79. package/skills-entry/doc-smith-docs-detail/batch.yaml +56 -0
  80. package/skills-entry/doc-smith-docs-detail/index.mjs +95 -0
  81. package/skills-entry/doc-smith-docs-detail/prompt.md +64 -0
  82. package/utils/afs-factory.mjs +183 -0
  83. package/utils/agent-constants.mjs +97 -0
  84. package/utils/{auth-utils.mjs → auth.mjs} +6 -9
  85. package/{agents/utils/update-branding.mjs → utils/branding.mjs} +3 -4
  86. package/utils/config.mjs +261 -0
  87. package/utils/constants.mjs +32 -0
  88. package/utils/deploy.mjs +3 -3
  89. package/utils/docs-converter.mjs +454 -0
  90. package/utils/docs.mjs +212 -0
  91. package/utils/document-paths.mjs +172 -0
  92. package/utils/files.mjs +74 -0
  93. package/utils/git.mjs +65 -0
  94. package/utils/{blocklet.mjs → http.mjs} +18 -0
  95. package/utils/image-slots.mjs +57 -0
  96. package/utils/image-utils.mjs +114 -0
  97. package/utils/project.mjs +95 -0
  98. package/utils/sources-path-resolver.mjs +76 -0
  99. package/utils/{upload-files.mjs → upload.mjs} +3 -3
  100. package/utils/workspace.mjs +371 -0
  101. package/agents/chat/chat-system.md +0 -38
  102. package/agents/chat/index.mjs +0 -59
  103. package/agents/chat/skills/generate-document.yaml +0 -15
  104. package/agents/chat/skills/list-documents.mjs +0 -15
  105. package/agents/chat/skills/update-document.yaml +0 -24
  106. package/agents/clear/clear-document-config.mjs +0 -36
  107. package/agents/clear/clear-document-structure.mjs +0 -102
  108. package/agents/clear/clear-generated-docs.mjs +0 -142
  109. package/agents/clear/clear-media-description.mjs +0 -129
  110. package/agents/create/aggregate-document-structure.mjs +0 -21
  111. package/agents/create/analyze-diagram-type-llm.yaml +0 -159
  112. package/agents/create/analyze-diagram-type.mjs +0 -455
  113. package/agents/create/check-document-structure.yaml +0 -30
  114. package/agents/create/check-need-generate-structure.mjs +0 -138
  115. package/agents/create/document-structure-tools/add-document.mjs +0 -85
  116. package/agents/create/document-structure-tools/delete-document.mjs +0 -116
  117. package/agents/create/document-structure-tools/move-document.mjs +0 -109
  118. package/agents/create/document-structure-tools/update-document.mjs +0 -84
  119. package/agents/create/generate-diagram-image.yaml +0 -91
  120. package/agents/create/generate-structure.yaml +0 -106
  121. package/agents/create/index.yaml +0 -45
  122. package/agents/create/refine-document-structure.yaml +0 -12
  123. package/agents/create/replace-d2-with-image.mjs +0 -610
  124. package/agents/create/update-document-structure.yaml +0 -54
  125. package/agents/create/user-add-document/add-documents-to-structure.mjs +0 -90
  126. package/agents/create/user-add-document/find-documents-to-add-links.yaml +0 -47
  127. package/agents/create/user-add-document/index.yaml +0 -46
  128. package/agents/create/user-add-document/prepare-documents-to-translate.mjs +0 -22
  129. package/agents/create/user-add-document/print-add-document-summary.mjs +0 -63
  130. package/agents/create/user-add-document/review-documents-with-new-links.mjs +0 -110
  131. package/agents/create/user-remove-document/find-documents-with-invalid-links.mjs +0 -78
  132. package/agents/create/user-remove-document/index.yaml +0 -40
  133. package/agents/create/user-remove-document/prepare-documents-to-translate.mjs +0 -22
  134. package/agents/create/user-remove-document/print-remove-document-summary.mjs +0 -53
  135. package/agents/create/user-remove-document/remove-documents-from-structure.mjs +0 -99
  136. package/agents/create/user-remove-document/review-documents-with-invalid-links.mjs +0 -115
  137. package/agents/create/user-review-document-structure.mjs +0 -139
  138. package/agents/create/utils/init-current-content.mjs +0 -34
  139. package/agents/create/utils/merge-document-structures.mjs +0 -36
  140. package/agents/evaluate/code-snippet.mjs +0 -97
  141. package/agents/evaluate/document-structure.yaml +0 -67
  142. package/agents/evaluate/document.yaml +0 -82
  143. package/agents/evaluate/generate-report.mjs +0 -85
  144. package/agents/evaluate/index.yaml +0 -46
  145. package/agents/history/index.yaml +0 -6
  146. package/agents/history/view.mjs +0 -78
  147. package/agents/init/check.mjs +0 -16
  148. package/agents/init/index.mjs +0 -643
  149. package/agents/init/validate.mjs +0 -16
  150. package/agents/localize/choose-language.mjs +0 -107
  151. package/agents/localize/record-translation-history.mjs +0 -23
  152. package/agents/localize/save-doc-translation-or-skip.mjs +0 -18
  153. package/agents/localize/set-review-content.mjs +0 -58
  154. package/agents/localize/translate-document-wrapper.mjs +0 -34
  155. package/agents/localize/translate-document.yaml +0 -24
  156. package/agents/localize/translate-multilingual.yaml +0 -57
  157. package/agents/localize/translate-or-skip-diagram.mjs +0 -52
  158. package/agents/media/batch-generate-media-description.yaml +0 -46
  159. package/agents/media/generate-media-description.yaml +0 -50
  160. package/agents/media/load-media-description.mjs +0 -454
  161. package/agents/prefs/index.mjs +0 -203
  162. package/agents/schema/document-structure-item.yaml +0 -26
  163. package/agents/schema/document-structure-refine-item.yaml +0 -23
  164. package/agents/schema/document-structure.yaml +0 -29
  165. package/agents/update/batch-generate-document.yaml +0 -27
  166. package/agents/update/batch-update-document.yaml +0 -7
  167. package/agents/update/check-diagram-flag.mjs +0 -116
  168. package/agents/update/check-document.mjs +0 -162
  169. package/agents/update/check-generate-diagram.mjs +0 -106
  170. package/agents/update/check-update-is-single.mjs +0 -53
  171. package/agents/update/document-tools/update-document-content.mjs +0 -303
  172. package/agents/update/generate-diagram.yaml +0 -80
  173. package/agents/update/generate-document.yaml +0 -70
  174. package/agents/update/handle-document-update.yaml +0 -103
  175. package/agents/update/index.yaml +0 -69
  176. package/agents/update/pre-check-generate-diagram.yaml +0 -44
  177. package/agents/update/save-and-translate-document.mjs +0 -80
  178. package/agents/update/update-document-detail.yaml +0 -71
  179. package/agents/update/update-single/update-single-document-detail.mjs +0 -322
  180. package/agents/update/update-single-document.yaml +0 -7
  181. package/agents/update/user-review-document.mjs +0 -272
  182. package/agents/utils/action-success.mjs +0 -16
  183. package/agents/utils/analyze-document-feedback-intent.yaml +0 -32
  184. package/agents/utils/analyze-feedback-intent.mjs +0 -253
  185. package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
  186. package/agents/utils/check-detail-result.mjs +0 -51
  187. package/agents/utils/check-feedback-refiner.mjs +0 -81
  188. package/agents/utils/choose-docs.mjs +0 -251
  189. package/agents/utils/document-icon-generate.yaml +0 -52
  190. package/agents/utils/document-title-streamline.yaml +0 -48
  191. package/agents/utils/ensure-document-icons.mjs +0 -129
  192. package/agents/utils/exit.mjs +0 -6
  193. package/agents/utils/feedback-refiner.yaml +0 -50
  194. package/agents/utils/find-item-by-path.mjs +0 -114
  195. package/agents/utils/find-user-preferences-by-path.mjs +0 -37
  196. package/agents/utils/format-document-structure.mjs +0 -35
  197. package/agents/utils/generate-document-or-skip.mjs +0 -41
  198. package/agents/utils/handle-diagram-operations.mjs +0 -263
  199. package/agents/utils/load-all-document-content.mjs +0 -30
  200. package/agents/utils/load-document-all-content.mjs +0 -96
  201. package/agents/utils/load-sources.mjs +0 -405
  202. package/agents/utils/map-reasoning-effort-level.mjs +0 -15
  203. package/agents/utils/post-generate.mjs +0 -133
  204. package/agents/utils/read-current-document-content.mjs +0 -46
  205. package/agents/utils/save-doc-translation.mjs +0 -30
  206. package/agents/utils/save-doc.mjs +0 -54
  207. package/agents/utils/save-output.mjs +0 -26
  208. package/agents/utils/save-sidebar.mjs +0 -38
  209. package/agents/utils/skip-if-content-exists.mjs +0 -27
  210. package/agents/utils/streamline-document-titles-if-needed.mjs +0 -88
  211. package/agents/utils/transform-detail-data-sources.mjs +0 -45
  212. package/assets/report-template/report.html +0 -198
  213. package/docs-mcp/analyze-content-relevance.yaml +0 -50
  214. package/docs-mcp/analyze-docs-relevance.yaml +0 -59
  215. package/docs-mcp/docs-search.yaml +0 -42
  216. package/docs-mcp/get-docs-detail.mjs +0 -41
  217. package/docs-mcp/get-docs-structure.mjs +0 -16
  218. package/docs-mcp/read-doc-content.mjs +0 -119
  219. package/prompts/common/document/content-rules-core.md +0 -20
  220. package/prompts/common/document/markdown-syntax-rules.md +0 -65
  221. package/prompts/common/document/media-file-list-usage-rules.md +0 -18
  222. package/prompts/common/document/openapi-usage-rules.md +0 -189
  223. package/prompts/common/document/role-and-personality.md +0 -16
  224. package/prompts/common/document/user-preferences.md +0 -9
  225. package/prompts/common/document-structure/conflict-resolution-guidance.md +0 -16
  226. package/prompts/common/document-structure/document-icon-generate.md +0 -116
  227. package/prompts/common/document-structure/document-structure-rules.md +0 -43
  228. package/prompts/common/document-structure/document-title-streamline.md +0 -86
  229. package/prompts/common/document-structure/glossary.md +0 -7
  230. package/prompts/common/document-structure/intj-traits.md +0 -5
  231. package/prompts/common/document-structure/openapi-usage-rules.md +0 -28
  232. package/prompts/common/document-structure/output-constraints.md +0 -18
  233. package/prompts/common/document-structure/user-locale-rules.md +0 -10
  234. package/prompts/common/document-structure/user-preferences.md +0 -9
  235. package/prompts/detail/custom/admonition-usage-rules.md +0 -94
  236. package/prompts/detail/custom/code-block-usage-rules.md +0 -163
  237. package/prompts/detail/custom/custom-components/x-card-usage-rules.md +0 -63
  238. package/prompts/detail/custom/custom-components/x-cards-usage-rules.md +0 -83
  239. package/prompts/detail/custom/custom-components/x-field-desc-usage-rules.md +0 -120
  240. package/prompts/detail/custom/custom-components/x-field-group-usage-rules.md +0 -80
  241. package/prompts/detail/custom/custom-components/x-field-usage-rules.md +0 -189
  242. package/prompts/detail/custom/custom-components-usage-rules.md +0 -18
  243. package/prompts/detail/diagram/generate-image-user.md +0 -81
  244. package/prompts/detail/diagram/guide.md +0 -29
  245. package/prompts/detail/diagram/official-examples.md +0 -712
  246. package/prompts/detail/diagram/pre-check.md +0 -23
  247. package/prompts/detail/diagram/role-and-personality.md +0 -2
  248. package/prompts/detail/diagram/rules.md +0 -46
  249. package/prompts/detail/diagram/system-prompt.md +0 -1139
  250. package/prompts/detail/diagram/user-prompt.md +0 -43
  251. package/prompts/detail/generate/detail-example.md +0 -457
  252. package/prompts/detail/generate/document-rules.md +0 -45
  253. package/prompts/detail/generate/system-prompt.md +0 -61
  254. package/prompts/detail/generate/user-prompt.md +0 -99
  255. package/prompts/detail/jsx/rules.md +0 -6
  256. package/prompts/detail/update/system-prompt.md +0 -121
  257. package/prompts/detail/update/user-prompt.md +0 -41
  258. package/prompts/evaluate/document-structure.md +0 -93
  259. package/prompts/evaluate/document.md +0 -149
  260. package/prompts/media/media-description/system-prompt.md +0 -43
  261. package/prompts/media/media-description/user-prompt.md +0 -17
  262. package/prompts/structure/check-document-structure.md +0 -93
  263. package/prompts/structure/document-rules.md +0 -21
  264. package/prompts/structure/find-documents-to-add-links.md +0 -52
  265. package/prompts/structure/generate/system-prompt.md +0 -13
  266. package/prompts/structure/generate/user-prompt.md +0 -137
  267. package/prompts/structure/review/structure-review-system.md +0 -81
  268. package/prompts/structure/structure-example.md +0 -89
  269. package/prompts/structure/structure-getting-started.md +0 -10
  270. package/prompts/structure/update/system-prompt.md +0 -93
  271. package/prompts/structure/update/user-prompt.md +0 -43
  272. package/prompts/translate/admonition.md +0 -20
  273. package/prompts/translate/code-block.md +0 -33
  274. package/prompts/utils/analyze-document-feedback-intent.md +0 -54
  275. package/prompts/utils/analyze-structure-feedback-intent.md +0 -43
  276. package/prompts/utils/feedback-refiner.md +0 -105
  277. package/types/document-schema.mjs +0 -55
  278. package/types/document-structure-schema.mjs +0 -261
  279. package/utils/check-document-has-diagram.mjs +0 -95
  280. package/utils/conflict-detector.mjs +0 -149
  281. package/utils/constants/index.mjs +0 -620
  282. package/utils/constants/linter.mjs +0 -102
  283. package/utils/d2-utils.mjs +0 -205
  284. package/utils/debug.mjs +0 -3
  285. package/utils/delete-diagram-images.mjs +0 -99
  286. package/utils/diagram-version-utils.mjs +0 -14
  287. package/utils/docs-finder-utils.mjs +0 -548
  288. package/utils/evaluate/report-utils.mjs +0 -132
  289. package/utils/extract-api.mjs +0 -32
  290. package/utils/file-utils.mjs +0 -960
  291. package/utils/history-utils.mjs +0 -203
  292. package/utils/icon-map.mjs +0 -26
  293. package/utils/image-compress.mjs +0 -154
  294. package/utils/kroki-utils.mjs +0 -173
  295. package/utils/linter/index.mjs +0 -50
  296. package/utils/load-config.mjs +0 -78
  297. package/utils/markdown/index.mjs +0 -26
  298. package/utils/markdown-checker.mjs +0 -694
  299. package/utils/mermaid-validator.mjs +0 -140
  300. package/utils/mermaid-worker-pool.mjs +0 -250
  301. package/utils/mermaid-worker.mjs +0 -233
  302. package/utils/openapi/index.mjs +0 -28
  303. package/utils/preferences-utils.mjs +0 -175
  304. package/utils/request.mjs +0 -10
  305. package/utils/sync-diagram-to-translations.mjs +0 -272
  306. package/utils/translate-diagram-images.mjs +0 -807
  307. package/utils/utils.mjs +0 -1354
  308. /package/{prompts/translate → agents/localize/prompts}/glossary.md +0 -0
@@ -1,140 +0,0 @@
1
- /**
2
- * Simplified Mermaid validation using Worker Thread pool
3
- * Provides concurrent-safe validation with isolated worker environments
4
- */
5
-
6
- import { getMermaidWorkerPool, shutdownMermaidWorkerPool } from "./mermaid-worker-pool.mjs";
7
-
8
- /**
9
- * Basic mermaid syntax validation fallback
10
- * Used when worker validation fails due to environment issues
11
- * @param {string} content - Mermaid diagram content
12
- * @returns {boolean} - True if basic validation passes
13
- * @throws {Error} - If validation fails
14
- */
15
- export function validateBasicMermaidSyntax(content) {
16
- const trimmedContent = content.trim();
17
-
18
- if (!trimmedContent) {
19
- throw new Error("Empty mermaid diagram");
20
- }
21
-
22
- // Check for valid diagram type
23
- const validDiagramTypes = [
24
- "flowchart",
25
- "graph",
26
- "sequenceDiagram",
27
- "classDiagram",
28
- "stateDiagram",
29
- "entityRelationshipDiagram",
30
- "erDiagram",
31
- "journey",
32
- "gantt",
33
- "pie",
34
- "requirement",
35
- "gitgraph",
36
- "mindmap",
37
- "timeline",
38
- "quadrantChart",
39
- ];
40
-
41
- const firstLine = trimmedContent.split("\n")[0].trim();
42
- const hasValidType = validDiagramTypes.some((type) => firstLine.includes(type));
43
-
44
- if (!hasValidType) {
45
- throw new Error("Invalid or missing diagram type");
46
- }
47
-
48
- // Basic bracket matching
49
- const openBrackets = (content.match(/[[{(]/g) || []).length;
50
- const closeBrackets = (content.match(/[\]})]/g) || []).length;
51
-
52
- if (openBrackets !== closeBrackets) {
53
- throw new Error("Unmatched brackets in diagram");
54
- }
55
-
56
- // Basic quote matching
57
- const singleQuotes = (content.match(/'/g) || []).length;
58
- const doubleQuotes = (content.match(/"/g) || []).length;
59
-
60
- if (singleQuotes % 2 !== 0) {
61
- throw new Error("Unmatched single quotes in diagram");
62
- }
63
-
64
- if (doubleQuotes % 2 !== 0) {
65
- throw new Error("Unmatched double quotes in diagram");
66
- }
67
-
68
- return true;
69
- }
70
-
71
- /**
72
- * Main validation function using simplified worker pool for concurrency safety
73
- * @param {string} content - Mermaid diagram content
74
- * @returns {Promise<boolean>} - True if validation passes
75
- * @throws {Error} - If validation fails
76
- */
77
- export async function validateMermaidSyntax(content) {
78
- if (!content || !content.trim()) {
79
- throw new Error("Empty mermaid diagram");
80
- }
81
-
82
- try {
83
- // Use simplified worker pool for validation
84
- const workerPool = getMermaidWorkerPool({
85
- poolSize: 2, // Reduced pool size
86
- timeout: 10000, // Reduced timeout
87
- });
88
-
89
- const result = await workerPool.validate(content);
90
- return result;
91
- } catch (error) {
92
- // If worker validation fails, check if it's an environment issue
93
- const errorMsg = error.message || String(error);
94
-
95
- if (
96
- errorMsg.includes("Worker error") ||
97
- errorMsg.includes("Worker exited") ||
98
- errorMsg.includes("Worker pool") ||
99
- errorMsg.includes("timeout") ||
100
- errorMsg.includes("Cannot resolve module") ||
101
- errorMsg.includes("window is not defined") ||
102
- errorMsg.includes("canvas") ||
103
- errorMsg.includes("Web APIs") ||
104
- errorMsg.includes("getComputedTextLength") ||
105
- errorMsg.includes("document is not defined")
106
- ) {
107
- // Fall back to basic validation for environment issues
108
- console.warn(
109
- "Worker-based mermaid validation failed, falling back to basic validation:",
110
- errorMsg,
111
- );
112
- return validateBasicMermaidSyntax(content);
113
- }
114
-
115
- // If it's a genuine syntax error, re-throw it
116
- throw error;
117
- }
118
- }
119
-
120
- /**
121
- * Get worker pool statistics for monitoring
122
- * @returns {Object} - Pool statistics
123
- */
124
- export function getValidationStats() {
125
- try {
126
- const workerPool = getMermaidWorkerPool();
127
- return workerPool.getStats();
128
- } catch (error) {
129
- return { error: error.message };
130
- }
131
- }
132
-
133
- /**
134
- * Shutdown the validation worker pool
135
- * Call this when shutting down the application
136
- * @returns {Promise<void>}
137
- */
138
- export async function shutdownValidation() {
139
- await shutdownMermaidWorkerPool();
140
- }
@@ -1,250 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Simplified Mermaid Worker Pool
5
- * Manages worker threads for concurrent mermaid validation
6
- */
7
-
8
- import { dirname, join } from "node:path";
9
- import { fileURLToPath } from "node:url";
10
- import { Worker } from "node:worker_threads";
11
-
12
- const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = dirname(__filename);
14
-
15
- class SimpleMermaidWorkerPool {
16
- constructor(options = {}) {
17
- this.poolSize = options.poolSize || 3;
18
- this.timeout = options.timeout || 15000; // Reduced timeout
19
-
20
- this.workers = [];
21
- this.availableWorkers = [];
22
- this.requestQueue = [];
23
- this.nextRequestId = 1;
24
- this.isShuttingDown = false;
25
- }
26
-
27
- /**
28
- * Initialize worker pool
29
- */
30
- async initialize() {
31
- if (this.workers.length > 0) return; // Already initialized
32
-
33
- const workerPath = join(__dirname, "mermaid-worker.mjs");
34
-
35
- for (let i = 0; i < this.poolSize; i++) {
36
- await this.createWorker(workerPath, i);
37
- }
38
- }
39
-
40
- /**
41
- * Create a single worker
42
- */
43
- async createWorker(workerPath, workerId) {
44
- return new Promise((resolve, reject) => {
45
- try {
46
- const worker = new Worker(workerPath);
47
- worker.workerId = workerId;
48
- worker.isAvailable = true;
49
- worker.currentRequest = null;
50
-
51
- // Handle worker errors more gracefully
52
- worker.on("error", (error) => {
53
- if (worker.currentRequest) {
54
- worker.currentRequest.reject(new Error(`Worker error: ${error.message}`));
55
- worker.currentRequest = null;
56
- }
57
- });
58
-
59
- worker.on("exit", (_code) => {
60
- if (worker.currentRequest) {
61
- worker.currentRequest.reject(new Error("Worker exited unexpectedly"));
62
- worker.currentRequest = null;
63
- }
64
- });
65
-
66
- worker.on("message", (data) => {
67
- this.handleWorkerMessage(worker, data);
68
- });
69
-
70
- this.workers.push(worker);
71
- this.availableWorkers.push(worker);
72
-
73
- resolve(worker);
74
- } catch (error) {
75
- reject(error);
76
- }
77
- });
78
- }
79
-
80
- /**
81
- * Handle worker message
82
- */
83
- handleWorkerMessage(worker, data) {
84
- if (!worker.currentRequest) return;
85
-
86
- const { resolve, reject, timeoutId } = worker.currentRequest;
87
-
88
- // Clear timeout
89
- if (timeoutId) {
90
- clearTimeout(timeoutId);
91
- }
92
-
93
- // Reset worker state
94
- worker.currentRequest = null;
95
- worker.isAvailable = true;
96
-
97
- // Move worker back to available pool
98
- const workerIndex = this.workers.indexOf(worker);
99
- if (workerIndex > -1 && !this.availableWorkers.includes(worker)) {
100
- this.availableWorkers.push(worker);
101
- }
102
-
103
- // Process queued requests
104
- this.processQueue();
105
-
106
- // Handle response
107
- if (data.error) {
108
- reject(new Error(data.error));
109
- } else {
110
- resolve(data.result);
111
- }
112
- }
113
-
114
- /**
115
- * Process queued requests
116
- */
117
- processQueue() {
118
- while (this.requestQueue.length > 0 && this.availableWorkers.length > 0) {
119
- const queuedRequest = this.requestQueue.shift();
120
- const worker = this.availableWorkers.shift();
121
-
122
- this.executeRequest(worker, queuedRequest);
123
- }
124
- }
125
-
126
- /**
127
- * Execute a request on a worker
128
- */
129
- executeRequest(worker, request) {
130
- const { content, resolve, reject } = request;
131
- const requestId = this.nextRequestId++;
132
-
133
- // Set timeout
134
- const timeoutId = setTimeout(() => {
135
- worker.currentRequest = null;
136
- worker.isAvailable = true;
137
- if (!this.availableWorkers.includes(worker)) {
138
- this.availableWorkers.push(worker);
139
- }
140
- reject(new Error(`Validation timeout after ${this.timeout}ms`));
141
- }, this.timeout);
142
-
143
- // Store request info
144
- worker.currentRequest = { resolve, reject, timeoutId };
145
- worker.isAvailable = false;
146
-
147
- // Send request
148
- worker.postMessage({
149
- id: requestId,
150
- content: content,
151
- });
152
- }
153
-
154
- /**
155
- * Validate content using worker pool
156
- */
157
- async validate(content) {
158
- if (this.isShuttingDown) {
159
- throw new Error("Worker pool is shutting down");
160
- }
161
-
162
- // Initialize if needed
163
- await this.initialize();
164
-
165
- return new Promise((resolve, reject) => {
166
- const request = { content, resolve, reject };
167
-
168
- // If worker available, use it immediately
169
- if (this.availableWorkers.length > 0) {
170
- const worker = this.availableWorkers.shift();
171
- this.executeRequest(worker, request);
172
- } else {
173
- // Queue the request
174
- this.requestQueue.push(request);
175
- }
176
- });
177
- }
178
-
179
- /**
180
- * Get pool statistics
181
- */
182
- getStats() {
183
- return {
184
- poolSize: this.poolSize,
185
- totalWorkers: this.workers.length,
186
- availableWorkers: this.availableWorkers.length,
187
- busyWorkers: this.workers.length - this.availableWorkers.length,
188
- queuedRequests: this.requestQueue.length,
189
- isShuttingDown: this.isShuttingDown,
190
- };
191
- }
192
-
193
- /**
194
- * Shutdown the pool
195
- */
196
- async shutdown() {
197
- if (this.isShuttingDown) return;
198
-
199
- this.isShuttingDown = true;
200
-
201
- // Reject all queued requests
202
- while (this.requestQueue.length > 0) {
203
- const request = this.requestQueue.shift();
204
- request.reject(new Error("Worker pool is shutting down"));
205
- }
206
-
207
- // Terminate all workers
208
- const terminationPromises = this.workers.map(async (worker) => {
209
- try {
210
- await worker.terminate();
211
- } catch (_error) {
212
- // Ignore termination errors
213
- }
214
- });
215
-
216
- await Promise.allSettled(terminationPromises);
217
-
218
- // Clear arrays
219
- this.workers.length = 0;
220
- this.availableWorkers.length = 0;
221
- }
222
- }
223
-
224
- // Global pool instance
225
- let globalPool = null;
226
-
227
- /**
228
- * Get global worker pool
229
- */
230
- export function getMermaidWorkerPool(options = {}) {
231
- if (!globalPool) {
232
- globalPool = new SimpleMermaidWorkerPool(options);
233
- }
234
- return globalPool;
235
- }
236
-
237
- /**
238
- * Shutdown global pool
239
- */
240
- export async function shutdownMermaidWorkerPool() {
241
- if (globalPool) {
242
- await globalPool.shutdown();
243
- globalPool = null;
244
- }
245
- }
246
-
247
- // Note: We don't add global process event listeners here to avoid preventing clean exit
248
- // The application should call shutdownMermaidWorkerPool() explicitly when needed
249
-
250
- export { SimpleMermaidWorkerPool };
@@ -1,233 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Simplified Mermaid Validation Worker
5
- * Runs in isolated Worker thread to avoid global state conflicts
6
- */
7
-
8
- import { parentPort } from "node:worker_threads";
9
-
10
- /**
11
- * Validate mermaid syntax using official parser in isolated environment
12
- */
13
- async function validateMermaidWithOfficialParser(content) {
14
- const trimmedContent = content.trim();
15
- if (!content || !trimmedContent) {
16
- throw new Error("Empty mermaid diagram");
17
- }
18
-
19
- try {
20
- // Import dependencies
21
- const { JSDOM } = await import("jsdom");
22
- const DOMPurifyModule = await import("dompurify");
23
-
24
- // Create isolated DOM environment
25
- const { window } = new JSDOM(`<!DOCTYPE html><html><body></body></html>`, {
26
- pretendToBeVisual: true,
27
- resources: "usable",
28
- });
29
-
30
- // Setup globals (safe in worker - no conflicts)
31
- global.window = window;
32
- global.document = window.document;
33
-
34
- // Only set navigator if it doesn't exist
35
- if (!global.navigator) {
36
- global.navigator = {
37
- userAgent: "node.js",
38
- platform: "node",
39
- cookieEnabled: false,
40
- onLine: true,
41
- };
42
- }
43
-
44
- global.DOMParser = window.DOMParser;
45
- global.XMLSerializer = window.XMLSerializer;
46
- global.HTMLElement = window.HTMLElement;
47
- global.HTMLDivElement = window.HTMLDivElement;
48
- global.SVGElement = window.SVGElement;
49
- global.Element = window.Element;
50
- global.Node = window.Node;
51
-
52
- // Initialize DOMPurify with the JSDOM window
53
- const dompurify = DOMPurifyModule.default(window);
54
-
55
- // Verify DOMPurify is working before proceeding
56
- if (typeof dompurify.sanitize !== "function") {
57
- throw new Error("DOMPurify initialization failed - sanitize method not available");
58
- }
59
-
60
- // Test DOMPurify functionality
61
- dompurify.sanitize("<p>test</p>");
62
-
63
- // Step 5: Comprehensively set up DOMPurify in all possible global locations
64
- global.DOMPurify = dompurify;
65
- window.DOMPurify = dompurify;
66
-
67
- // For ES module interception, we need to ensure DOMPurify is available
68
- // in all the ways mermaid might try to access it
69
- if (typeof globalThis !== "undefined") {
70
- globalThis.DOMPurify = dompurify;
71
- }
72
-
73
- // Set up on the global scope itself
74
- if (typeof self !== "undefined") {
75
- self.DOMPurify = dompurify;
76
- }
77
-
78
- // CRITICAL: Override the DOMPurify constructor/factory to always use our window
79
- // This is the key to solving the issue: mermaid imports DOMPurify directly
80
- const originalDOMPurifyFactory = DOMPurifyModule.default;
81
- try {
82
- // This might work: intercept the factory function itself
83
- if (typeof originalDOMPurifyFactory === "function" && !originalDOMPurifyFactory.sanitize) {
84
- // This means DOMPurify.default is a factory function, not an instance
85
- // We need to make sure when mermaid calls DOMPurify.sanitize, it works
86
- const factoryResult = originalDOMPurifyFactory(window);
87
-
88
- // Copy methods from our working instance to the factory result
89
- Object.assign(originalDOMPurifyFactory, factoryResult);
90
- }
91
- } catch (_factoryError) {
92
- // If factory modification fails, that's OK - we have other fallbacks
93
- }
94
-
95
- // Import and setup mermaid
96
- const mermaid = await import("mermaid");
97
-
98
- mermaid.default.initialize({
99
- startOnLoad: false,
100
- theme: "default",
101
- securityLevel: "loose",
102
- htmlLabels: false,
103
- });
104
-
105
- // Parse content
106
- await mermaid.default.parse(trimmedContent);
107
-
108
- return true;
109
- } catch (error) {
110
- const errorMessage = error.message || String(error);
111
-
112
- // Keep parse errors as-is for useful info
113
- if (errorMessage.includes("Parse error")) {
114
- throw new Error(errorMessage);
115
- }
116
-
117
- if (errorMessage.includes("Expecting ")) {
118
- throw new Error(`Syntax error: ${errorMessage.replace(/^.*Expecting /, "Expected ")}`);
119
- }
120
-
121
- if (errorMessage.includes("Lexical error")) {
122
- throw new Error("Syntax error: invalid characters or tokens");
123
- }
124
-
125
- if (errorMessage.includes("No diagram type detected")) {
126
- throw new Error("Syntax error: invalid or unrecognized diagram type");
127
- }
128
-
129
- throw new Error(errorMessage);
130
- }
131
- }
132
-
133
- /**
134
- * Basic validation fallback
135
- */
136
- function validateBasicMermaidSyntax(content) {
137
- const trimmedContent = content.trim();
138
-
139
- if (!trimmedContent) {
140
- throw new Error("Empty mermaid diagram");
141
- }
142
-
143
- const validDiagramTypes = [
144
- "flowchart",
145
- "graph",
146
- "sequenceDiagram",
147
- "classDiagram",
148
- "stateDiagram",
149
- "entityRelationshipDiagram",
150
- "erDiagram",
151
- "journey",
152
- "gantt",
153
- "pie",
154
- "requirement",
155
- "gitgraph",
156
- "mindmap",
157
- "timeline",
158
- "quadrantChart",
159
- ];
160
-
161
- const firstLine = trimmedContent.split("\n")[0].trim();
162
- const hasValidType = validDiagramTypes.some((type) => firstLine.includes(type));
163
-
164
- if (!hasValidType) {
165
- throw new Error("Invalid or missing diagram type");
166
- }
167
-
168
- // Basic bracket matching
169
- const openBrackets = (content.match(/[[{(]/g) || []).length;
170
- const closeBrackets = (content.match(/[\]})]/g) || []).length;
171
-
172
- if (openBrackets !== closeBrackets) {
173
- throw new Error("Unmatched brackets in diagram");
174
- }
175
-
176
- return true;
177
- }
178
-
179
- /**
180
- * Main validation with fallback
181
- */
182
- async function validateMermaidSyntax(content) {
183
- try {
184
- return await validateMermaidWithOfficialParser(content);
185
- } catch (officialError) {
186
- const errorMsg = officialError.message || String(officialError);
187
-
188
- // Check if it's an environment issue
189
- if (
190
- errorMsg.includes("Cannot resolve module") ||
191
- errorMsg.includes("window is not defined") ||
192
- errorMsg.includes("canvas") ||
193
- errorMsg.includes("Web APIs") ||
194
- errorMsg.includes("getComputedTextLength") ||
195
- errorMsg.includes("document is not defined") ||
196
- errorMsg.includes("DOMPurify")
197
- ) {
198
- // Fall back to basic validation
199
- return validateBasicMermaidSyntax(content);
200
- }
201
-
202
- // Re-throw syntax errors
203
- throw officialError;
204
- }
205
- }
206
-
207
- // Worker message handler
208
- if (parentPort) {
209
- parentPort.on("message", async (data) => {
210
- const { id, content } = data;
211
-
212
- try {
213
- if (!id || !content) {
214
- throw new Error("Missing id or content");
215
- }
216
-
217
- const result = await validateMermaidSyntax(content);
218
-
219
- parentPort.postMessage({
220
- id,
221
- success: true,
222
- result,
223
- });
224
- } catch (error) {
225
- parentPort.postMessage({
226
- id,
227
- error: error.message || String(error),
228
- });
229
- }
230
- });
231
- }
232
-
233
- export { validateMermaidSyntax };
@@ -1,28 +0,0 @@
1
- import { parse } from "yaml";
2
-
3
- function isMatchOpenAPISpec(content) {
4
- if (!content) return false;
5
- if (!(content.openapi || content.swagger)) return false;
6
- if (!content.paths) return false;
7
- if (!(content.info?.title && content.info?.version)) return false;
8
- return true;
9
- }
10
-
11
- export function isOpenAPISpecFile(content) {
12
- const trimmedContent = content.trim();
13
- try {
14
- const parsed = parse(trimmedContent, {
15
- logLevel: "silent",
16
- });
17
- return isMatchOpenAPISpec(parsed);
18
- } catch {
19
- //
20
- }
21
- try {
22
- const parsed = JSON.parse(trimmedContent);
23
- return isMatchOpenAPISpec(parsed);
24
- } catch {
25
- //
26
- }
27
- return false;
28
- }