@aigne/doc-smith 0.9.10 → 0.9.11-beta

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 (308) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +189 -219
  3. package/README.zh.md +270 -0
  4. package/agents/bash-executor/index.mjs +347 -0
  5. package/agents/clear/ai/intent.md +142 -0
  6. package/agents/clear/choose-contents.mjs +13 -65
  7. package/agents/clear/clear-auth-tokens.mjs +17 -21
  8. package/agents/clear/clear-deployment-config.mjs +33 -24
  9. package/agents/clear/index.yaml +1 -9
  10. package/agents/content-checker/ai/intent.md +209 -0
  11. package/agents/content-checker/clean-invalid-docs.mjs +254 -0
  12. package/agents/content-checker/index.mjs +191 -0
  13. package/agents/content-checker/validate-content.mjs +983 -0
  14. package/agents/generate-images/generate-image.yaml +75 -0
  15. package/agents/generate-images/generate-summary.mjs +213 -0
  16. package/agents/generate-images/index.yaml +39 -0
  17. package/agents/generate-images/prepare-generation.mjs +286 -0
  18. package/agents/generate-images/prepare-image-generation.mjs +130 -0
  19. package/{prompts/detail/diagram/generate-image-system.md → agents/generate-images/prompts/system.md} +22 -56
  20. package/agents/generate-images/prompts/user.md +85 -0
  21. package/agents/generate-images/save-image-result.mjs +247 -0
  22. package/agents/generate-images/scan-image-slots.mjs +247 -0
  23. package/agents/localize/index.yaml +19 -42
  24. package/{prompts/translate → agents/localize/prompts}/translate-document.md +0 -139
  25. package/agents/localize/translate-documents/generate-summary.mjs +163 -0
  26. package/agents/localize/translate-documents/load-glossary.mjs +52 -0
  27. package/agents/localize/translate-documents/prepare-translation.mjs +249 -0
  28. package/agents/localize/translate-documents/save-translation.mjs +171 -0
  29. package/agents/localize/translate-documents/translate-document-to-language.mjs +209 -0
  30. package/agents/localize/translate-documents/translate-document.yaml +23 -0
  31. package/agents/localize/translate-documents/translate-to-languages.yaml +10 -0
  32. package/agents/localize/translate-images/check-image-translation.mjs +225 -0
  33. package/agents/localize/translate-images/detect-text/detect-and-update-shared.mjs +148 -0
  34. package/agents/localize/translate-images/detect-text/detect-image-text.yaml +44 -0
  35. package/agents/localize/translate-images/detect-text/detect-images-text.yaml +21 -0
  36. package/agents/localize/translate-images/detect-text/prompts/detect-image-text-system.md +43 -0
  37. package/agents/localize/translate-images/detect-text/prompts/detect-image-text-user.md +14 -0
  38. package/agents/localize/translate-images/detect-text/save-text-detection.mjs +105 -0
  39. package/agents/localize/translate-images/prepare-image-input.mjs +124 -0
  40. package/agents/localize/translate-images/save-image-translation.mjs +172 -0
  41. package/agents/localize/translate-images/scan-doc-images.mjs +165 -0
  42. package/agents/localize/translate-images/translate-doc-images.yaml +24 -0
  43. package/agents/localize/{translate-diagram.yaml → translate-images/translate-image.yaml} +25 -14
  44. package/agents/publish/ai/intent.md +182 -0
  45. package/agents/publish/check.mjs +107 -0
  46. package/agents/publish/index.yaml +9 -14
  47. package/agents/publish/publish-docs.mjs +81 -61
  48. package/agents/publish/translate-meta.mjs +79 -58
  49. package/agents/save-document/index.mjs +260 -0
  50. package/agents/structure-checker/index.mjs +307 -0
  51. package/agents/structure-checker/validate-structure.mjs +477 -0
  52. package/agents/update-image/analyze-feedback.yaml +37 -0
  53. package/agents/update-image/index.yaml +78 -0
  54. package/agents/update-image/load-existing-image.mjs +211 -0
  55. package/agents/update-image/prompts/analyze-feedback-system.md +43 -0
  56. package/agents/update-image/prompts/analyze-feedback-user.md +15 -0
  57. package/aigne.yaml +26 -139
  58. package/package.json +16 -48
  59. package/scripts/README.md +90 -0
  60. package/scripts/install.sh +86 -0
  61. package/scripts/uninstall.sh +52 -0
  62. package/skills/doc-smith/SKILL.md +285 -0
  63. package/skills/doc-smith/ai/intent/sources-improve.md +290 -0
  64. package/skills/doc-smith/references/changeset-guide.md +171 -0
  65. package/skills/doc-smith/references/document-content-guide.md +214 -0
  66. package/skills/doc-smith/references/document-structure-schema.md +138 -0
  67. package/skills/doc-smith/references/patch-guide.md +96 -0
  68. package/skills/doc-smith/references/structure-confirmation-guide.md +133 -0
  69. package/skills/doc-smith/references/structure-planning-guide.md +149 -0
  70. package/skills/doc-smith/references/update-workflow.md +108 -0
  71. package/skills/doc-smith/references/user-intent-guide.md +175 -0
  72. package/skills/doc-smith/references/workspace-initialization.md +376 -0
  73. package/skills/doc-smith-docs-detail/SKILL.md +356 -0
  74. package/skills/doc-smith-docs-detail/ai/intent.md +271 -0
  75. package/skills-entry/doc-smith/ai/intent.md +260 -0
  76. package/skills-entry/doc-smith/index.mjs +66 -0
  77. package/skills-entry/doc-smith/prompt.md +57 -0
  78. package/skills-entry/doc-smith/utils.mjs +27 -0
  79. package/skills-entry/doc-smith-docs-detail/batch.yaml +56 -0
  80. package/skills-entry/doc-smith-docs-detail/index.mjs +95 -0
  81. package/skills-entry/doc-smith-docs-detail/prompt.md +64 -0
  82. package/utils/afs-factory.mjs +183 -0
  83. package/utils/agent-constants.mjs +97 -0
  84. package/utils/{auth-utils.mjs → auth.mjs} +6 -9
  85. package/{agents/utils/update-branding.mjs → utils/branding.mjs} +3 -4
  86. package/utils/config.mjs +261 -0
  87. package/utils/constants.mjs +32 -0
  88. package/utils/deploy.mjs +3 -3
  89. package/utils/docs-converter.mjs +454 -0
  90. package/utils/docs.mjs +212 -0
  91. package/utils/document-paths.mjs +172 -0
  92. package/utils/files.mjs +74 -0
  93. package/utils/git.mjs +65 -0
  94. package/utils/{blocklet.mjs → http.mjs} +18 -0
  95. package/utils/image-slots.mjs +57 -0
  96. package/utils/image-utils.mjs +114 -0
  97. package/utils/project.mjs +95 -0
  98. package/utils/sources-path-resolver.mjs +76 -0
  99. package/utils/{upload-files.mjs → upload.mjs} +3 -3
  100. package/utils/workspace.mjs +371 -0
  101. package/agents/chat/chat-system.md +0 -38
  102. package/agents/chat/index.mjs +0 -59
  103. package/agents/chat/skills/generate-document.yaml +0 -15
  104. package/agents/chat/skills/list-documents.mjs +0 -15
  105. package/agents/chat/skills/update-document.yaml +0 -24
  106. package/agents/clear/clear-document-config.mjs +0 -36
  107. package/agents/clear/clear-document-structure.mjs +0 -102
  108. package/agents/clear/clear-generated-docs.mjs +0 -142
  109. package/agents/clear/clear-media-description.mjs +0 -129
  110. package/agents/create/aggregate-document-structure.mjs +0 -21
  111. package/agents/create/analyze-diagram-type-llm.yaml +0 -159
  112. package/agents/create/analyze-diagram-type.mjs +0 -455
  113. package/agents/create/check-document-structure.yaml +0 -30
  114. package/agents/create/check-need-generate-structure.mjs +0 -138
  115. package/agents/create/document-structure-tools/add-document.mjs +0 -85
  116. package/agents/create/document-structure-tools/delete-document.mjs +0 -116
  117. package/agents/create/document-structure-tools/move-document.mjs +0 -109
  118. package/agents/create/document-structure-tools/update-document.mjs +0 -84
  119. package/agents/create/generate-diagram-image.yaml +0 -91
  120. package/agents/create/generate-structure.yaml +0 -106
  121. package/agents/create/index.yaml +0 -45
  122. package/agents/create/refine-document-structure.yaml +0 -12
  123. package/agents/create/replace-d2-with-image.mjs +0 -610
  124. package/agents/create/update-document-structure.yaml +0 -54
  125. package/agents/create/user-add-document/add-documents-to-structure.mjs +0 -90
  126. package/agents/create/user-add-document/find-documents-to-add-links.yaml +0 -47
  127. package/agents/create/user-add-document/index.yaml +0 -46
  128. package/agents/create/user-add-document/prepare-documents-to-translate.mjs +0 -22
  129. package/agents/create/user-add-document/print-add-document-summary.mjs +0 -63
  130. package/agents/create/user-add-document/review-documents-with-new-links.mjs +0 -110
  131. package/agents/create/user-remove-document/find-documents-with-invalid-links.mjs +0 -78
  132. package/agents/create/user-remove-document/index.yaml +0 -40
  133. package/agents/create/user-remove-document/prepare-documents-to-translate.mjs +0 -22
  134. package/agents/create/user-remove-document/print-remove-document-summary.mjs +0 -53
  135. package/agents/create/user-remove-document/remove-documents-from-structure.mjs +0 -99
  136. package/agents/create/user-remove-document/review-documents-with-invalid-links.mjs +0 -115
  137. package/agents/create/user-review-document-structure.mjs +0 -139
  138. package/agents/create/utils/init-current-content.mjs +0 -34
  139. package/agents/create/utils/merge-document-structures.mjs +0 -36
  140. package/agents/evaluate/code-snippet.mjs +0 -97
  141. package/agents/evaluate/document-structure.yaml +0 -67
  142. package/agents/evaluate/document.yaml +0 -82
  143. package/agents/evaluate/generate-report.mjs +0 -85
  144. package/agents/evaluate/index.yaml +0 -46
  145. package/agents/history/index.yaml +0 -6
  146. package/agents/history/view.mjs +0 -78
  147. package/agents/init/check.mjs +0 -16
  148. package/agents/init/index.mjs +0 -643
  149. package/agents/init/validate.mjs +0 -16
  150. package/agents/localize/choose-language.mjs +0 -107
  151. package/agents/localize/record-translation-history.mjs +0 -23
  152. package/agents/localize/save-doc-translation-or-skip.mjs +0 -18
  153. package/agents/localize/set-review-content.mjs +0 -58
  154. package/agents/localize/translate-document-wrapper.mjs +0 -34
  155. package/agents/localize/translate-document.yaml +0 -24
  156. package/agents/localize/translate-multilingual.yaml +0 -57
  157. package/agents/localize/translate-or-skip-diagram.mjs +0 -52
  158. package/agents/media/batch-generate-media-description.yaml +0 -46
  159. package/agents/media/generate-media-description.yaml +0 -50
  160. package/agents/media/load-media-description.mjs +0 -454
  161. package/agents/prefs/index.mjs +0 -203
  162. package/agents/schema/document-structure-item.yaml +0 -26
  163. package/agents/schema/document-structure-refine-item.yaml +0 -23
  164. package/agents/schema/document-structure.yaml +0 -29
  165. package/agents/update/batch-generate-document.yaml +0 -27
  166. package/agents/update/batch-update-document.yaml +0 -7
  167. package/agents/update/check-diagram-flag.mjs +0 -116
  168. package/agents/update/check-document.mjs +0 -162
  169. package/agents/update/check-generate-diagram.mjs +0 -106
  170. package/agents/update/check-update-is-single.mjs +0 -53
  171. package/agents/update/document-tools/update-document-content.mjs +0 -303
  172. package/agents/update/generate-diagram.yaml +0 -80
  173. package/agents/update/generate-document.yaml +0 -70
  174. package/agents/update/handle-document-update.yaml +0 -103
  175. package/agents/update/index.yaml +0 -69
  176. package/agents/update/pre-check-generate-diagram.yaml +0 -44
  177. package/agents/update/save-and-translate-document.mjs +0 -80
  178. package/agents/update/update-document-detail.yaml +0 -71
  179. package/agents/update/update-single/update-single-document-detail.mjs +0 -322
  180. package/agents/update/update-single-document.yaml +0 -7
  181. package/agents/update/user-review-document.mjs +0 -272
  182. package/agents/utils/action-success.mjs +0 -16
  183. package/agents/utils/analyze-document-feedback-intent.yaml +0 -32
  184. package/agents/utils/analyze-feedback-intent.mjs +0 -253
  185. package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
  186. package/agents/utils/check-detail-result.mjs +0 -51
  187. package/agents/utils/check-feedback-refiner.mjs +0 -81
  188. package/agents/utils/choose-docs.mjs +0 -251
  189. package/agents/utils/document-icon-generate.yaml +0 -52
  190. package/agents/utils/document-title-streamline.yaml +0 -48
  191. package/agents/utils/ensure-document-icons.mjs +0 -129
  192. package/agents/utils/exit.mjs +0 -6
  193. package/agents/utils/feedback-refiner.yaml +0 -50
  194. package/agents/utils/find-item-by-path.mjs +0 -114
  195. package/agents/utils/find-user-preferences-by-path.mjs +0 -37
  196. package/agents/utils/format-document-structure.mjs +0 -35
  197. package/agents/utils/generate-document-or-skip.mjs +0 -41
  198. package/agents/utils/handle-diagram-operations.mjs +0 -263
  199. package/agents/utils/load-all-document-content.mjs +0 -30
  200. package/agents/utils/load-document-all-content.mjs +0 -96
  201. package/agents/utils/load-sources.mjs +0 -405
  202. package/agents/utils/map-reasoning-effort-level.mjs +0 -15
  203. package/agents/utils/post-generate.mjs +0 -133
  204. package/agents/utils/read-current-document-content.mjs +0 -46
  205. package/agents/utils/save-doc-translation.mjs +0 -30
  206. package/agents/utils/save-doc.mjs +0 -54
  207. package/agents/utils/save-output.mjs +0 -26
  208. package/agents/utils/save-sidebar.mjs +0 -38
  209. package/agents/utils/skip-if-content-exists.mjs +0 -27
  210. package/agents/utils/streamline-document-titles-if-needed.mjs +0 -88
  211. package/agents/utils/transform-detail-data-sources.mjs +0 -45
  212. package/assets/report-template/report.html +0 -198
  213. package/docs-mcp/analyze-content-relevance.yaml +0 -50
  214. package/docs-mcp/analyze-docs-relevance.yaml +0 -59
  215. package/docs-mcp/docs-search.yaml +0 -42
  216. package/docs-mcp/get-docs-detail.mjs +0 -41
  217. package/docs-mcp/get-docs-structure.mjs +0 -16
  218. package/docs-mcp/read-doc-content.mjs +0 -119
  219. package/prompts/common/document/content-rules-core.md +0 -20
  220. package/prompts/common/document/markdown-syntax-rules.md +0 -65
  221. package/prompts/common/document/media-file-list-usage-rules.md +0 -18
  222. package/prompts/common/document/openapi-usage-rules.md +0 -189
  223. package/prompts/common/document/role-and-personality.md +0 -16
  224. package/prompts/common/document/user-preferences.md +0 -9
  225. package/prompts/common/document-structure/conflict-resolution-guidance.md +0 -16
  226. package/prompts/common/document-structure/document-icon-generate.md +0 -116
  227. package/prompts/common/document-structure/document-structure-rules.md +0 -43
  228. package/prompts/common/document-structure/document-title-streamline.md +0 -86
  229. package/prompts/common/document-structure/glossary.md +0 -7
  230. package/prompts/common/document-structure/intj-traits.md +0 -5
  231. package/prompts/common/document-structure/openapi-usage-rules.md +0 -28
  232. package/prompts/common/document-structure/output-constraints.md +0 -18
  233. package/prompts/common/document-structure/user-locale-rules.md +0 -10
  234. package/prompts/common/document-structure/user-preferences.md +0 -9
  235. package/prompts/detail/custom/admonition-usage-rules.md +0 -94
  236. package/prompts/detail/custom/code-block-usage-rules.md +0 -163
  237. package/prompts/detail/custom/custom-components/x-card-usage-rules.md +0 -63
  238. package/prompts/detail/custom/custom-components/x-cards-usage-rules.md +0 -83
  239. package/prompts/detail/custom/custom-components/x-field-desc-usage-rules.md +0 -120
  240. package/prompts/detail/custom/custom-components/x-field-group-usage-rules.md +0 -80
  241. package/prompts/detail/custom/custom-components/x-field-usage-rules.md +0 -189
  242. package/prompts/detail/custom/custom-components-usage-rules.md +0 -18
  243. package/prompts/detail/diagram/generate-image-user.md +0 -81
  244. package/prompts/detail/diagram/guide.md +0 -29
  245. package/prompts/detail/diagram/official-examples.md +0 -712
  246. package/prompts/detail/diagram/pre-check.md +0 -23
  247. package/prompts/detail/diagram/role-and-personality.md +0 -2
  248. package/prompts/detail/diagram/rules.md +0 -46
  249. package/prompts/detail/diagram/system-prompt.md +0 -1139
  250. package/prompts/detail/diagram/user-prompt.md +0 -43
  251. package/prompts/detail/generate/detail-example.md +0 -457
  252. package/prompts/detail/generate/document-rules.md +0 -45
  253. package/prompts/detail/generate/system-prompt.md +0 -61
  254. package/prompts/detail/generate/user-prompt.md +0 -99
  255. package/prompts/detail/jsx/rules.md +0 -6
  256. package/prompts/detail/update/system-prompt.md +0 -121
  257. package/prompts/detail/update/user-prompt.md +0 -41
  258. package/prompts/evaluate/document-structure.md +0 -93
  259. package/prompts/evaluate/document.md +0 -149
  260. package/prompts/media/media-description/system-prompt.md +0 -43
  261. package/prompts/media/media-description/user-prompt.md +0 -17
  262. package/prompts/structure/check-document-structure.md +0 -93
  263. package/prompts/structure/document-rules.md +0 -21
  264. package/prompts/structure/find-documents-to-add-links.md +0 -52
  265. package/prompts/structure/generate/system-prompt.md +0 -13
  266. package/prompts/structure/generate/user-prompt.md +0 -137
  267. package/prompts/structure/review/structure-review-system.md +0 -81
  268. package/prompts/structure/structure-example.md +0 -89
  269. package/prompts/structure/structure-getting-started.md +0 -10
  270. package/prompts/structure/update/system-prompt.md +0 -93
  271. package/prompts/structure/update/user-prompt.md +0 -43
  272. package/prompts/translate/admonition.md +0 -20
  273. package/prompts/translate/code-block.md +0 -33
  274. package/prompts/utils/analyze-document-feedback-intent.md +0 -54
  275. package/prompts/utils/analyze-structure-feedback-intent.md +0 -43
  276. package/prompts/utils/feedback-refiner.md +0 -105
  277. package/types/document-schema.mjs +0 -55
  278. package/types/document-structure-schema.mjs +0 -261
  279. package/utils/check-document-has-diagram.mjs +0 -95
  280. package/utils/conflict-detector.mjs +0 -149
  281. package/utils/constants/index.mjs +0 -620
  282. package/utils/constants/linter.mjs +0 -102
  283. package/utils/d2-utils.mjs +0 -205
  284. package/utils/debug.mjs +0 -3
  285. package/utils/delete-diagram-images.mjs +0 -99
  286. package/utils/diagram-version-utils.mjs +0 -14
  287. package/utils/docs-finder-utils.mjs +0 -548
  288. package/utils/evaluate/report-utils.mjs +0 -132
  289. package/utils/extract-api.mjs +0 -32
  290. package/utils/file-utils.mjs +0 -960
  291. package/utils/history-utils.mjs +0 -203
  292. package/utils/icon-map.mjs +0 -26
  293. package/utils/image-compress.mjs +0 -154
  294. package/utils/kroki-utils.mjs +0 -173
  295. package/utils/linter/index.mjs +0 -50
  296. package/utils/load-config.mjs +0 -78
  297. package/utils/markdown/index.mjs +0 -26
  298. package/utils/markdown-checker.mjs +0 -694
  299. package/utils/mermaid-validator.mjs +0 -140
  300. package/utils/mermaid-worker-pool.mjs +0 -250
  301. package/utils/mermaid-worker.mjs +0 -233
  302. package/utils/openapi/index.mjs +0 -28
  303. package/utils/preferences-utils.mjs +0 -175
  304. package/utils/request.mjs +0 -10
  305. package/utils/sync-diagram-to-translations.mjs +0 -272
  306. package/utils/translate-diagram-images.mjs +0 -807
  307. package/utils/utils.mjs +0 -1354
  308. /package/{prompts/translate → agents/localize/prompts}/glossary.md +0 -0
