@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,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
- });