@aigne/doc-smith 0.8.12-beta.7 → 0.8.12-beta.9

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 (284) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/agents/clear/choose-contents.mjs +14 -1
  3. package/agents/clear/clear-media-description.mjs +129 -0
  4. package/agents/clear/index.yaml +3 -1
  5. package/agents/evaluate/code-snippet.mjs +28 -24
  6. package/agents/evaluate/document-structure.yaml +0 -4
  7. package/agents/evaluate/document.yaml +1 -5
  8. package/agents/generate/index.yaml +1 -0
  9. package/agents/init/index.mjs +10 -0
  10. package/agents/media/batch-generate-media-description.yaml +44 -0
  11. package/agents/media/generate-media-description.yaml +47 -0
  12. package/agents/media/load-media-description.mjs +238 -0
  13. package/agents/publish/index.yaml +4 -0
  14. package/agents/publish/publish-docs.mjs +77 -5
  15. package/agents/publish/translate-meta.mjs +103 -0
  16. package/agents/update/generate-document.yaml +30 -28
  17. package/agents/update/index.yaml +1 -0
  18. package/agents/update/update-document-detail.yaml +3 -1
  19. package/agents/utils/load-sources.mjs +103 -53
  20. package/agents/utils/update-branding.mjs +69 -0
  21. package/aigne.yaml +6 -0
  22. package/assets/report-template/report.html +34 -34
  23. package/package.json +17 -2
  24. package/prompts/common/document/role-and-personality.md +3 -1
  25. package/prompts/detail/d2-diagram/guide.md +7 -1
  26. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  27. package/prompts/detail/generate/system-prompt.md +6 -7
  28. package/prompts/detail/generate/user-prompt.md +12 -3
  29. package/prompts/detail/update/user-prompt.md +0 -2
  30. package/prompts/evaluate/document-structure.md +6 -7
  31. package/prompts/evaluate/document.md +16 -25
  32. package/prompts/media/media-description/system-prompt.md +35 -0
  33. package/prompts/media/media-description/user-prompt.md +8 -0
  34. package/prompts/structure/update/user-prompt.md +0 -4
  35. package/utils/constants/index.mjs +0 -107
  36. package/utils/file-utils.mjs +86 -0
  37. package/utils/markdown-checker.mjs +0 -20
  38. package/utils/request.mjs +7 -0
  39. package/utils/upload-files.mjs +231 -0
  40. package/utils/utils.mjs +11 -1
  41. package/.aigne/doc-smith/config.yaml +0 -77
  42. package/.aigne/doc-smith/history.yaml +0 -37
  43. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  44. package/.aigne/doc-smith/preferences.yml +0 -97
  45. package/.aigne/doc-smith/upload-cache.yaml +0 -1893
  46. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  47. package/.github/workflows/ci.yml +0 -54
  48. package/.github/workflows/create-release-pr.yaml +0 -21
  49. package/.github/workflows/publish-docs.yml +0 -65
  50. package/.github/workflows/release.yml +0 -49
  51. package/.github/workflows/reviewer.yml +0 -54
  52. package/.release-please-manifest.json +0 -3
  53. package/RELEASE.md +0 -9
  54. package/assets/screenshots/doc-complete-setup.png +0 -0
  55. package/assets/screenshots/doc-generate-docs.png +0 -0
  56. package/assets/screenshots/doc-generate.png +0 -0
  57. package/assets/screenshots/doc-generated-successfully.png +0 -0
  58. package/assets/screenshots/doc-publish.png +0 -0
  59. package/assets/screenshots/doc-regenerate.png +0 -0
  60. package/assets/screenshots/doc-translate-langs.png +0 -0
  61. package/assets/screenshots/doc-translate.png +0 -0
  62. package/assets/screenshots/doc-update.png +0 -0
  63. package/biome.json +0 -73
  64. package/codecov.yml +0 -15
  65. package/docs/_sidebar.md +0 -15
  66. package/docs/configuration-initial-setup.ja.md +0 -179
  67. package/docs/configuration-initial-setup.md +0 -179
  68. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  69. package/docs/configuration-initial-setup.zh.md +0 -179
  70. package/docs/configuration-managing-preferences.ja.md +0 -100
  71. package/docs/configuration-managing-preferences.md +0 -100
  72. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  73. package/docs/configuration-managing-preferences.zh.md +0 -100
  74. package/docs/configuration.ja.md +0 -96
  75. package/docs/configuration.md +0 -96
  76. package/docs/configuration.zh-TW.md +0 -96
  77. package/docs/configuration.zh.md +0 -96
  78. package/docs/getting-started.ja.md +0 -88
  79. package/docs/getting-started.md +0 -88
  80. package/docs/getting-started.zh-TW.md +0 -88
  81. package/docs/getting-started.zh.md +0 -88
  82. package/docs/guides-cleaning-up.ja.md +0 -51
  83. package/docs/guides-cleaning-up.md +0 -51
  84. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  85. package/docs/guides-cleaning-up.zh.md +0 -51
  86. package/docs/guides-evaluating-documents.ja.md +0 -66
  87. package/docs/guides-evaluating-documents.md +0 -66
  88. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  89. package/docs/guides-evaluating-documents.zh.md +0 -66
  90. package/docs/guides-generating-documentation.ja.md +0 -151
  91. package/docs/guides-generating-documentation.md +0 -151
  92. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  93. package/docs/guides-generating-documentation.zh.md +0 -151
  94. package/docs/guides-interactive-chat.ja.md +0 -85
  95. package/docs/guides-interactive-chat.md +0 -85
  96. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  97. package/docs/guides-interactive-chat.zh.md +0 -85
  98. package/docs/guides-managing-history.ja.md +0 -48
  99. package/docs/guides-managing-history.md +0 -48
  100. package/docs/guides-managing-history.zh-TW.md +0 -48
  101. package/docs/guides-managing-history.zh.md +0 -48
  102. package/docs/guides-publishing-your-docs.ja.md +0 -78
  103. package/docs/guides-publishing-your-docs.md +0 -78
  104. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  105. package/docs/guides-publishing-your-docs.zh.md +0 -78
  106. package/docs/guides-translating-documentation.ja.md +0 -95
  107. package/docs/guides-translating-documentation.md +0 -95
  108. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  109. package/docs/guides-translating-documentation.zh.md +0 -95
  110. package/docs/guides-updating-documentation.ja.md +0 -77
  111. package/docs/guides-updating-documentation.md +0 -77
  112. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  113. package/docs/guides-updating-documentation.zh.md +0 -77
  114. package/docs/guides.ja.md +0 -32
  115. package/docs/guides.md +0 -32
  116. package/docs/guides.zh-TW.md +0 -32
  117. package/docs/guides.zh.md +0 -32
  118. package/docs/overview.ja.md +0 -61
  119. package/docs/overview.md +0 -61
  120. package/docs/overview.zh-TW.md +0 -61
  121. package/docs/overview.zh.md +0 -61
  122. package/docs/release-notes.ja.md +0 -255
  123. package/docs/release-notes.md +0 -255
  124. package/docs/release-notes.zh-TW.md +0 -255
  125. package/docs/release-notes.zh.md +0 -255
  126. package/media.md +0 -19
  127. package/prompts/common/afs/afs-tools-usage.md +0 -5
  128. package/prompts/common/afs/use-afs-instruction.md +0 -1
  129. package/release-please-config.json +0 -14
  130. package/tests/agents/chat/chat.test.mjs +0 -46
  131. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  132. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  133. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  134. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  135. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  136. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  137. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  138. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  139. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  140. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  141. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  142. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  143. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  144. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  145. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  146. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  147. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  148. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  149. package/tests/agents/history/view.test.mjs +0 -97
  150. package/tests/agents/init/init.test.mjs +0 -1657
  151. package/tests/agents/prefs/prefs.test.mjs +0 -431
  152. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  153. package/tests/agents/translate/choose-language.test.mjs +0 -311
  154. package/tests/agents/translate/translate-document.test.mjs +0 -51
  155. package/tests/agents/update/check-document.test.mjs +0 -463
  156. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  157. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  158. package/tests/agents/update/generate-document.test.mjs +0 -51
  159. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  160. package/tests/agents/update/user-review-document.test.mjs +0 -582
  161. package/tests/agents/utils/action-success.test.mjs +0 -54
  162. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  163. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  164. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  165. package/tests/agents/utils/exit.test.mjs +0 -70
  166. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  167. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  168. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  169. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  170. package/tests/agents/utils/fs.test.mjs +0 -267
  171. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  172. package/tests/agents/utils/save-docs.test.mjs +0 -109
  173. package/tests/agents/utils/save-output.test.mjs +0 -315
  174. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  175. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  176. package/tests/utils/auth-utils.test.mjs +0 -596
  177. package/tests/utils/blocklet.test.mjs +0 -336
  178. package/tests/utils/conflict-detector.test.mjs +0 -355
  179. package/tests/utils/constants.test.mjs +0 -295
  180. package/tests/utils/d2-utils.test.mjs +0 -437
  181. package/tests/utils/deploy.test.mjs +0 -399
  182. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  183. package/tests/utils/file-utils.test.mjs +0 -521
  184. package/tests/utils/history-utils.test.mjs +0 -206
  185. package/tests/utils/kroki-utils.test.mjs +0 -646
  186. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  187. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  188. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  189. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  190. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  191. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  192. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  193. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  194. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  195. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  196. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  197. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  198. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  199. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  200. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  201. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  202. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  203. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  204. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  205. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  206. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  207. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  208. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  209. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  210. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  211. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  212. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  213. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  214. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  215. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  216. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  217. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  218. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  219. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  220. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  221. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  222. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  223. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  224. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  225. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  226. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  227. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  228. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  229. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  230. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  231. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  232. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  233. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  234. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  235. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  236. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  237. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  238. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  239. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  240. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  241. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  242. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  243. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  244. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  245. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  246. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  247. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  248. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  249. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  250. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  251. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  252. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  253. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  254. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  255. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  256. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  257. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  258. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  259. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  260. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  261. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  262. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  263. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  264. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  265. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  266. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  267. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  268. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  269. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  270. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  271. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  272. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  273. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  274. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  275. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  276. package/tests/utils/linter/index.test.mjs +0 -440
  277. package/tests/utils/linter/scan-results.mjs +0 -42
  278. package/tests/utils/load-config.test.mjs +0 -141
  279. package/tests/utils/markdown/index.test.mjs +0 -478
  280. package/tests/utils/mermaid-validator.test.mjs +0 -541
  281. package/tests/utils/mock-chat-model.mjs +0 -12
  282. package/tests/utils/preferences-utils.test.mjs +0 -465
  283. package/tests/utils/save-value-to-config.test.mjs +0 -483
  284. package/tests/utils/utils.test.mjs +0 -941