@@ -0,0 +1,249 @@
1
+ import { loadDocumentPaths, filterValidPaths } from "../../../utils/document-paths.mjs";
2
+ import { PATHS, ERROR_CODES } from "../../../utils/agent-constants.mjs";
3
+ import { loadLocale, loadConfigFromFile, saveValueToConfig } from "../../../utils/config.mjs";
4
+
5
+ /**
6
+ * Prepare translation tasks
7
+ * @param {Object} input - Input parameters
8
+ * @param {string[]} input.docs - Document paths to translate (optional)
9
+ * @param {string[]} input.langs - Target language list (required)
10
+ * @param {boolean} input.force - Whether to force re-translation (optional, default false)
11
+ * @returns {Promise<Object>} - Translation task list or error message
12
+ */
13
+ export default async function prepareTranslation(input) {
14
+ try {
15
+ // 1. Validate langs parameter
16
+ const { docs, langs, force = false } = input;
17
+
18
+ if (!langs || !Array.isArray(langs) || langs.length === 0) {
19
+ return {
20
+ success: false,
21
+ error: ERROR_CODES.MISSING_LANGS,
22
+ message: "Target language list cannot be empty",
23
+ suggestion: 'Please provide at least one target language (e.g., ["en", "ja"])',
24
+ };
25
+ }
26
+
27
+ // 2. Read source language
28
+ let sourceLanguage;
29
+ try {
30
+ sourceLanguage = await loadLocale();
31
+ } catch (error) {
32
+ if (error.message === ERROR_CODES.MISSING_CONFIG_FILE) {
33
+ return {
34
+ success: false,
35
+ error: ERROR_CODES.MISSING_CONFIG_FILE,
36
+ message: `Config file does not exist: ${PATHS.CONFIG}`,
37
+ suggestion:
38
+ "Please ensure you are executing this command in the document project root directory",
39
+ };
40
+ }
41
+ if (error.message === ERROR_CODES.MISSING_LOCALE) {
42
+ return {
43
+ success: false,
44
+ error: ERROR_CODES.MISSING_LOCALE,
45
+ message: `Missing locale field in ${PATHS.CONFIG}`,
46
+ suggestion: `Please add locale field to ${PATHS.CONFIG}`,
47
+ };
48
+ }
49
+ throw error;
50
+ }
51
+
52
+ // 3. Filter out languages same as source language
53
+ const targetLanguages = langs.filter((lang) => lang !== sourceLanguage);
54
+
55
+ if (targetLanguages.length === 0) {
56
+ return {
57
+ success: true,
58
+ skipped: true,
59
+ translationTasks: [],
60
+ sourceLanguage,
61
+ message: `All target languages are the same as source language (${sourceLanguage}), skipping translation`,
62
+ };
63
+ }
64
+
65
+ // 4. Load document structure
66
+ let validPaths;
67
+ try {
68
+ validPaths = await loadDocumentPaths();
69
+ } catch (error) {
70
+ if (error.message === ERROR_CODES.MISSING_STRUCTURE_FILE) {
71
+ return {
72
+ success: false,
73
+ error: ERROR_CODES.MISSING_STRUCTURE_FILE,
74
+ message: `Document structure file does not exist: ${PATHS.DOCUMENT_STRUCTURE}`,
75
+ suggestion: "Please generate document structure file first",
76
+ };
77
+ }
78
+ if (error.message === ERROR_CODES.INVALID_STRUCTURE_FILE) {
79
+ return {
80
+ success: false,
81
+ error: ERROR_CODES.INVALID_STRUCTURE_FILE,
82
+ message: "Invalid document structure file format",
83
+ suggestion: `Please ensure ${PATHS.DOCUMENT_STRUCTURE} contains a valid documents array`,
84
+ };
85
+ }
86
+ throw error;
87
+ }
88
+
89
+ // 5. Collect or validate document paths
90
+ let docPaths;
91
+ if (!docs || docs.length === 0) {
92
+ // Translate all documents
93
+ docPaths = Array.from(validPaths);
94
+ } else {
95
+ // Validate specified document paths
96
+ const { validPaths: validDocPaths, invalidPaths } = filterValidPaths(docs, validPaths);
97
+
98
+ if (invalidPaths.length > 0) {
99
+ return {
100
+ success: false,
101
+ error: ERROR_CODES.INVALID_DOC_PATHS,
102
+ message: `The following document paths do not exist in document structure: ${invalidPaths.join(", ")}`,
103
+ suggestion: `Please check if document paths are correct, or add these paths to ${PATHS.DOCUMENT_STRUCTURE}`,
104
+ invalidPaths,
105
+ };
106
+ }
107
+
108
+ docPaths = validDocPaths;
109
+ }
110
+
111
+ // 6. Update translateLanguages in config.yaml (only handle additions)
112
+ try {
113
+ const config = await loadConfigFromFile();
114
+ const existingLanguages = config?.translateLanguages || [];
115
+
116
+ // Find new languages (in targetLanguages but not in existingLanguages)
117
+ const newLanguages = targetLanguages.filter((lang) => !existingLanguages.includes(lang));
118
+
119
+ // If there are new languages, update config
120
+ if (newLanguages.length > 0) {
121
+ const updatedLanguages = [...existingLanguages, ...newLanguages];
122
+ await saveValueToConfig(
123
+ "translateLanguages",
124
+ updatedLanguages,
125
+ "A list of languages to translate the documentation to",
126
+ );
127
+ }
128
+ } catch (error) {
129
+ // If update fails, log warning but don't affect main flow
130
+ console.warn(`Failed to update translateLanguages in config.yaml: ${error.message}`);
131
+ }
132
+
133
+ // 7. Generate translation tasks
134
+ // Convert targetLanguages to object array so iterate_on can use
135
+ const translationTasks = docPaths.map((path) => ({
136
+ path,
137
+ sourceLanguage,
138
+ force,
139
+ targetLanguages: targetLanguages.map((lang) => ({ language: lang })),
140
+ }));
141
+
142
+ return {
143
+ success: true,
144
+ translationTasks,
145
+ sourceLanguage,
146
+ targetLanguages,
147
+ totalDocs: docPaths.length,
148
+ message: `Preparing to translate ${docPaths.length} documents to ${targetLanguages.length} languages (${targetLanguages.join(", ")})`,
149
+ };
150
+ } catch (error) {
151
+ return {
152
+ success: false,
153
+ error: ERROR_CODES.UNEXPECTED_ERROR,
154
+ message: `Error preparing translation tasks: ${error.message}`,
155
+ suggestion: "Check file system permissions and file formats",
156
+ };
157
+ }
158
+ }
159
+
160
+ // Add description
161
+ prepareTranslation.description =
162
+ "Check translation parameters, filter target languages, collect document paths, prepare for batch translation. " +
163
+ "Automatically read source language from config.yaml, filter target languages same as source language, " +
164
+ "validate document paths exist in planning/document-structure.yaml.";
165
+
166
+ // Define input schema
167
+ prepareTranslation.input_schema = {
168
+ type: "object",
169
+ properties: {
170
+ docs: {
171
+ type: "array",
172
+ items: { type: "string" },
173
+ description:
174
+ "Document paths to translate (optional, translates all documents if not provided)",
175
+ },
176
+ langs: {
177
+ type: "array",
178
+ items: { type: "string" },
179
+ description: "Target language list (required, at least one)",
180
+ },
181
+ force: {
182
+ type: "boolean",
183
+ description:
184
+ "Whether to force re-translation (optional, default false. When true, re-translate even if source document unchanged)",
185
+ },
186
+ },
187
+ required: ["langs"],
188
+ };
189
+
190
+ // Define output schema
191
+ prepareTranslation.output_schema = {
192
+ type: "object",
193
+ required: ["success"],
194
+ properties: {
195
+ success: {
196
+ type: "boolean",
197
+ description: "Whether operation succeeded",
198
+ },
199
+ translationTasks: {
200
+ type: "array",
201
+ description: "Translation task list (present on success)",
202
+ items: {
203
+ type: "object",
204
+ properties: {
205
+ path: { type: "string" },
206
+ sourceLanguage: { type: "string" },
207
+ targetLanguages: {
208
+ type: "array",
209
+ items: { type: "object", properties: { language: { type: "string" } } },
210
+ },
211
+ },
212
+ },
213
+ },
214
+ sourceLanguage: {
215
+ type: "string",
216
+ description: "Source language code",
217
+ },
218
+ targetLanguages: {
219
+ type: "array",
220
+ items: { type: "string" },
221
+ description: "Filtered target language list",
222
+ },
223
+ totalDocs: {
224
+ type: "number",
225
+ description: "Total document count",
226
+ },
227
+ message: {
228
+ type: "string",
229
+ description: "Operation result description",
230
+ },
231
+ skipped: {
232
+ type: "boolean",
233
+ description: "Whether translation was skipped",
234
+ },
235
+ error: {
236
+ type: "string",
237
+ description: "Error code (present on failure)",
238
+ },
239
+ suggestion: {
240
+ type: "string",
241
+ description: "Suggested action (present on failure)",
242
+ },
243
+ invalidPaths: {
244
+ type: "array",
245
+ items: { type: "string" },
246
+ description: "Invalid document paths list (present on failure)",
247
+ },
248
+ },
249
+ };
@@ -0,0 +1,171 @@
1
+ import { readFile, writeFile, access } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
4
+ import path from "node:path";
5
+ import {
6
+ PATHS,
7
+ ERROR_CODES,
8
+ FILE_TYPES,
9
+ DOC_META_DEFAULTS,
10
+ } from "../../../utils/agent-constants.mjs";
11
+
12
+ /**
13
+ * Save translation result and update .meta.yaml
14
+ * @param {Object} input - Input parameters
15
+ * @param {string} input.path - Document path
16
+ * @param {string} input.targetFile - Target file path
17
+ * @param {string} input.targetLanguage - Target language code
18
+ * @param {string} input.sourceHash - Source document hash
19
+ * @param {string} input.translation - Translation content
20
+ * @returns {Promise<Object>} - Operation result
21
+ */
22
+ export default async function saveTranslation(input) {
23
+ const { path: docPath, targetFile, targetLanguage, sourceHash, translation } = input;
24
+ try {
25
+ // 1. Save translation file
26
+ await writeFile(targetFile, translation, "utf8");
27
+
28
+ // 2. Update .meta.yaml
29
+ const docFolder = path.join(PATHS.DOCS_DIR, docPath);
30
+ const metaPath = path.join(docFolder, FILE_TYPES.META);
31
+
32
+ let meta = {};
33
+ let metaExists = false;
34
+
35
+ // Try to read existing .meta.yaml
36
+ try {
37
+ await access(metaPath, constants.F_OK | constants.R_OK);
38
+ const metaContent = await readFile(metaPath, "utf8");
39
+ meta = yamlParse(metaContent);
40
+ metaExists = true;
41
+ } catch (_error) {
42
+ // .meta.yaml does not exist, use defaults
43
+ meta = {
44
+ kind: DOC_META_DEFAULTS.KIND,
45
+ source: targetLanguage,
46
+ default: targetLanguage,
47
+ };
48
+ }
49
+
50
+ // 3. Initialize or update languages array
51
+ if (!meta.languages || !Array.isArray(meta.languages)) {
52
+ // Initialize languages array, including source language
53
+ meta.languages = meta.source ? [meta.source] : [];
54
+ }
55
+
56
+ // 4. Add target language (avoid duplicates)
57
+ if (!meta.languages.includes(targetLanguage)) {
58
+ meta.languages.push(targetLanguage);
59
+ }
60
+
61
+ // 5. Initialize or update translations object
62
+ if (!meta.translations || typeof meta.translations !== "object") {
63
+ meta.translations = {};
64
+ }
65
+
66
+ // 6. Record translation info (sourceHash and translation time)
67
+ meta.translations[targetLanguage] = {
68
+ sourceHash,
69
+ translatedAt: new Date().toISOString(),
70
+ };
71
+
72
+ // 7. Save updated .meta.yaml
73
+ const updatedMetaContent = yamlStringify(meta);
74
+ await writeFile(metaPath, updatedMetaContent, "utf8");
75
+
76
+ return {
77
+ success: true,
78
+ targetFile,
79
+ targetLanguage,
80
+ metaUpdated: true,
81
+ languages: meta.languages,
82
+ message: metaExists
83
+ ? `Translation saved and metadata updated: ${targetFile}`
84
+ : `Translation saved and metadata created: ${targetFile}`,
85
+ path: docPath,
86
+ };
87
+ } catch (error) {
88
+ return {
89
+ path: docPath,
90
+ success: false,
91
+ error: ERROR_CODES.SAVE_ERROR,
92
+ message: `Error saving translation: ${error.message}`,
93
+ suggestion: "Check file system permissions",
94
+ };
95
+ }
96
+ }
97
+
98
+ // Add description
99
+ saveTranslation.description =
100
+ "Save translation result to target file and update document's .meta.yaml file. " +
101
+ "Automatically add target language to languages array, " +
102
+ "record source document hash and translation time to translations object for determining if re-translation is needed later.";
103
+
104
+ // Define input schema
105
+ saveTranslation.input_schema = {
106
+ type: "object",
107
+ required: ["path", "targetFile", "targetLanguage", "sourceHash", "translation"],
108
+ properties: {
109
+ path: {
110
+ type: "string",
111
+ description: "Document path",
112
+ },
113
+ targetFile: {
114
+ type: "string",
115
+ description: "Target file path",
116
+ },
117
+ targetLanguage: {
118
+ type: "string",
119
+ description: "Target language code",
120
+ },
121
+ sourceHash: {
122
+ type: "string",
123
+ description: "Source document SHA256 hash",
124
+ },
125
+ translation: {
126
+ type: "string",
127
+ description: "Translation content",
128
+ },
129
+ },
130
+ };
131
+
132
+ // Define output schema
133
+ saveTranslation.output_schema = {
134
+ type: "object",
135
+ required: ["success"],
136
+ properties: {
137
+ success: {
138
+ type: "boolean",
139
+ description: "Whether operation succeeded",
140
+ },
141
+ targetFile: {
142
+ type: "string",
143
+ description: "Target file path (present on success)",
144
+ },
145
+ targetLanguage: {
146
+ type: "string",
147
+ description: "Target language code (present on success)",
148
+ },
149
+ metaUpdated: {
150
+ type: "boolean",
151
+ description: "Whether metadata was updated (present on success)",
152
+ },
153
+ languages: {
154
+ type: "array",
155
+ items: { type: "string" },
156
+ description: "Updated language list (present on success)",
157
+ },
158
+ message: {
159
+ type: "string",
160
+ description: "Operation result description",
161
+ },
162
+ error: {
163
+ type: "string",
164
+ description: "Error code (present on failure)",
165
+ },
166
+ suggestion: {
167
+ type: "string",
168
+ description: "Suggested action (present on failure)",
169
+ },
170
+ },
171
+ };
@@ -0,0 +1,209 @@
1
+ import { readFile, access } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import path from "node:path";
4
+ import { parse as yamlParse } from "yaml";
5
+ import { PATHS, ERROR_CODES, FILE_TYPES } from "../../../utils/agent-constants.mjs";
6
+ import { calculateContentHash } from "../../../utils/image-utils.mjs";
7
+ import saveTranslation from "./save-translation.mjs";
8
+
9
+ /**
10
+ * Translate a single document to a single target language
11
+ * @param {Object} input - Input parameters
12
+ * @param {string} input.path - Document path
13
+ * @param {string} input.sourceLanguage - Source language code
14
+ * @param {string} input.language - Current iteration target language code (from iterate_on)
15
+ * @param {boolean} input.force - Whether to force re-translation
16
+ * @param {string} input.glossary - Glossary content
17
+ * @param {Object} options - Options parameters
18
+ * @param {Object} options.context - Context object containing invoke method
19
+ * @returns {Promise<Object>} - Translation result
20
+ */
21
+ export default async function translateDocumentToLanguage(input, options) {
22
+ try {
23
+ const { path: docPath, sourceLanguage, language, force = false, glossary = "" } = input;
24
+
25
+ // When using iterate_on, object properties are spread, directly receiving language field
26
+ const targetLanguage = language;
27
+
28
+ // 1. Build file paths
29
+ const docFolder = path.join(PATHS.DOCS_DIR, docPath);
30
+ const sourceFile = path.join(docFolder, `${sourceLanguage}.md`);
31
+ const targetFile = path.join(docFolder, `${targetLanguage}.md`);
32
+
33
+ // 2. Read source document
34
+ let content;
35
+ try {
36
+ await access(sourceFile, constants.F_OK | constants.R_OK);
37
+ content = await readFile(sourceFile, "utf8");
38
+ } catch (_error) {
39
+ throw new Error(
40
+ `Source document does not exist: ${sourceFile}, document path: ${docPath}, please ensure source language document has been created`,
41
+ );
42
+ }
43
+
44
+ // 3. Calculate source document hash
45
+ const sourceHash = calculateContentHash(content);
46
+
47
+ // 4. Check if translation is needed (unless forced)
48
+ if (!force) {
49
+ const metaPath = path.join(docFolder, FILE_TYPES.META);
50
+ try {
51
+ await access(metaPath, constants.F_OK | constants.R_OK);
52
+ const metaContent = await readFile(metaPath, "utf8");
53
+ const meta = yamlParse(metaContent);
54
+
55
+ // Check if translation record exists for this language
56
+ if (meta.translations?.[targetLanguage]) {
57
+ const translationInfo = meta.translations[targetLanguage];
58
+
59
+ // If hash is the same, skip translation
60
+ if (translationInfo.sourceHash === sourceHash) {
61
+ return {
62
+ success: true,
63
+ skipped: true,
64
+ reason: "hash_unchanged",
65
+ targetLanguage,
66
+ message: `Source document unchanged, skipping translation: ${docPath} (${sourceLanguage} -> ${targetLanguage})`,
67
+ path: docPath,
68
+ };
69
+ }
70
+ }
71
+ } catch (_error) {
72
+ // .meta.yaml does not exist or failed to read, continue translation
73
+ }
74
+ }
75
+
76
+ // 5. Try to read old translation (as reference)
77
+ let previousTranslation = "";
78
+ try {
79
+ await access(targetFile, constants.F_OK | constants.R_OK);
80
+ previousTranslation = await readFile(targetFile, "utf8");
81
+ } catch (_error) {
82
+ // Old translation does not exist, this is normal
83
+ }
84
+
85
+ // 6. Call translation agent
86
+ const translateDocumentAgent = options.context?.agents?.["translateDocument"];
87
+ const translateResult = await options.context.invoke(translateDocumentAgent, {
88
+ language: targetLanguage,
89
+ content,
90
+ glossary,
91
+ previousTranslation,
92
+ });
93
+
94
+ if (!translateResult || !translateResult.translation) {
95
+ throw new Error(
96
+ `Translation failed: ${docPath} (${sourceLanguage} -> ${targetLanguage}), please try again`,
97
+ );
98
+ }
99
+
100
+ // 7. Save translation result
101
+ const saveResult = await saveTranslation({
102
+ path: docPath,
103
+ targetFile,
104
+ targetLanguage,
105
+ sourceHash,
106
+ translation: translateResult.translation,
107
+ });
108
+
109
+ return {
110
+ ...saveResult,
111
+ path: docPath,
112
+ };
113
+ } catch (error) {
114
+ return {
115
+ success: false,
116
+ error: ERROR_CODES.UNEXPECTED_ERROR,
117
+ message: `Error during translation: ${error.message}`,
118
+ suggestion: "Check file system permissions and translation configuration",
119
+ };
120
+ }
121
+ }
122
+
123
+ // Add description
124
+ translateDocumentToLanguage.description =
125
+ "Translate a single document to a single target language. " +
126
+ "Calculate source document hash, check if re-translation is needed (by comparing sourceHash saved in .meta.yaml). " +
127
+ "If source document is unchanged and not in force mode, skip translation. " +
128
+ "Otherwise call translation agent to execute translation and save result and sourceHash.";
129
+
130
+ // Define input schema
131
+ translateDocumentToLanguage.input_schema = {
132
+ type: "object",
133
+ required: ["path", "sourceLanguage", "language"],
134
+ properties: {
135
+ path: {
136
+ type: "string",
137
+ description: "Document path",
138
+ },
139
+ sourceLanguage: {
140
+ type: "string",
141
+ description: "Source language code",
142
+ },
143
+ language: {
144
+ type: "string",
145
+ description: "Target language code (from iterate_on, object properties spread)",
146
+ },
147
+ force: {
148
+ type: "boolean",
149
+ description: "Whether to force re-translation (optional, default false)",
150
+ },
151
+ glossary: {
152
+ type: "string",
153
+ description: "Glossary content (optional)",
154
+ },
155
+ },
156
+ };
157
+
158
+ // Define output schema
159
+ translateDocumentToLanguage.output_schema = {
160
+ type: "object",
161
+ required: ["success"],
162
+ properties: {
163
+ success: {
164
+ type: "boolean",
165
+ description: "Whether operation succeeded",
166
+ },
167
+ skipped: {
168
+ type: "boolean",
169
+ description: "Whether translation was skipped (when source document hash unchanged)",
170
+ },
171
+ reason: {
172
+ type: "string",
173
+ description: "Skip reason (present when skipped=true)",
174
+ },
175
+ targetFile: {
176
+ type: "string",
177
+ description: "Target file path (present when succeeded and not skipped)",
178
+ },
179
+ targetLanguage: {
180
+ type: "string",
181
+ description: "Target language code",
182
+ },
183
+ metaUpdated: {
184
+ type: "boolean",
185
+ description: "Whether metadata was updated (present when succeeded and not skipped)",
186
+ },
187
+ languages: {
188
+ type: "array",
189
+ items: { type: "string" },
190
+ description: "Updated language list (present when succeeded and not skipped)",
191
+ },
192
+ message: {
193
+ type: "string",
194
+ description: "Operation result description",
195
+ },
196
+ path: {
197
+ type: "string",
198
+ description: "Document path",
199
+ },
200
+ error: {
201
+ type: "string",
202
+ description: "Error code (present on failure)",
203
+ },
204
+ suggestion: {
205
+ type: "string",
206
+ description: "Suggested action (present on failure)",
207
+ },
208
+ },
209
+ };
@@ -0,0 +1,23 @@
1
+ name: translateDocument
2
+ description: Translate document to target language using translation prompts
3
+ instructions:
4
+ url: ../prompts/translate-document.md
5
+ input_schema:
6
+ type: object
7
+ properties:
8
+ language:
9
+ type: string
10
+ description: Target language code (e.g., "en", "ja", "fr", etc.)
11
+ content:
12
+ type: string
13
+ description: Document content to translate (Markdown format)
14
+ glossary:
15
+ type: string
16
+ description: Glossary content (optional, for maintaining consistent translation of proper nouns)
17
+ previousTranslation:
18
+ type: string
19
+ description: Existing translation version (optional, as reference context to improve translation quality)
20
+ required:
21
+ - language
22
+ - content
23
+ output_key: translation
@@ -0,0 +1,10 @@
1
+ type: team
2
+ name: translateToLanguages
3
+ description: Translate a single document to multiple languages, and translate images in the document
4
+ skills:
5
+ - url: ./translate-document-to-language.mjs # Check hash, execute translation, save result
6
+ - url: ../translate-images/translate-doc-images.yaml # Detect and translate images in the document
7
+ iterate_on: targetLanguages
8
+ concurrency: 1
9
+ mode: parallel
10
+ include_input_in_output: true