@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,463 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
2
- import * as fsPromises from "node:fs/promises";
3
- import * as aigneCore from "@aigne/core";
4
- import checkDocument from "../../../agents/update/check-document.mjs";
5
- import * as checkDetailResultModule from "../../../agents/utils/check-detail-result.mjs";
6
-
7
- describe("check-document", () => {
8
- let mockOptions;
9
-
10
- // Spies for external dependencies
11
- let teamAgentFromSpy;
12
-
13
- // Spies for internal utils and fs operations
14
- let checkDetailResultSpy;
15
- let consoleSpy;
16
- let accessSpy;
17
- let readFileSpy;
18
-
19
- beforeEach(() => {
20
- // Set up spy for external dependencies
21
- teamAgentFromSpy = spyOn(aigneCore.TeamAgent, "from").mockReturnValue({ mockTeamAgent: true });
22
-
23
- mockOptions = {
24
- context: {
25
- agents: {
26
- handleDocumentUpdate: { mockAgent: true },
27
- },
28
- invoke: mock(async () => ({ mockResult: true })),
29
- },
30
- };
31
-
32
- // Set up spies for internal utils
33
- checkDetailResultSpy = spyOn(checkDetailResultModule, "default").mockResolvedValue({
34
- isApproved: true,
35
- detailFeedback: "",
36
- });
37
- consoleSpy = spyOn(console, "log").mockImplementation(() => {});
38
-
39
- // Use spyOn for fs operations instead of module mocking
40
- accessSpy = spyOn(fsPromises, "access").mockResolvedValue(undefined);
41
- readFileSpy = spyOn(fsPromises, "readFile").mockResolvedValue("# Test Content\n\nSome content");
42
-
43
- // Clear context mock call history
44
- mockOptions.context.invoke.mockClear();
45
- });
46
-
47
- afterEach(() => {
48
- // Restore all spies
49
- teamAgentFromSpy?.mockRestore();
50
- checkDetailResultSpy?.mockRestore();
51
- consoleSpy?.mockRestore();
52
- accessSpy?.mockRestore();
53
- readFileSpy?.mockRestore();
54
- });
55
-
56
- // FILE EXISTENCE TESTS
57
- test("should return early when file exists and no changes detected", async () => {
58
- // File exists, no changes
59
- accessSpy.mockResolvedValue();
60
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
61
-
62
- const result = await checkDocument(
63
- {
64
- path: "/getting-started",
65
- docsDir: "./docs",
66
- sourceIds: ["file1.js"],
67
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
68
- documentStructure: [{ path: "/getting-started" }],
69
- modifiedFiles: [],
70
- },
71
- mockOptions,
72
- );
73
-
74
- expect(result.detailGenerated).toBe(true);
75
- expect(mockOptions.context.invoke).not.toHaveBeenCalled();
76
- });
77
-
78
- test("should generate when file does not exist", async () => {
79
- // File doesn't exist
80
- accessSpy.mockRejectedValue(new Error("File not found"));
81
-
82
- const result = await checkDocument(
83
- {
84
- path: "/getting-started",
85
- docsDir: "./docs",
86
- sourceIds: ["file1.js"],
87
- },
88
- mockOptions,
89
- );
90
-
91
- expect(mockOptions.context.invoke).toHaveBeenCalled();
92
- expect(result.path).toBe("/getting-started");
93
- });
94
-
95
- // SOURCE IDS CHANGE TESTS
96
- test("should regenerate when sourceIds have changed", async () => {
97
- accessSpy.mockResolvedValue();
98
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
99
-
100
- await checkDocument(
101
- {
102
- path: "/getting-started",
103
- docsDir: "./docs",
104
- sourceIds: ["file1.js", "file2.js"], // Different from original
105
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
106
- documentStructure: [{ path: "/getting-started" }],
107
- },
108
- mockOptions,
109
- );
110
-
111
- expect(mockOptions.context.invoke).toHaveBeenCalled();
112
- });
113
-
114
- test("should regenerate when sourceIds count changed", async () => {
115
- accessSpy.mockResolvedValue();
116
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
117
-
118
- await checkDocument(
119
- {
120
- path: "/getting-started",
121
- docsDir: "./docs",
122
- sourceIds: ["file1.js", "file2.js", "file3.js"], // More files
123
- originalDocumentStructure: [
124
- { path: "/getting-started", sourceIds: ["file1.js", "file2.js"] },
125
- ],
126
- documentStructure: [{ path: "/getting-started" }],
127
- },
128
- mockOptions,
129
- );
130
-
131
- expect(mockOptions.context.invoke).toHaveBeenCalled();
132
- });
133
-
134
- test("should not regenerate when sourceIds are same (different order)", async () => {
135
- accessSpy.mockResolvedValue();
136
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
137
-
138
- const result = await checkDocument(
139
- {
140
- path: "/getting-started",
141
- docsDir: "./docs",
142
- sourceIds: ["file2.js", "file1.js"], // Same files, different order
143
- originalDocumentStructure: [
144
- { path: "/getting-started", sourceIds: ["file1.js", "file2.js"] },
145
- ],
146
- documentStructure: [{ path: "/getting-started" }],
147
- modifiedFiles: [],
148
- },
149
- mockOptions,
150
- );
151
-
152
- expect(result.detailGenerated).toBe(true);
153
- expect(mockOptions.context.invoke).not.toHaveBeenCalled();
154
- });
155
-
156
- test("should handle missing originalDocumentStructure gracefully", async () => {
157
- accessSpy.mockResolvedValue();
158
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
159
-
160
- const result = await checkDocument(
161
- {
162
- path: "/getting-started",
163
- docsDir: "./docs",
164
- sourceIds: ["file1.js"],
165
- originalDocumentStructure: null,
166
- documentStructure: [{ path: "/getting-started" }],
167
- modifiedFiles: [],
168
- },
169
- mockOptions,
170
- );
171
-
172
- expect(result.detailGenerated).toBe(true);
173
- expect(mockOptions.context.invoke).not.toHaveBeenCalled();
174
- });
175
-
176
- test("should handle missing original node in documentation structure", async () => {
177
- accessSpy.mockResolvedValue();
178
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
179
-
180
- const result = await checkDocument(
181
- {
182
- path: "/getting-started",
183
- docsDir: "./docs",
184
- sourceIds: ["file1.js"],
185
- originalDocumentStructure: [{ path: "/different-path", sourceIds: ["file1.js"] }],
186
- documentStructure: [{ path: "/getting-started" }],
187
- modifiedFiles: [],
188
- },
189
- mockOptions,
190
- );
191
-
192
- expect(result.detailGenerated).toBe(true);
193
- expect(mockOptions.context.invoke).not.toHaveBeenCalled();
194
- });
195
-
196
- // SOURCE FILES CHANGE TESTS - These tests are now obsolete as modifiedFiles checking has been removed
197
- // The check-document function now only checks for sourceIds changes and content validation
198
-
199
- // CONTENT VALIDATION TESTS
200
- test("should regenerate when content validation fails", async () => {
201
- accessSpy.mockResolvedValue();
202
- readFileSpy.mockResolvedValue("# Test Content");
203
- checkDetailResultSpy.mockResolvedValue({
204
- isApproved: false,
205
- detailFeedback: "Content needs improvement",
206
- });
207
-
208
- await checkDocument(
209
- {
210
- path: "/getting-started",
211
- docsDir: "./docs",
212
- sourceIds: ["file1.js"],
213
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
214
- documentStructure: [{ path: "/getting-started" }],
215
- modifiedFiles: [],
216
- },
217
- mockOptions,
218
- );
219
-
220
- expect(checkDetailResultSpy).toHaveBeenCalledWith({
221
- documentStructure: [{ path: "/getting-started" }],
222
- reviewContent: "# Test Content",
223
- docsDir: "./docs",
224
- });
225
- expect(mockOptions.context.invoke).toHaveBeenCalledWith(
226
- { mockTeamAgent: true },
227
- expect.objectContaining({
228
- detailFeedback: "Content needs improvement",
229
- }),
230
- );
231
- });
232
-
233
- test("should not validate content when file doesn't exist", async () => {
234
- accessSpy.mockRejectedValue(new Error("File not found"));
235
-
236
- await checkDocument(
237
- {
238
- path: "/getting-started",
239
- docsDir: "./docs",
240
- documentStructure: [{ path: "/getting-started" }],
241
- },
242
- mockOptions,
243
- );
244
-
245
- expect(checkDetailResultSpy).not.toHaveBeenCalled();
246
- });
247
-
248
- test("should not validate content when no documentStructure provided", async () => {
249
- accessSpy.mockResolvedValue();
250
- readFileSpy.mockResolvedValue("# Test Content");
251
-
252
- const result = await checkDocument(
253
- {
254
- path: "/getting-started",
255
- docsDir: "./docs",
256
- sourceIds: ["file1.js"],
257
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
258
- documentStructure: null,
259
- modifiedFiles: [],
260
- },
261
- mockOptions,
262
- );
263
-
264
- expect(checkDetailResultSpy).not.toHaveBeenCalled();
265
- expect(result.detailGenerated).toBe(true);
266
- });
267
-
268
- // FORCE REGENERATE TESTS
269
- test("should regenerate when forceRegenerate is true", async () => {
270
- accessSpy.mockResolvedValue();
271
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
272
-
273
- await checkDocument(
274
- {
275
- path: "/getting-started",
276
- docsDir: "./docs",
277
- sourceIds: ["file1.js"],
278
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
279
- documentStructure: [{ path: "/getting-started" }],
280
- modifiedFiles: [],
281
- forceRegenerate: true,
282
- },
283
- mockOptions,
284
- );
285
-
286
- expect(mockOptions.context.invoke).toHaveBeenCalled();
287
- });
288
-
289
- // TEAM AGENT TESTS
290
- test("should create team agent with correct configuration", async () => {
291
- accessSpy.mockRejectedValue(new Error("File not found"));
292
-
293
- await checkDocument(
294
- {
295
- path: "/getting-started",
296
- docsDir: "./docs",
297
- },
298
- mockOptions,
299
- );
300
-
301
- expect(teamAgentFromSpy).toHaveBeenCalledWith({
302
- name: "generateDocument",
303
- skills: [{ mockAgent: true }],
304
- });
305
- });
306
-
307
- test("should invoke team agent with correct parameters", async () => {
308
- accessSpy.mockRejectedValue(new Error("File not found"));
309
-
310
- await checkDocument(
311
- {
312
- path: "/getting-started",
313
- docsDir: "./docs",
314
- sourceIds: ["file1.js"],
315
- originalDocumentStructure: [{ path: "/getting-started" }],
316
- documentStructure: [{ path: "/getting-started" }],
317
- customParam: "test",
318
- },
319
- mockOptions,
320
- );
321
-
322
- expect(mockOptions.context.invoke).toHaveBeenCalledWith(
323
- { mockTeamAgent: true },
324
- expect.objectContaining({
325
- path: "/getting-started",
326
- docsDir: "./docs",
327
- sourceIds: ["file1.js"],
328
- originalDocumentStructure: [{ path: "/getting-started" }],
329
- documentStructure: [{ path: "/getting-started" }],
330
- customParam: "test",
331
- detailFeedback: "",
332
- }),
333
- );
334
- });
335
-
336
- // PATH PROCESSING TESTS
337
- test("should handle root path correctly", async () => {
338
- accessSpy.mockRejectedValue(new Error("File not found"));
339
-
340
- await checkDocument(
341
- {
342
- path: "/",
343
- docsDir: "./docs",
344
- },
345
- mockOptions,
346
- );
347
-
348
- // Root path "/" -> flatName "" -> fileFullName ".md"
349
- expect(accessSpy).toHaveBeenCalledWith(expect.stringMatching(/\.md$/));
350
- });
351
-
352
- test("should handle nested path correctly", async () => {
353
- accessSpy.mockRejectedValue(new Error("File not found"));
354
-
355
- await checkDocument(
356
- {
357
- path: "/api/users/create",
358
- docsDir: "./docs",
359
- locale: "en",
360
- },
361
- mockOptions,
362
- );
363
-
364
- // "/api/users/create" -> flatName "api-users-create" -> fileFullName "api-users-create.md"
365
- // The access function is called with a full path that includes docsDir
366
- expect(accessSpy).toHaveBeenCalled();
367
- const callArg = accessSpy.mock.calls[0][0];
368
- expect(callArg).toMatch(/api-users-create\.md$/);
369
- });
370
-
371
- // RESULT STRUCTURE TESTS
372
- test("should return correct result structure when regenerating", async () => {
373
- accessSpy.mockRejectedValue(new Error("File not found"));
374
- mockOptions.context.invoke.mockResolvedValue({ generatedContent: "test" });
375
-
376
- const result = await checkDocument(
377
- {
378
- path: "/getting-started",
379
- docsDir: "./docs",
380
- customParam: "test",
381
- },
382
- mockOptions,
383
- );
384
-
385
- expect(result).toEqual({
386
- path: "/getting-started",
387
- docsDir: "./docs",
388
- customParam: "test",
389
- result: { generatedContent: "test" },
390
- });
391
- });
392
-
393
- test("should return correct result structure when not regenerating", async () => {
394
- accessSpy.mockResolvedValue();
395
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
396
-
397
- const result = await checkDocument(
398
- {
399
- path: "/getting-started",
400
- docsDir: "./docs",
401
- sourceIds: ["file1.js"],
402
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
403
- documentStructure: [{ path: "/getting-started" }],
404
- modifiedFiles: [],
405
- customParam: "test",
406
- },
407
- mockOptions,
408
- );
409
-
410
- expect(result).toEqual({
411
- path: "/getting-started",
412
- docsDir: "./docs",
413
- customParam: "test",
414
- detailGenerated: true,
415
- });
416
- });
417
-
418
- // EDGE CASES
419
- test("should handle file read errors gracefully", async () => {
420
- accessSpy.mockResolvedValue();
421
- readFileSpy.mockRejectedValue(new Error("Read error"));
422
-
423
- // When file read fails, content validation is skipped, and since file exists
424
- // but can't be read properly, no early return occurs, so regeneration happens
425
- const result = await checkDocument(
426
- {
427
- path: "/getting-started",
428
- docsDir: "./docs",
429
- sourceIds: ["file1.js"],
430
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: ["file1.js"] }],
431
- documentStructure: [{ path: "/getting-started" }],
432
- modifiedFiles: [],
433
- },
434
- mockOptions,
435
- );
436
-
437
- // When file read fails, no content validation happens, and since no early return
438
- // condition is met, the function should proceed to regeneration
439
- expect(result.result).toBeDefined();
440
- expect(mockOptions.context.invoke).toHaveBeenCalled();
441
- expect(checkDetailResultSpy).not.toHaveBeenCalled();
442
- });
443
-
444
- test("should handle empty sourceIds arrays", async () => {
445
- accessSpy.mockResolvedValue();
446
- checkDetailResultSpy.mockResolvedValue({ isApproved: true });
447
-
448
- const result = await checkDocument(
449
- {
450
- path: "/getting-started",
451
- docsDir: "./docs",
452
- sourceIds: [],
453
- originalDocumentStructure: [{ path: "/getting-started", sourceIds: [] }],
454
- documentStructure: [{ path: "/getting-started" }],
455
- modifiedFiles: [],
456
- },
457
- mockOptions,
458
- );
459
-
460
- expect(result.detailGenerated).toBe(true);
461
- expect(mockOptions.context.invoke).not.toHaveBeenCalled();
462
- });
463
- });