@@ -1,743 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import checkDetailResult from "../../../agents/utils/check-detail-result.mjs";
3
-
4
- describe("check-detail-result", () => {
5
- test("should approve valid content", async () => {
6
- const documentStructure = [{ path: "/getting-started" }];
7
- const reviewContent =
8
- "This is a test with a [valid link](/getting-started).\n\nThis has proper structure with multiple lines.";
9
- const result = await checkDetailResult({ documentStructure, reviewContent });
10
- expect(result.isApproved).toBe(true);
11
- expect(result.detailFeedback).toBe("");
12
- });
13
-
14
- test("should reject content with a dead link", async () => {
15
- const documentStructure = [{ path: "/getting-started" }];
16
- const reviewContent = "This contains a [dead link](/dead-link).";
17
- const result = await checkDetailResult({ documentStructure, reviewContent });
18
- expect(result.isApproved).toBe(false);
19
- expect(result.detailFeedback).toContain("Found a dead link");
20
- });
21
-
22
- test("should accept valid table format", async () => {
23
- const documentStructure = [];
24
- const reviewContent =
25
- "| Header | Header |\n|--------|--------|\n| Cell | Cell |\n\nThis table is properly formatted.";
26
- const result = await checkDetailResult({ documentStructure, reviewContent });
27
- expect(result.isApproved).toBe(true);
28
- expect(result.detailFeedback).toBe("");
29
- });
30
-
31
- test("should approve content with an external link", async () => {
32
- const documentStructure = [];
33
- const reviewContent =
34
- "This is a [valid external link](https://example.com).\n\nThis has proper multi-line structure.";
35
- const result = await checkDetailResult({ documentStructure, reviewContent });
36
- expect(result.isApproved).toBe(true);
37
- expect(result.detailFeedback).toBe("");
38
- });
39
-
40
- test("should approve content with valid local image path", async () => {
41
- const documentStructure = [];
42
- const reviewContent =
43
- "This is a valid image ![Test Image](./README.md).\n\nThis has proper structure.";
44
- const docsDir = process.cwd();
45
- const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
46
- expect(result.isApproved).toBe(true);
47
- expect(result.detailFeedback).toBe("");
48
- });
49
-
50
- test("should reject content with invalid local image path", async () => {
51
- const documentStructure = [];
52
- const reviewContent =
53
- "This is an invalid image ![Non-existent Image](./nonexistent.png).\n\nThis has proper structure.";
54
- const docsDir = process.cwd();
55
- const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
56
- expect(result.isApproved).toBe(false);
57
- expect(result.detailFeedback).toContain("Found invalid local image");
58
- expect(result.detailFeedback).toContain("only valid media resources can be used");
59
- });
60
-
61
- test("should approve content with absolute image path that exists", async () => {
62
- const documentStructure = [];
63
- const reviewContent = `This is an absolute image ![Test Image](${process.cwd()}/README.md).\n\nThis has proper structure.`;
64
- const result = await checkDetailResult({ documentStructure, reviewContent });
65
- expect(result.isApproved).toBe(true);
66
- expect(result.detailFeedback).toBe("");
67
- });
68
-
69
- test("should reject content with absolute image path that doesn't exist", async () => {
70
- const documentStructure = [];
71
- const reviewContent =
72
- "This is an invalid absolute image ![Non-existent Image](/path/to/nonexistent.png).\n\nThis has proper structure.";
73
- const result = await checkDetailResult({ documentStructure, reviewContent });
74
- expect(result.isApproved).toBe(false);
75
- expect(result.detailFeedback).toContain("Found invalid local image");
76
- expect(result.detailFeedback).toContain("only valid media resources can be used");
77
- });
78
-
79
- test("should approve content with external image URL", async () => {
80
- const documentStructure = [];
81
- const reviewContent =
82
- "This is an external image ![External Image](https://example.com/image.png).\n\nThis has proper structure.";
83
- const result = await checkDetailResult({ documentStructure, reviewContent });
84
- expect(result.isApproved).toBe(true);
85
- expect(result.detailFeedback).toBe("");
86
- });
87
-
88
- describe("Table validation", () => {
89
- test("should reject table with mismatched column count", async () => {
90
- const documentStructure = [];
91
- const reviewContent =
92
- "| Header 1 | Header 2 | Header 3 |\n" +
93
- "|----------|----------|\n" + // Only 2 separator columns but 3 header columns
94
- "| Cell 1 | Cell 2 | Cell 3 |";
95
- const result = await checkDetailResult({ documentStructure, reviewContent });
96
- expect(result.isApproved).toBe(false);
97
- expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
98
- });
99
-
100
- test("should reject table with data row column mismatch", async () => {
101
- const documentStructure = [];
102
- const reviewContent =
103
- "| Header 1 | Header 2 |\n" + "|----------|----------|\n" + "| Cell 1 | Cell 2 | Cell 3 |"; // Data row has 3 columns but separator defines 2
104
- const result = await checkDetailResult({ documentStructure, reviewContent });
105
- expect(result.isApproved).toBe(false);
106
- expect(result.detailFeedback).toContain(
107
- "data row has 3 columns but separator defines 2 columns",
108
- );
109
- });
110
-
111
- test("should handle complex table with pipes in content", async () => {
112
- const documentStructure = [];
113
- const reviewContent =
114
- "| Code | Description |\n" +
115
- "|------|-------------|\n" +
116
- "| `a \\| b` | This has escaped pipe |\n" +
117
- "| `c | d` | This has unescaped pipe in code |";
118
- const result = await checkDetailResult({ documentStructure, reviewContent });
119
- expect(result.isApproved).toBe(true);
120
- });
121
- });
122
-
123
- describe("Code block validation", () => {
124
- test("should reject incomplete code blocks", async () => {
125
- const documentStructure = [];
126
- const reviewContent =
127
- "Here is some code:\n\n" +
128
- "```javascript\n" +
129
- "function test() {\n" +
130
- " return 'incomplete';\n" +
131
- "}\n"; // Missing closing ```
132
- const result = await checkDetailResult({ documentStructure, reviewContent });
133
- expect(result.isApproved).toBe(false);
134
- expect(result.detailFeedback).toContain("incomplete code block");
135
- });
136
-
137
- test("should detect code block indentation issues", async () => {
138
- const documentStructure = [];
139
- const reviewContent =
140
- " ```javascript\n" +
141
- "function test() {\n" + // This line has insufficient indentation
142
- " return 'test';\n" +
143
- " }\n" +
144
- " ```";
145
- const result = await checkDetailResult({ documentStructure, reviewContent });
146
- expect(result.isApproved).toBe(false);
147
- expect(result.detailFeedback).toContain("insufficient indentation");
148
- });
149
-
150
- test("should approve various programming language code blocks with proper detection", async () => {
151
- const documentStructure = [];
152
- const reviewContent = `Programming Language Examples:
153
-
154
- ## Rust with Configuration
155
- \`\`\`rust,no_run
156
- use tokio::signal::windows::ctrl_shutdown;
157
-
158
- #[tokio::main]
159
- async fn main() -> Result<(), Box<dyn std::error::Error>> {
160
- let mut signal = ctrl_shutdown()?;
161
- signal.recv().await;
162
- println!("got CTRL-SHUTDOWN. Cleaning up before exiting");
163
- Ok(())
164
- }
165
- \`\`\`
166
-
167
- ## C# .NET Example
168
- \`\`\`c#
169
- using System;
170
- using System.Threading.Tasks;
171
-
172
- public class Program
173
- {
174
- public static async Task Main(string[] args)
175
- {
176
- Console.WriteLine("Hello C#!");
177
- await Task.Delay(1000);
178
- }
179
- }
180
- \`\`\`
181
-
182
- ## C++ with CLI Extension
183
- \`\`\`c++/cli
184
- #include <iostream>
185
- #include <vector>
186
-
187
- int main() {
188
- std::vector<int> numbers = {1, 2, 3, 4, 5};
189
- for (const auto& num : numbers) {
190
- std::cout << num << " ";
191
- }
192
- return 0;
193
- }
194
- \`\`\`
195
-
196
- ## TypeScript with Extension
197
- \`\`\`typescript.tsx
198
- interface Props {
199
- title: string;
200
- count: number;
201
- }
202
-
203
- const Component: React.FC<Props> = ({ title, count }) => {
204
- return <div>{title}: {count}</div>;
205
- };
206
-
207
- export default Component;
208
- \`\`\`
209
-
210
- ## Python with Version
211
- \`\`\`python,version=3.9
212
- import asyncio
213
- from typing import List, Optional
214
-
215
- async def fetch_data(urls: List[str]) -> Optional[dict]:
216
- tasks = [asyncio.create_task(process_url(url)) for url in urls]
217
- results = await asyncio.gather(*tasks)
218
- return {"results": results}
219
-
220
- if __name__ == "__main__":
221
- asyncio.run(fetch_data(["http://example.com"]))
222
- \`\`\`
223
-
224
- ## Shell Script with Latest Tag
225
- \`\`\`bash:latest
226
- #!/bin/bash
227
- set -euo pipefail
228
-
229
- function deploy_app() {
230
- local app_name="$1"
231
- local version="$2"
232
-
233
- echo "Deploying $app_name version $version"
234
- docker run --rm "$app_name:$version"
235
- }
236
-
237
- deploy_app "my-app" "v1.0.0"
238
- \`\`\`
239
-
240
- ## Node.js Configuration
241
- \`\`\`node.js
242
- const express = require('express');
243
- const app = express();
244
- const PORT = process.env.PORT || 3000;
245
-
246
- app.get('/health', (req, res) => {
247
- res.json({ status: 'ok', timestamp: new Date().toISOString() });
248
- });
249
-
250
- app.listen(PORT, () => {
251
- console.log(\`Server running on port \${PORT}\`);
252
- });
253
- \`\`\`
254
-
255
- This document demonstrates various programming language code blocks.`;
256
-
257
- const result = await checkDetailResult({ documentStructure, reviewContent });
258
- expect(result.isApproved).toBe(true);
259
- expect(result.detailFeedback).toBe("");
260
- });
261
- });
262
-
263
- describe("Content structure validation", () => {
264
- test("should reject single line content", async () => {
265
- const documentStructure = [];
266
- const reviewContent = "This is a single line without proper line breaks";
267
- const result = await checkDetailResult({ documentStructure, reviewContent });
268
- expect(result.isApproved).toBe(false);
269
- expect(result.detailFeedback).toContain("single line content");
270
- });
271
-
272
- test("should reject incomplete content without proper ending", async () => {
273
- const documentStructure = [];
274
- const reviewContent = "This content doesn't end properly\n\nNo proper punctuation";
275
- const result = await checkDetailResult({ documentStructure, reviewContent });
276
- expect(result.isApproved).toBe(false);
277
- expect(result.detailFeedback).toContain("incomplete content");
278
- });
279
-
280
- test("should approve content with valid ending punctuation", async () => {
281
- const documentStructure = [];
282
- const reviewContent = "This content ends properly.\n\nWith valid punctuation.";
283
- const result = await checkDetailResult({ documentStructure, reviewContent });
284
- expect(result.isApproved).toBe(true);
285
- });
286
- });
287
-
288
- describe("Mermaid syntax validation", () => {
289
- test("should reject Mermaid with backticks in node labels", async () => {
290
- const documentStructure = [];
291
- const reviewContent =
292
- "```mermaid\n" + "graph TD\n" + ' A["Contains `backticks` in label"]\n' + "```";
293
- const result = await checkDetailResult({ documentStructure, reviewContent });
294
- expect(result.isApproved).toBe(false);
295
- expect(result.detailFeedback).toContain("backticks in Mermaid node label");
296
- });
297
-
298
- test("should reject Mermaid with numbered lists in node labels", async () => {
299
- const documentStructure = [];
300
- const reviewContent =
301
- "```mermaid\n" + "graph TD\n" + ' A["1. First item\\n2. Second item"]\n' + "```";
302
- const result = await checkDetailResult({ documentStructure, reviewContent });
303
- expect(result.isApproved).toBe(false);
304
- expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
305
- });
306
-
307
- test("should reject Mermaid with numbered lists in edge descriptions", async () => {
308
- const documentStructure = [];
309
- const reviewContent =
310
- "```mermaid\n" + "graph TD\n" + ' A -- "1. First step" --> B\n' + "```";
311
- const result = await checkDetailResult({ documentStructure, reviewContent });
312
- expect(result.isApproved).toBe(false);
313
- expect(result.detailFeedback).toContain("numbered list format in Mermaid edge description");
314
- });
315
-
316
- test("should reject Mermaid with unquoted special characters", async () => {
317
- const documentStructure = [];
318
- const reviewContent =
319
- "```mermaid\n" + "graph TD\n" + " A[Node with: special chars]\n" + "```";
320
- const result = await checkDetailResult({ documentStructure, reviewContent });
321
- expect(result.isApproved).toBe(false);
322
- expect(result.detailFeedback).toContain("unquoted special characters in Mermaid node label");
323
- });
324
-
325
- test("should approve properly formatted Mermaid", async () => {
326
- const documentStructure = [];
327
- const reviewContent =
328
- "```mermaid\n" +
329
- "graph TD\n" +
330
- ' A["Properly quoted label"]\n' +
331
- ' B["Another node"]\n' +
332
- " A --> B\n" +
333
- "```\n\n" +
334
- "This diagram is properly formatted.";
335
- const result = await checkDetailResult({ documentStructure, reviewContent });
336
- expect(result.isApproved).toBe(true);
337
- });
338
- });
339
-
340
- describe("D2 syntax validation", () => {
341
- test("should handle D2 syntax errors", async () => {
342
- const documentStructure = [];
343
- const reviewContent =
344
- "```d2\n" +
345
- "invalid d2 syntax {{\n" + // Malformed D2
346
- "```\n\n" +
347
- "This has proper structure.";
348
- const result = await checkDetailResult({ documentStructure, reviewContent });
349
- expect(result.isApproved).toBe(false);
350
- });
351
- });
352
-
353
- describe("Advanced table edge cases", () => {
354
- test("should handle empty table cells correctly", async () => {
355
- const documentStructure = [];
356
- const reviewContent =
357
- "| Header 1 | Header 2 | Header 3 |\n" +
358
- "|----------|----------|----------|\n" +
359
- "| Cell 1 | | Cell 3 |\n" +
360
- "| | Cell 2 | |";
361
- const result = await checkDetailResult({ documentStructure, reviewContent });
362
- expect(result.isApproved).toBe(true);
363
- });
364
-
365
- test("should handle tables with code spans containing pipes", async () => {
366
- const documentStructure = [];
367
- const reviewContent =
368
- "| Function | Code Example |\n" +
369
- "|----------|---------------|\n" +
370
- "| pipe | `a \\| b` |\n" +
371
- "| filter | `data \\| filter` |";
372
- const result = await checkDetailResult({ documentStructure, reviewContent });
373
- expect(result.isApproved).toBe(true);
374
- });
375
- });
376
-
377
- describe("Code block edge cases", () => {
378
- test("should handle nested code blocks properly", async () => {
379
- const documentStructure = [];
380
- const reviewContent =
381
- "Here's a markdown example:\n\n" +
382
- "```markdown\n" +
383
- "# Title\n" +
384
- "\n" +
385
- "```javascript\n" +
386
- "function test() { return true; }\n" +
387
- "```\n" +
388
- "```\n\n" +
389
- "This content ends properly.";
390
- const result = await checkDetailResult({ documentStructure, reviewContent });
391
- expect(result.isApproved).toBe(true);
392
- });
393
-
394
- test("should handle code blocks with unusual indentation patterns", async () => {
395
- const documentStructure = [];
396
- const reviewContent =
397
- " ```javascript\n" +
398
- " function test() {\n" +
399
- " return 'properly indented';\n" +
400
- " }\n" +
401
- " ```\n\n" +
402
- "This has proper structure.";
403
- const result = await checkDetailResult({ documentStructure, reviewContent });
404
- expect(result.isApproved).toBe(true);
405
- });
406
- });
407
-
408
- describe("Complex Mermaid scenarios", () => {
409
- test("should handle Mermaid with curly brace syntax", async () => {
410
- const documentStructure = [];
411
- const reviewContent =
412
- "```mermaid\n" +
413
- "graph TD\n" +
414
- ' A{"Decision point"}\n' +
415
- ' B["Action"]\n' +
416
- " A --> B\n" +
417
- "```\n\n" +
418
- "This diagram uses proper syntax.";
419
- const result = await checkDetailResult({ documentStructure, reviewContent });
420
- expect(result.isApproved).toBe(true);
421
- });
422
-
423
- test("should reject Mermaid with problematic curly brace labels", async () => {
424
- const documentStructure = [];
425
- const reviewContent =
426
- "```mermaid\n" + "graph TD\n" + ' A{"Contains `backticks` problem"}\n' + "```";
427
- const result = await checkDetailResult({ documentStructure, reviewContent });
428
- expect(result.isApproved).toBe(false);
429
- expect(result.detailFeedback).toContain("backticks in Mermaid node label");
430
- });
431
- });
432
-
433
- describe("Image validation edge cases", () => {
434
- test("should approve data URLs in images", async () => {
435
- const documentStructure = [];
436
- const reviewContent =
437
- "Here's an inline image ![Inline](data:image/svg+xml;base64,PHN2Zz4KPC9zdmc+).\n\n" +
438
- "This has proper structure.";
439
- const result = await checkDetailResult({ documentStructure, reviewContent });
440
- expect(result.isApproved).toBe(true);
441
- });
442
-
443
- test("should handle images with complex alt text", async () => {
444
- const documentStructure = [];
445
- const reviewContent =
446
- "![Complex alt text with [brackets] and (parentheses)](https://example.com/image.png)\n\n" +
447
- "This has proper structure.";
448
- const result = await checkDetailResult({ documentStructure, reviewContent });
449
- expect(result.isApproved).toBe(true);
450
- });
451
- });
452
-
453
- describe("Link validation edge cases", () => {
454
- test("should handle mailto links correctly", async () => {
455
- const documentStructure = [];
456
- const reviewContent =
457
- "Contact us at [email](mailto:test@example.com).\n\n" + "This has proper structure.";
458
- const result = await checkDetailResult({ documentStructure, reviewContent });
459
- expect(result.isApproved).toBe(true);
460
- });
461
-
462
- test("should handle links with anchors", async () => {
463
- const documentStructure = [{ path: "/getting-started" }];
464
- const reviewContent =
465
- "See the [installation section](/getting-started#installation).\n\n" +
466
- "This has proper structure.";
467
- const result = await checkDetailResult({ documentStructure, reviewContent });
468
- expect(result.isApproved).toBe(true);
469
- });
470
-
471
- test("should handle anchor-only links without base path", async () => {
472
- const documentStructure = [];
473
- const reviewContent =
474
- "See the [section](#non-existent-anchor).\n\n" + "This has proper structure.";
475
- const result = await checkDetailResult({ documentStructure, reviewContent });
476
- expect(result.isApproved).toBe(true);
477
- });
478
- });
479
-
480
- describe("Content structure edge cases", () => {
481
- test("should approve content ending with table", async () => {
482
- const documentStructure = [];
483
- const reviewContent =
484
- "Here's a data table:\n\n" +
485
- "| Column 1 | Column 2 |\n" +
486
- "|----------|----------|\n" +
487
- "| Data 1 | Data 2 |";
488
- const result = await checkDetailResult({ documentStructure, reviewContent });
489
- expect(result.isApproved).toBe(true);
490
- });
491
-
492
- test("should approve content ending with list", async () => {
493
- const documentStructure = [];
494
- const reviewContent =
495
- "Here are the requirements:\n\n" +
496
- "- First requirement\n" +
497
- "- Second requirement\n" +
498
- "- Third requirement*";
499
- const result = await checkDetailResult({ documentStructure, reviewContent });
500
- expect(result.isApproved).toBe(true);
501
- });
502
-
503
- test("should approve content ending with blockquote", async () => {
504
- const documentStructure = [];
505
- const reviewContent =
506
- "As they say:\n\n" + "> This is a famous quote that ends with proper punctuation.";
507
- const result = await checkDetailResult({ documentStructure, reviewContent });
508
- expect(result.isApproved).toBe(true);
509
- });
510
- });
511
-
512
- describe("Real-world scenario tests", () => {
513
- test("should approve comprehensive valid document", async () => {
514
- const documentStructure = [
515
- { path: "./getting-started" },
516
- { path: "/api/overview" },
517
- { path: "./advanced/configuration" },
518
- ];
519
- const reviewContent = `# Getting Started Guide
520
-
521
- This is a complete document with proper structure and formatting.
522
-
523
- ## Introduction
524
-
525
- Welcome to our comprehensive guide. This document follows all markdown best practices.
526
-
527
- ## Code Examples
528
-
529
- Here's a properly formatted code block:
530
-
531
- \`\`\`javascript
532
- function validateInput(data) {
533
- if (!data) {
534
- throw new Error("Data is required");
535
- }
536
- return data.trim();
537
- }
538
-
539
- // Export the function
540
- export { validateInput };
541
- \`\`\`
542
-
543
- ## Data Tables
544
-
545
- Our API supports the following data types:
546
-
547
- |Type|Description|Example|
548
- |----|-----------|-------|
549
- |String|Text data|"Hello"|
550
- |Number|Numeric values|42|
551
- |Boolean|True/false|true|
552
-
553
- ## Process Flow
554
-
555
- The following diagram shows our validation process:
556
-
557
- \`\`\`mermaid
558
- flowchart TD
559
- A[Start] --> B{Valid Input?}
560
- B -->|Yes| C[Process Data]
561
- B -->|No| D[Return Error]
562
- C --> E[Save Results]
563
- D --> F[Log Error]
564
- E --> G[End]
565
- F --> G
566
- \`\`\`
567
-
568
- ## Related Documentation
569
-
570
- For more information, see our [API reference](/api/overview) and [advanced configuration](./advanced/configuration).
571
-
572
- This document ends with proper punctuation and formatting.
573
- `;
574
- const result = await checkDetailResult({ documentStructure, reviewContent });
575
- expect(result.isApproved).toBe(true);
576
- });
577
-
578
- test("should approve content with Chinese punctuation", async () => {
579
- const documentStructure = [];
580
- const reviewContent = `# 中文文档
581
-
582
- 这是一个中文文档的示例。
583
-
584
- ## 内容说明
585
-
586
- 文档内容使用中文标点符号。
587
-
588
- 这个文档以中文句号结尾。
589
- `;
590
- const result = await checkDetailResult({ documentStructure, reviewContent });
591
- expect(result.isApproved).toBe(true);
592
- });
593
-
594
- test("should reject document with multiple validation issues", async () => {
595
- const documentStructure = [{ path: "/getting-started" }];
596
- const reviewContent = `# Complex Test Document
597
-
598
- This document has [multiple issues](./broken-link).
599
-
600
- | Column 1 | Column 2 | Column 3 |
601
- | - | - |
602
- | Data 1 | Data 2 | Data 3 |
603
-
604
- \`\`\`mermaid
605
- flowchart TD
606
- A["node with \`backticks\`"] --> B[End]
607
- \`\`\`
608
-
609
- This content doesn't end properly`;
610
- const result = await checkDetailResult({ documentStructure, reviewContent });
611
- expect(result.isApproved).toBe(false);
612
- expect(result.detailFeedback).toContain("dead link");
613
- expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
614
- expect(result.detailFeedback).toContain("incomplete content");
615
- });
616
- });
617
-
618
- describe("Complex code block indentation cases", () => {
619
- test("should reject real-world code block indentation issue", async () => {
620
- const documentStructure = [];
621
- const reviewContent = `# API Response Handling
622
-
623
- You can retrieve the response body in various formats:
624
-
625
- * **\`response.content\`**: Accesses the raw response body as bytes. This is useful for non-text data like images or binary files.
626
- \`\`\`python
627
- import requests
628
-
629
- r = requests.get('https://httpbin.org/image/png')
630
- print(type(r.content))
631
- # Expected output: <class 'bytes'>
632
- \`\`\`
633
-
634
- * **\`response.text\`**: Accesses the response body as Unicode text. Requests automatically guesses the encoding, or you can explicitly set \`response.encoding\`.
635
- \`\`\`python
636
- import requests
637
-
638
- r = requests.get('https://httpbin.org/get')
639
- print(type(r.text))
640
- # Expected output: <class 'str'>
641
- print(r.text)
642
- # Expected output: {"args": {}, "headers": ..., "origin": "...", "url": "https://httpbin.org/get"}
643
- \`\`\`
644
-
645
- This document ends properly.
646
- `;
647
- const result = await checkDetailResult({ documentStructure, reviewContent });
648
- expect(result.isApproved).toBe(false);
649
- expect(result.detailFeedback).toContain("insufficient indentation");
650
- });
651
- });
652
-
653
- describe("Advanced Mermaid validation cases", () => {
654
- test("should reject Mermaid with numbered list in node labels", async () => {
655
- const documentStructure = [];
656
- const reviewContent = `# Test Document
657
-
658
- \`\`\`mermaid
659
- flowchart TD
660
- A["1. Create Backend Implementation<br>api/src/providers/"]
661
- B["2. Add Backend Configuration<br>api/src/providers/models.ts"]
662
- C["3. Update Frontend Selector<br>src/pages/config/ai-providers/"]
663
-
664
- A --> B --> C
665
- \`\`\`
666
-
667
- This content ends properly.
668
- `;
669
- const result = await checkDetailResult({ documentStructure, reviewContent });
670
- expect(result.isApproved).toBe(false);
671
- expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
672
- });
673
-
674
- test("should handle complex Mermaid with subgraph issues", async () => {
675
- const documentStructure = [];
676
- const reviewContent = `# Test Document
677
-
678
- \`\`\`mermaid
679
- flowchart TD
680
- A["FastAPI Application"] --> B["Security & Authentication"];
681
- A --> C["Error Handling"];
682
- H["Project Structure"] -- "Organizes" --> A;
683
-
684
- subgraph Advanced Capabilities
685
- B
686
- C
687
- end
688
-
689
- AdvancedCapabilities --> "Robustness" --> L["Production-Ready API"];
690
- \`\`\`
691
-
692
- This content ends properly.
693
- `;
694
- const result = await checkDetailResult({ documentStructure, reviewContent });
695
- // This may pass or fail depending on Mermaid validation - we just ensure it doesn't crash
696
- expect(typeof result.isApproved).toBe("boolean");
697
- });
698
- });
699
-
700
- describe("Table validation with real content", () => {
701
- test("should approve table with escaped pipes", async () => {
702
- const documentStructure = [];
703
- const reviewContent = `# Test Document
704
-
705
- | 参数 | 类型 | 描述 |
706
- |---|---|---|
707
- | callback | () => void \\| Promise<void> | Payment Kit 组件运行后要执行的函数。这可以是一个异步函数。 |
708
- | wait | boolean | 可选。如果为,稍后在组件启动时执行回调。 |
709
-
710
- This document demonstrates escaped pipe handling.
711
- `;
712
- const result = await checkDetailResult({ documentStructure, reviewContent });
713
- expect(result.isApproved).toBe(true);
714
- });
715
- });
716
-
717
- describe("Error handling", () => {
718
- test("should handle markdown processing errors gracefully", async () => {
719
- const documentStructure = [];
720
- // Test with extremely malformed content that might cause parsing errors
721
- const reviewContent = null;
722
- const result = await checkDetailResult({ documentStructure, reviewContent });
723
- expect(result.isApproved).toBe(false);
724
- expect(result.detailFeedback).toBe("Review content is empty");
725
- });
726
-
727
- test("should handle empty content gracefully", async () => {
728
- const documentStructure = [];
729
- const reviewContent = "";
730
- const result = await checkDetailResult({ documentStructure, reviewContent });
731
- expect(result.isApproved).toBe(false);
732
- expect(result.detailFeedback).toBe("Review content is empty");
733
- });
734
-
735
- test("should handle whitespace-only content", async () => {
736
- const documentStructure = [];
737
- const reviewContent = " \n\n \t \n ";
738
- const result = await checkDetailResult({ documentStructure, reviewContent });
739
- expect(result.isApproved).toBe(false);
740
- expect(result.detailFeedback).toBe("Review content is empty");
741
- });
742
- });
743
- });