@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,319 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
2
- import userReviewDocumentStructure from "../../../agents/generate/user-review-document-structure.mjs";
3
-
4
- import * as preferencesUtils from "../../../utils/preferences-utils.mjs";
5
- import * as historyUtils from "../../../utils/history-utils.mjs";
6
-
7
- describe("user-review-document-structure", () => {
8
- let mockOptions;
9
- let documentStructure;
10
-
11
- // Spies for internal utils
12
- let getActiveRulesForScopeSpy;
13
- let consoleSpy;
14
-
15
- beforeEach(() => {
16
- // Reset all mocks
17
- mock.restore();
18
-
19
- documentStructure = [
20
- {
21
- path: "/getting-started",
22
- title: "Getting Started",
23
- description: "Introduction and setup guide",
24
- parentId: null,
25
- },
26
- {
27
- path: "/getting-started/installation",
28
- title: "Installation",
29
- description: "How to install the project",
30
- parentId: "/getting-started",
31
- },
32
- {
33
- path: "/api",
34
- title: "API Reference",
35
- description: "Complete API documentation",
36
- parentId: null,
37
- },
38
- ];
39
-
40
- mockOptions = {
41
- prompts: {
42
- select: mock(async () => "no"),
43
- input: mock(async () => ""),
44
- },
45
- context: {
46
- agents: {
47
- updateDocumentStructure: {},
48
- checkFeedbackRefiner: {},
49
- },
50
- invoke: mock(async () => ({
51
- documentStructure: documentStructure,
52
- })),
53
- userContext: {
54
- currentStructure: [],
55
- },
56
- },
57
- };
58
-
59
- // Set up spies for internal utils
60
- getActiveRulesForScopeSpy = spyOn(preferencesUtils, "getActiveRulesForScope").mockReturnValue(
61
- [],
62
- );
63
-
64
- consoleSpy = spyOn(console, "log").mockImplementation(() => {});
65
- spyOn(historyUtils, "recordUpdate").mockImplementation(() => {});
66
-
67
- // Clear prompts mock call history
68
- mockOptions.prompts.select.mockClear();
69
- mockOptions.prompts.input.mockClear();
70
- mockOptions.context.invoke.mockClear();
71
- });
72
-
73
- afterEach(() => {
74
- // Restore all spies
75
- getActiveRulesForScopeSpy?.mockRestore();
76
- consoleSpy?.mockRestore();
77
- });
78
-
79
- test("should return original structure when no documentation structure provided", async () => {
80
- const result = await userReviewDocumentStructure({}, mockOptions);
81
-
82
- expect(result).toBeDefined();
83
- expect(result.documentStructure).toBeUndefined();
84
- expect(mockOptions.prompts.select).not.toHaveBeenCalled();
85
- expect(consoleSpy).toHaveBeenCalledWith("No documentation structure was generated to review.");
86
- });
87
-
88
- test("should return original structure when empty array provided", async () => {
89
- const result = await userReviewDocumentStructure({ documentStructure: [] }, mockOptions);
90
-
91
- expect(result).toBeDefined();
92
- expect(result.documentStructure).toEqual([]);
93
- expect(mockOptions.prompts.select).not.toHaveBeenCalled();
94
- expect(consoleSpy).toHaveBeenCalledWith("No documentation structure was generated to review.");
95
- });
96
-
97
- test("should return original structure when user chooses not to review", async () => {
98
- mockOptions.prompts.select.mockImplementation(async () => "no");
99
-
100
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
101
-
102
- expect(result).toBeDefined();
103
- expect(result.documentStructure).toEqual(documentStructure);
104
- expect(mockOptions.prompts.select).toHaveBeenCalled();
105
- expect(mockOptions.prompts.input).not.toHaveBeenCalled();
106
- });
107
-
108
- test("should enter review loop when user chooses to review", async () => {
109
- mockOptions.prompts.select.mockImplementation(async () => "yes");
110
- mockOptions.prompts.input.mockImplementation(async () => ""); // Empty feedback to exit loop
111
-
112
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
113
-
114
- expect(result).toBeDefined();
115
- expect(result.documentStructure).toEqual(documentStructure);
116
- expect(mockOptions.prompts.select).toHaveBeenCalled();
117
- expect(mockOptions.prompts.input).toHaveBeenCalled();
118
- expect(consoleSpy).toHaveBeenCalledWith(
119
- expect.stringContaining("Current Documentation Structure"),
120
- );
121
- });
122
-
123
- test("should process user feedback and call refineDocumentStructure agent", async () => {
124
- const feedback = "Please add more details to the API section";
125
- const refinedStructure = [
126
- ...documentStructure,
127
- {
128
- path: "/api/authentication",
129
- title: "Authentication",
130
- description: "How to authenticate API requests",
131
- parentId: "/api",
132
- },
133
- ];
134
-
135
- mockOptions.prompts.select.mockImplementation(async () => "yes");
136
- mockOptions.prompts.input
137
- .mockImplementationOnce(async () => feedback)
138
- .mockImplementationOnce(async () => ""); // Exit loop on second call
139
-
140
- mockOptions.context.invoke.mockImplementation(async () => {
141
- // Simulate the agent updating the shared context
142
- mockOptions.context.userContext.currentStructure = refinedStructure;
143
- return {
144
- documentStructure: refinedStructure,
145
- };
146
- });
147
-
148
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
149
-
150
- expect(mockOptions.context.invoke).toHaveBeenCalledWith(
151
- mockOptions.context.agents.updateDocumentStructure,
152
- expect.objectContaining({
153
- feedback: feedback,
154
- documentStructure: documentStructure,
155
- userPreferences: "",
156
- }),
157
- );
158
- expect(mockOptions.context.invoke).toHaveBeenCalledWith(
159
- mockOptions.context.agents.checkFeedbackRefiner,
160
- expect.objectContaining({
161
- documentStructureFeedback: feedback,
162
- stage: "structure",
163
- }),
164
- );
165
- expect(result.documentStructure).toEqual(refinedStructure);
166
- });
167
-
168
- test("should include user preferences in refinement call", async () => {
169
- const mockRules = [{ rule: "Keep sections concise" }, { rule: "Use clear headings" }];
170
- const expectedPreferences = "Keep sections concise\n\nUse clear headings";
171
-
172
- getActiveRulesForScopeSpy
173
- .mockImplementationOnce(() => mockRules) // structure rules
174
- .mockImplementationOnce(() => []); // global rules
175
-
176
- mockOptions.prompts.select.mockImplementation(async () => "yes");
177
- mockOptions.prompts.input
178
- .mockImplementationOnce(async () => "Add more examples")
179
- .mockImplementationOnce(async () => "");
180
-
181
- await userReviewDocumentStructure({ documentStructure }, mockOptions);
182
-
183
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("structure", []);
184
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
185
- expect(mockOptions.context.invoke).toHaveBeenCalledWith(
186
- mockOptions.context.agents.updateDocumentStructure,
187
- expect.objectContaining({
188
- userPreferences: expectedPreferences,
189
- }),
190
- );
191
- });
192
-
193
- test("should handle missing updateDocumentStructure agent", async () => {
194
- mockOptions.context.agents = {}; // No updateDocumentStructure agent
195
- mockOptions.prompts.select.mockImplementation(async () => "yes");
196
- mockOptions.prompts.input.mockImplementation(async () => "Some feedback");
197
-
198
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
199
-
200
- expect(result.documentStructure).toEqual(documentStructure);
201
- expect(consoleSpy).toHaveBeenCalledWith(
202
- "Unable to process your feedback - the documentation structure update feature is unavailable.",
203
- );
204
- });
205
-
206
- test("should handle errors from updateDocumentStructure agent", async () => {
207
- mockOptions.prompts.select.mockImplementation(async () => "yes");
208
- mockOptions.prompts.input
209
- .mockImplementationOnce(async () => "Some feedback")
210
- .mockImplementationOnce(async () => "");
211
-
212
- mockOptions.context.invoke.mockImplementation(async () => {
213
- throw new Error("Agent failed");
214
- });
215
-
216
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
217
-
218
- expect(result.documentStructure).toEqual(documentStructure);
219
- expect(consoleSpy).toHaveBeenCalledWith(
220
- "\nPlease try rephrasing your feedback or continue with the current structure.",
221
- );
222
- });
223
-
224
- test("should handle multiple feedback rounds", async () => {
225
- const firstFeedback = "Add authentication section";
226
- const secondFeedback = "Reorganize API structure";
227
-
228
- const firstRefinedStructure = [
229
- ...documentStructure,
230
- {
231
- path: "/api/auth",
232
- title: "Authentication",
233
- description: "Auth guide",
234
- parentId: "/api",
235
- },
236
- ];
237
-
238
- const finalRefinedStructure = [
239
- ...firstRefinedStructure,
240
- {
241
- path: "/api/endpoints",
242
- title: "Endpoints",
243
- description: "API endpoints",
244
- parentId: "/api",
245
- },
246
- ];
247
-
248
- mockOptions.prompts.select.mockImplementation(async () => "yes");
249
- mockOptions.prompts.input
250
- .mockImplementationOnce(async () => firstFeedback)
251
- .mockImplementationOnce(async () => secondFeedback)
252
- .mockImplementationOnce(async () => ""); // Exit loop
253
-
254
- let invokeCount = 0;
255
- mockOptions.context.invoke.mockImplementation(async () => {
256
- invokeCount++;
257
- if (invokeCount === 1) {
258
- // refineDocumentStructure 1st call
259
- mockOptions.context.userContext.currentStructure = firstRefinedStructure;
260
- return { documentStructure: firstRefinedStructure };
261
- } else if (invokeCount === 2) {
262
- // checkFeedbackRefiner 1st call
263
- return {};
264
- } else if (invokeCount === 3) {
265
- // refineDocumentStructure 2nd call
266
- mockOptions.context.userContext.currentStructure = finalRefinedStructure;
267
- return { documentStructure: finalRefinedStructure };
268
- } else {
269
- // checkFeedbackRefiner 2nd call
270
- return {};
271
- }
272
- });
273
-
274
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
275
-
276
- expect(mockOptions.context.invoke).toHaveBeenCalledTimes(4); // 2 refine + 2 feedback refiner calls
277
- expect(result.documentStructure).toEqual(finalRefinedStructure);
278
- });
279
-
280
- test("should handle missing checkFeedbackRefiner agent gracefully", async () => {
281
- const feedback = "Some feedback";
282
- mockOptions.context.agents = { updateDocumentStructure: {} }; // No checkFeedbackRefiner agent
283
-
284
- mockOptions.prompts.select.mockImplementation(async () => "yes");
285
- mockOptions.prompts.input
286
- .mockImplementationOnce(async () => feedback)
287
- .mockImplementationOnce(async () => "");
288
-
289
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
290
-
291
- expect(result.documentStructure).toEqual(documentStructure);
292
- expect(mockOptions.context.invoke).toHaveBeenCalledTimes(1); // Only refineDocumentStructure called
293
- });
294
-
295
- test("should handle checkFeedbackRefiner errors gracefully", async () => {
296
- const feedback = "Some feedback";
297
- const warnSpy = spyOn(console, "warn").mockImplementation(() => {});
298
-
299
- mockOptions.prompts.select.mockImplementation(async () => "yes");
300
- mockOptions.prompts.input
301
- .mockImplementationOnce(async () => feedback)
302
- .mockImplementationOnce(async () => "");
303
-
304
- mockOptions.context.invoke
305
- .mockImplementationOnce(async () => ({ documentStructure })) // refineDocumentStructure
306
- .mockImplementationOnce(async () => {
307
- throw new Error("Refiner failed");
308
- }); // checkFeedbackRefiner
309
-
310
- const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
311
-
312
- expect(result.documentStructure).toEqual(documentStructure);
313
- expect(warnSpy).toHaveBeenCalledWith(
314
- "Your feedback was applied but not saved as a preference.",
315
- );
316
-
317
- warnSpy.mockRestore();
318
- });
319
- });
@@ -1,97 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test, mock, spyOn } from "bun:test";
2
- import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { DOC_SMITH_DIR } from "../../../utils/constants/index.mjs";
5
- import viewHistory from "../../../agents/history/view.mjs";
6
-
7
- const TEST_DIR = join(process.cwd(), `${DOC_SMITH_DIR}-test`);
8
- const ORIGINAL_CWD = process.cwd();
9
-
10
- describe("History View", () => {
11
- let consoleLogMock;
12
-
13
- beforeEach(async () => {
14
- // Clean up test directory
15
- if (existsSync(TEST_DIR)) {
16
- rmSync(TEST_DIR, { recursive: true });
17
- }
18
- mkdirSync(TEST_DIR, { recursive: true });
19
-
20
- // Change to test directory
21
- process.chdir(TEST_DIR);
22
-
23
- // Spy on console.log
24
- consoleLogMock = spyOn(console, "log");
25
- });
26
-
27
- afterEach(() => {
28
- // Restore original directory
29
- process.chdir(ORIGINAL_CWD);
30
-
31
- // Clean up
32
- if (existsSync(TEST_DIR)) {
33
- rmSync(TEST_DIR, { recursive: true });
34
- }
35
-
36
- mock.restore();
37
- });
38
-
39
- test("should display message when no history exists", () => {
40
- // No history file exists
41
- const result = viewHistory();
42
-
43
- expect(result).toEqual({});
44
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("No update history found"));
45
- });
46
-
47
- test("should display formatted history entries", async () => {
48
- // Create history file with sample data
49
- const historyPath = join(process.cwd(), DOC_SMITH_DIR, "history.yaml");
50
- mkdirSync(join(process.cwd(), DOC_SMITH_DIR), { recursive: true });
51
-
52
- const historyData = {
53
- entries: [
54
- {
55
- timestamp: "2023-01-01T00:00:00.000Z",
56
- operation: "document_update",
57
- feedback: "Updated documentation",
58
- documentPath: "/readme.md",
59
- },
60
- {
61
- timestamp: "2023-01-02T00:00:00.000Z",
62
- operation: "structure_update",
63
- feedback: "Reorganized sections",
64
- },
65
- ],
66
- };
67
-
68
- // Use YAML format instead of JSON
69
- const { stringify } = await import("yaml");
70
- writeFileSync(historyPath, stringify(historyData), "utf8");
71
-
72
- const result = viewHistory();
73
-
74
- expect(result).toEqual({});
75
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("📜 Update History"));
76
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("document_update"));
77
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("structure_update"));
78
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("Updated documentation"));
79
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("Reorganized sections"));
80
- });
81
-
82
- test("should handle empty history entries", async () => {
83
- // Create history file with empty entries
84
- const historyPath = join(process.cwd(), DOC_SMITH_DIR, "history.yaml");
85
- mkdirSync(join(process.cwd(), DOC_SMITH_DIR), { recursive: true });
86
-
87
- const historyData = { entries: [] };
88
- // Use YAML format instead of JSON
89
- const { stringify } = await import("yaml");
90
- writeFileSync(historyPath, stringify(historyData), "utf8");
91
-
92
- const result = viewHistory();
93
-
94
- expect(result).toEqual({});
95
- expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("No update history found"));
96
- });
97
- });