@aigne/doc-smith 0.8.12-beta.8 → 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 (264) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/agents/publish/index.yaml +4 -0
  3. package/agents/publish/publish-docs.mjs +77 -5
  4. package/agents/publish/translate-meta.mjs +103 -0
  5. package/agents/update/generate-document.yaml +30 -28
  6. package/agents/update/update-document-detail.yaml +3 -1
  7. package/agents/utils/update-branding.mjs +69 -0
  8. package/package.json +16 -2
  9. package/prompts/common/document/role-and-personality.md +3 -1
  10. package/prompts/detail/d2-diagram/guide.md +7 -1
  11. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  12. package/prompts/detail/generate/system-prompt.md +6 -7
  13. package/prompts/detail/generate/user-prompt.md +12 -3
  14. package/prompts/detail/update/user-prompt.md +0 -2
  15. package/prompts/structure/update/user-prompt.md +0 -4
  16. package/utils/file-utils.mjs +69 -24
  17. package/utils/markdown-checker.mjs +0 -20
  18. package/utils/request.mjs +7 -0
  19. package/utils/upload-files.mjs +231 -0
  20. package/utils/utils.mjs +11 -1
  21. package/.aigne/doc-smith/config.yaml +0 -77
  22. package/.aigne/doc-smith/history.yaml +0 -37
  23. package/.aigne/doc-smith/media-description.yaml +0 -91
  24. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  25. package/.aigne/doc-smith/preferences.yml +0 -97
  26. package/.aigne/doc-smith/upload-cache.yaml +0 -1830
  27. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  28. package/.github/workflows/ci.yml +0 -54
  29. package/.github/workflows/create-release-pr.yaml +0 -21
  30. package/.github/workflows/publish-docs.yml +0 -65
  31. package/.github/workflows/release.yml +0 -49
  32. package/.github/workflows/reviewer.yml +0 -54
  33. package/.release-please-manifest.json +0 -3
  34. package/RELEASE.md +0 -9
  35. package/assets/screenshots/doc-complete-setup.png +0 -0
  36. package/assets/screenshots/doc-generate-docs.png +0 -0
  37. package/assets/screenshots/doc-generate.png +0 -0
  38. package/assets/screenshots/doc-generated-successfully.png +0 -0
  39. package/assets/screenshots/doc-publish.png +0 -0
  40. package/assets/screenshots/doc-regenerate.png +0 -0
  41. package/assets/screenshots/doc-translate-langs.png +0 -0
  42. package/assets/screenshots/doc-translate.png +0 -0
  43. package/assets/screenshots/doc-update.png +0 -0
  44. package/biome.json +0 -73
  45. package/codecov.yml +0 -15
  46. package/docs/_sidebar.md +0 -15
  47. package/docs/configuration-initial-setup.ja.md +0 -179
  48. package/docs/configuration-initial-setup.md +0 -198
  49. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  50. package/docs/configuration-initial-setup.zh.md +0 -179
  51. package/docs/configuration-managing-preferences.ja.md +0 -100
  52. package/docs/configuration-managing-preferences.md +0 -100
  53. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  54. package/docs/configuration-managing-preferences.zh.md +0 -100
  55. package/docs/configuration.ja.md +0 -69
  56. package/docs/configuration.md +0 -69
  57. package/docs/configuration.zh-TW.md +0 -69
  58. package/docs/configuration.zh.md +0 -69
  59. package/docs/getting-started.ja.md +0 -107
  60. package/docs/getting-started.md +0 -107
  61. package/docs/getting-started.zh-TW.md +0 -107
  62. package/docs/getting-started.zh.md +0 -107
  63. package/docs/guides-cleaning-up.ja.md +0 -51
  64. package/docs/guides-cleaning-up.md +0 -52
  65. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  66. package/docs/guides-cleaning-up.zh.md +0 -51
  67. package/docs/guides-evaluating-documents.ja.md +0 -66
  68. package/docs/guides-evaluating-documents.md +0 -107
  69. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  70. package/docs/guides-evaluating-documents.zh.md +0 -66
  71. package/docs/guides-generating-documentation.ja.md +0 -151
  72. package/docs/guides-generating-documentation.md +0 -89
  73. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  74. package/docs/guides-generating-documentation.zh.md +0 -151
  75. package/docs/guides-interactive-chat.ja.md +0 -85
  76. package/docs/guides-interactive-chat.md +0 -93
  77. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  78. package/docs/guides-interactive-chat.zh.md +0 -85
  79. package/docs/guides-managing-history.ja.md +0 -48
  80. package/docs/guides-managing-history.md +0 -53
  81. package/docs/guides-managing-history.zh-TW.md +0 -48
  82. package/docs/guides-managing-history.zh.md +0 -48
  83. package/docs/guides-publishing-your-docs.ja.md +0 -78
  84. package/docs/guides-publishing-your-docs.md +0 -83
  85. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  86. package/docs/guides-publishing-your-docs.zh.md +0 -78
  87. package/docs/guides-translating-documentation.ja.md +0 -95
  88. package/docs/guides-translating-documentation.md +0 -100
  89. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  90. package/docs/guides-translating-documentation.zh.md +0 -95
  91. package/docs/guides-updating-documentation.ja.md +0 -77
  92. package/docs/guides-updating-documentation.md +0 -79
  93. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  94. package/docs/guides-updating-documentation.zh.md +0 -77
  95. package/docs/guides.ja.md +0 -32
  96. package/docs/guides.md +0 -32
  97. package/docs/guides.zh-TW.md +0 -32
  98. package/docs/guides.zh.md +0 -32
  99. package/docs/overview.ja.md +0 -61
  100. package/docs/overview.md +0 -61
  101. package/docs/overview.zh-TW.md +0 -61
  102. package/docs/overview.zh.md +0 -61
  103. package/docs/release-notes.ja.md +0 -255
  104. package/docs/release-notes.md +0 -288
  105. package/docs/release-notes.zh-TW.md +0 -255
  106. package/docs/release-notes.zh.md +0 -255
  107. package/prompts/common/afs/afs-tools-usage.md +0 -5
  108. package/prompts/common/afs/use-afs-instruction.md +0 -1
  109. package/release-please-config.json +0 -14
  110. package/tests/agents/chat/chat.test.mjs +0 -46
  111. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  112. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  113. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  114. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  115. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  116. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  117. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  118. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  119. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  120. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  121. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  122. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  123. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  124. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  125. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  126. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  127. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  128. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  129. package/tests/agents/history/view.test.mjs +0 -97
  130. package/tests/agents/init/init.test.mjs +0 -1657
  131. package/tests/agents/prefs/prefs.test.mjs +0 -431
  132. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  133. package/tests/agents/translate/choose-language.test.mjs +0 -311
  134. package/tests/agents/translate/translate-document.test.mjs +0 -51
  135. package/tests/agents/update/check-document.test.mjs +0 -463
  136. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  137. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  138. package/tests/agents/update/generate-document.test.mjs +0 -51
  139. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  140. package/tests/agents/update/user-review-document.test.mjs +0 -582
  141. package/tests/agents/utils/action-success.test.mjs +0 -54
  142. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  143. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  144. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  145. package/tests/agents/utils/exit.test.mjs +0 -70
  146. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  147. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  148. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  149. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  150. package/tests/agents/utils/fs.test.mjs +0 -267
  151. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  152. package/tests/agents/utils/save-docs.test.mjs +0 -109
  153. package/tests/agents/utils/save-output.test.mjs +0 -315
  154. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  155. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  156. package/tests/utils/auth-utils.test.mjs +0 -596
  157. package/tests/utils/blocklet.test.mjs +0 -336
  158. package/tests/utils/conflict-detector.test.mjs +0 -355
  159. package/tests/utils/constants.test.mjs +0 -295
  160. package/tests/utils/d2-utils.test.mjs +0 -437
  161. package/tests/utils/deploy.test.mjs +0 -399
  162. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  163. package/tests/utils/file-utils.test.mjs +0 -521
  164. package/tests/utils/history-utils.test.mjs +0 -206
  165. package/tests/utils/kroki-utils.test.mjs +0 -646
  166. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  167. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  168. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  169. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  170. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  171. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  172. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  173. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  174. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  175. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  176. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  177. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  178. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  179. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  180. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  181. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  182. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  183. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  184. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  185. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  186. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  187. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  188. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  189. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  190. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  191. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  192. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  193. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  194. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  195. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  196. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  197. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  198. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  199. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  200. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  201. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  202. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  203. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  204. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  205. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  206. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  207. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  208. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  209. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  210. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  211. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  212. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  213. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  214. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  215. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  216. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  217. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  218. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  219. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  220. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  221. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  222. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  223. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  224. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  225. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  226. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  227. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  228. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  229. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  230. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  231. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  232. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  233. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  234. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  235. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  236. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  237. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  238. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  239. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  240. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  241. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  242. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  243. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  244. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  245. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  246. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  247. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  248. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  249. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  250. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  251. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  252. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  253. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  254. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  255. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  256. package/tests/utils/linter/index.test.mjs +0 -440
  257. package/tests/utils/linter/scan-results.mjs +0 -42
  258. package/tests/utils/load-config.test.mjs +0 -141
  259. package/tests/utils/markdown/index.test.mjs +0 -478
  260. package/tests/utils/mermaid-validator.test.mjs +0 -541
  261. package/tests/utils/mock-chat-model.mjs +0 -12
  262. package/tests/utils/preferences-utils.test.mjs +0 -465
  263. package/tests/utils/save-value-to-config.test.mjs +0 -483
  264. 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
- });