@aigne/doc-smith 0.8.12-beta.8 → 0.8.12

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 +15 -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,311 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
2
- import chooseLanguage from "../../../agents/translate/choose-language.mjs";
3
-
4
- import * as utils from "../../../utils/utils.mjs";
5
-
6
- describe("choose-language", () => {
7
- let mockOptions;
8
-
9
- // Spies for internal utils
10
- let loadConfigFromFileSpy;
11
- let saveValueToConfigSpy;
12
- let consoleSpy;
13
-
14
- beforeEach(() => {
15
- mock.restore();
16
-
17
- mockOptions = {
18
- prompts: {
19
- checkbox: mock(async () => ["zh", "ja"]),
20
- },
21
- };
22
-
23
- // Set up spies for internal utils
24
- loadConfigFromFileSpy = spyOn(utils, "loadConfigFromFile").mockResolvedValue({});
25
- saveValueToConfigSpy = spyOn(utils, "saveValueToConfig").mockResolvedValue();
26
- consoleSpy = spyOn(console, "log").mockImplementation(() => {});
27
-
28
- // Clear prompts mock call history
29
- mockOptions.prompts.checkbox.mockClear();
30
- });
31
-
32
- afterEach(() => {
33
- // Restore all spies
34
- loadConfigFromFileSpy?.mockRestore();
35
- saveValueToConfigSpy?.mockRestore();
36
- consoleSpy?.mockRestore();
37
- });
38
-
39
- // BASIC FUNCTIONALITY TESTS
40
- test("should return selected languages with provided langs parameter", async () => {
41
- const selectedDocs = [
42
- { path: "/doc1", title: "Document 1" },
43
- { path: "/doc2", title: "Document 2" },
44
- ];
45
-
46
- const result = await chooseLanguage(
47
- {
48
- langs: ["zh", "ja"],
49
- locale: "en",
50
- selectedDocs,
51
- },
52
- mockOptions,
53
- );
54
-
55
- expect(result.selectedLanguages).toEqual(["zh", "ja"]);
56
- expect(result.selectedDocs).toHaveLength(2);
57
- expect(result.selectedDocs[0].translates).toEqual([{ language: "zh" }, { language: "ja" }]);
58
- expect(mockOptions.prompts.checkbox).not.toHaveBeenCalled();
59
- });
60
-
61
- test("should prompt for language selection when no langs provided", async () => {
62
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
63
-
64
- const result = await chooseLanguage(
65
- {
66
- locale: "en",
67
- selectedDocs,
68
- },
69
- mockOptions,
70
- );
71
-
72
- expect(mockOptions.prompts.checkbox).toHaveBeenCalledWith(
73
- expect.objectContaining({
74
- message: "Select translation languages:",
75
- choices: expect.any(Array),
76
- validate: expect.any(Function),
77
- }),
78
- );
79
- expect(result.selectedLanguages).toEqual(["zh", "ja"]);
80
- });
81
-
82
- test("should exclude primary language from available choices", async () => {
83
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
84
-
85
- await chooseLanguage(
86
- {
87
- locale: "zh",
88
- selectedDocs,
89
- },
90
- mockOptions,
91
- );
92
-
93
- const choices = mockOptions.prompts.checkbox.mock.calls[0][0].choices;
94
- const zhChoice = choices.find((choice) => choice.value === "zh");
95
- expect(zhChoice).toBeUndefined();
96
-
97
- // Should have English available since zh is primary
98
- const enChoice = choices.find((choice) => choice.value === "en");
99
- expect(enChoice).toBeDefined();
100
- });
101
-
102
- test("should use existing config for primary language when not provided", async () => {
103
- loadConfigFromFileSpy.mockResolvedValue({ locale: "es" });
104
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
105
-
106
- await chooseLanguage({ selectedDocs }, mockOptions);
107
-
108
- const choices = mockOptions.prompts.checkbox.mock.calls[0][0].choices;
109
- const esChoice = choices.find((choice) => choice.value === "es");
110
- expect(esChoice).toBeUndefined(); // Spanish should be excluded as primary
111
- });
112
-
113
- test("should default to 'en' when no locale in config or parameter", async () => {
114
- loadConfigFromFileSpy.mockResolvedValue({});
115
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
116
-
117
- await chooseLanguage({ selectedDocs }, mockOptions);
118
-
119
- const choices = mockOptions.prompts.checkbox.mock.calls[0][0].choices;
120
- const enChoice = choices.find((choice) => choice.value === "en");
121
- expect(enChoice).toBeUndefined(); // English should be excluded as primary
122
- });
123
-
124
- // VALIDATION TESTS
125
- test("should validate checkbox selection requires at least one language", async () => {
126
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
127
-
128
- await chooseLanguage({ locale: "en", selectedDocs }, mockOptions);
129
-
130
- const validateFn = mockOptions.prompts.checkbox.mock.calls[0][0].validate;
131
- expect(validateFn([])).toBe("Please select at least one language");
132
- expect(validateFn(["zh"])).toBe(true);
133
- });
134
-
135
- test("should filter out invalid languages from langs parameter", async () => {
136
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
137
-
138
- const result = await chooseLanguage(
139
- {
140
- langs: ["zh", "invalid-lang", "ja", "another-invalid"],
141
- locale: "en",
142
- selectedDocs,
143
- },
144
- mockOptions,
145
- );
146
-
147
- expect(result.selectedLanguages).toEqual(["zh", "ja"]);
148
- expect(consoleSpy).not.toHaveBeenCalled(); // Valid languages were found
149
- });
150
-
151
- test("should show warning and prompt when all provided langs are invalid", async () => {
152
- mockOptions.prompts.checkbox.mockResolvedValue(["fr"]);
153
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
154
-
155
- const result = await chooseLanguage(
156
- {
157
- langs: ["invalid1", "invalid2"],
158
- locale: "en",
159
- selectedDocs,
160
- },
161
- mockOptions,
162
- );
163
-
164
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invalid languages provided"));
165
- expect(mockOptions.prompts.checkbox).toHaveBeenCalled();
166
- expect(result.selectedLanguages).toEqual(["fr"]);
167
- });
168
-
169
- test("should throw error when no languages are selected", async () => {
170
- mockOptions.prompts.checkbox.mockResolvedValue([]);
171
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
172
-
173
- await expect(chooseLanguage({ locale: "en", selectedDocs }, mockOptions)).rejects.toThrow(
174
- "No languages selected for translation",
175
- );
176
- });
177
-
178
- // CONFIG MANAGEMENT TESTS
179
- test("should save new languages to config", async () => {
180
- loadConfigFromFileSpy.mockResolvedValue({
181
- translateLanguages: ["zh"],
182
- });
183
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
184
-
185
- await chooseLanguage(
186
- {
187
- langs: ["zh", "ja", "fr"], // ja and fr are new
188
- locale: "en",
189
- selectedDocs,
190
- },
191
- mockOptions,
192
- );
193
-
194
- expect(saveValueToConfigSpy).toHaveBeenCalledWith("translateLanguages", ["zh", "ja", "fr"]);
195
- });
196
-
197
- test("should not save to config when no new languages", async () => {
198
- loadConfigFromFileSpy.mockResolvedValue({
199
- translateLanguages: ["zh", "ja"],
200
- });
201
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
202
-
203
- await chooseLanguage(
204
- {
205
- langs: ["zh", "ja"], // All existing
206
- locale: "en",
207
- selectedDocs,
208
- },
209
- mockOptions,
210
- );
211
-
212
- expect(saveValueToConfigSpy).not.toHaveBeenCalled();
213
- });
214
-
215
- test("should mark previously selected languages as checked in prompt", async () => {
216
- loadConfigFromFileSpy.mockResolvedValue({
217
- translateLanguages: ["zh", "ja"],
218
- });
219
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
220
-
221
- await chooseLanguage({ locale: "en", selectedDocs }, mockOptions);
222
-
223
- const choices = mockOptions.prompts.checkbox.mock.calls[0][0].choices;
224
- const zhChoice = choices.find((choice) => choice.value === "zh");
225
- const jaChoice = choices.find((choice) => choice.value === "ja");
226
- const frChoice = choices.find((choice) => choice.value === "fr");
227
-
228
- expect(zhChoice.checked).toBe(true);
229
- expect(jaChoice.checked).toBe(true);
230
- expect(frChoice.checked).toBe(false);
231
- });
232
-
233
- // DOCUMENT PROCESSING TESTS
234
- test("should add translation info to selected documents", async () => {
235
- const selectedDocs = [
236
- { path: "/doc1", title: "Document 1", existing: "data" },
237
- { path: "/doc2", title: "Document 2" },
238
- ];
239
-
240
- const result = await chooseLanguage(
241
- {
242
- langs: ["zh", "ja"],
243
- locale: "en",
244
- selectedDocs,
245
- },
246
- mockOptions,
247
- );
248
-
249
- expect(result.selectedDocs).toEqual([
250
- {
251
- path: "/doc1",
252
- title: "Document 1",
253
- existing: "data",
254
- translates: [{ language: "zh" }, { language: "ja" }],
255
- },
256
- {
257
- path: "/doc2",
258
- title: "Document 2",
259
- translates: [{ language: "zh" }, { language: "ja" }],
260
- },
261
- ]);
262
- });
263
-
264
- // EDGE CASES
265
- test("should handle empty selectedDocs array", async () => {
266
- const result = await chooseLanguage(
267
- {
268
- langs: ["zh"],
269
- locale: "en",
270
- selectedDocs: [],
271
- },
272
- mockOptions,
273
- );
274
-
275
- expect(result.selectedDocs).toEqual([]);
276
- expect(result.selectedLanguages).toEqual(["zh"]);
277
- });
278
-
279
- test("should handle empty langs array", async () => {
280
- mockOptions.prompts.checkbox.mockResolvedValue(["fr"]);
281
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
282
-
283
- const result = await chooseLanguage(
284
- {
285
- langs: [],
286
- locale: "en",
287
- selectedDocs,
288
- },
289
- mockOptions,
290
- );
291
-
292
- expect(mockOptions.prompts.checkbox).toHaveBeenCalled();
293
- expect(result.selectedLanguages).toEqual(["fr"]);
294
- });
295
-
296
- test("should handle missing config file", async () => {
297
- loadConfigFromFileSpy.mockResolvedValue(null);
298
- const selectedDocs = [{ path: "/doc1", title: "Document 1" }];
299
-
300
- const result = await chooseLanguage(
301
- {
302
- langs: ["zh"],
303
- locale: "en",
304
- selectedDocs,
305
- },
306
- mockOptions,
307
- );
308
-
309
- expect(result.selectedLanguages).toEqual(["zh"]);
310
- });
311
- });
@@ -1,51 +0,0 @@
1
- import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
- import { join } from "node:path";
3
- import { AIAgent } from "@aigne/core";
4
- import { loadAgent } from "@aigne/core/loader/index.js";
5
- import { loadModel } from "../../utils/mock-chat-model.mjs";
6
-
7
- describe("translateDocument Agent", () => {
8
- beforeAll(() => {
9
- process.env.AIGNE_OBSERVABILITY_DISABLED = "true";
10
- });
11
-
12
- afterAll(() => {
13
- delete process.env.AIGNE_OBSERVABILITY_DISABLED;
14
- });
15
- test("should load agent correctly with proper configuration", async () => {
16
- const agent = await loadAgent(
17
- join(import.meta.dirname, "../../../agents/translate/translate-document.yaml"),
18
- {
19
- model: loadModel,
20
- },
21
- );
22
-
23
- expect(agent).toBeDefined();
24
-
25
- // Verify agent exists and is correct type
26
- expect(agent).toBeDefined();
27
- expect(agent).toBeInstanceOf(AIAgent);
28
- expect(agent.name).toBe("translateDocument");
29
- });
30
-
31
- test("should have instructions loaded from file", async () => {
32
- const agent = await loadAgent(
33
- join(import.meta.dirname, "../../../agents/translate/translate-document.yaml"),
34
- {
35
- model: loadModel,
36
- },
37
- );
38
-
39
- expect(agent).toBeDefined();
40
-
41
- // Verify instructions are loaded
42
- expect(agent.instructions).toBeDefined();
43
- const instructions = await agent.instructions.build({});
44
- expect(instructions.messages).toBeDefined();
45
- expect(instructions.messages.length).toBeGreaterThan(0);
46
-
47
- // The instructions should contain content from the prompt file
48
- const systemMessage = instructions.messages.find((m) => m.role === "system");
49
- expect(systemMessage).toBeDefined();
50
- });
51
- });