@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,247 @@
1
+ import { readFile, access, constants } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { loadDocumentPaths, filterValidPaths } from "../../utils/document-paths.mjs";
4
+ import { PATHS, ERROR_CODES } from "../../utils/agent-constants.mjs";
5
+ import { parseSlots } from "../../utils/image-slots.mjs";
6
+ import { calculateContentHash } from "../../utils/image-utils.mjs";
7
+ import { loadLocale } from "../../utils/config.mjs";
8
+
9
+ /**
10
+ * Scan slots in a single document
11
+ * @param {string} docPath - Document path
12
+ * @param {string} locale - Main language
13
+ * @returns {Promise<Object|null>} - { path, hash, content, slots } or null (if file does not exist)
14
+ */
15
+ async function scanDocument(docPath, locale) {
16
+ // Build document file path: docs/{path}/{locale}.md
17
+ const normalizedPath = docPath.startsWith("/") ? docPath.slice(1) : docPath;
18
+ const filePath = join(PATHS.DOCS_DIR, normalizedPath, `${locale}.md`);
19
+
20
+ // Check if file exists
21
+ try {
22
+ await access(filePath, constants.F_OK | constants.R_OK);
23
+ } catch (_error) {
24
+ // File does not exist, skip (may be a document not yet generated)
25
+ return null;
26
+ }
27
+
28
+ // Read document content
29
+ const content = await readFile(filePath, "utf8");
30
+
31
+ // Calculate hash
32
+ const hash = calculateContentHash(content);
33
+
34
+ // Parse slots
35
+ const slots = parseSlots(content, docPath);
36
+
37
+ return {
38
+ path: docPath,
39
+ hash,
40
+ content,
41
+ slots,
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Group slots by key
47
+ * @param {Array} scanResults - Scan results array
48
+ * @returns {Map} - key -> { key, id, desc, documents }
49
+ */
50
+ function groupSlotsByKey(scanResults) {
51
+ const slotMap = new Map();
52
+
53
+ for (const result of scanResults) {
54
+ if (!result || result.slots.length === 0) {
55
+ continue;
56
+ }
57
+
58
+ for (const slot of result.slots) {
59
+ const { key, id, desc } = slot;
60
+
61
+ if (!slotMap.has(key)) {
62
+ slotMap.set(key, {
63
+ key,
64
+ id,
65
+ desc,
66
+ documents: [],
67
+ });
68
+ }
69
+
70
+ // If the same key is used multiple times, use the last id and desc
71
+ const existing = slotMap.get(key);
72
+ existing.id = id;
73
+ existing.desc = desc;
74
+
75
+ // Add document reference
76
+ existing.documents.push({
77
+ path: result.path,
78
+ hash: result.hash,
79
+ content: result.content,
80
+ });
81
+ }
82
+ }
83
+
84
+ return slotMap;
85
+ }
86
+
87
+ /**
88
+ * Scan AFS image slots in documents
89
+ * @param {Object} input - Input parameters
90
+ * @param {string[]} input.docs - Document path list to scan (optional)
91
+ * @returns {Promise<Object>} - Scan result
92
+ */
93
+ export default async function scanImageSlots(input) {
94
+ try {
95
+ const { docs } = input;
96
+
97
+ // 1. Read main language
98
+ let locale;
99
+ try {
100
+ locale = await loadLocale();
101
+ } catch (error) {
102
+ if (error.message === ERROR_CODES.MISSING_CONFIG_FILE) {
103
+ throw new Error(
104
+ `Config file does not exist: ${PATHS.CONFIG}, please ensure executing this command in doc-smith project root directory`,
105
+ );
106
+ }
107
+ if (error.message === ERROR_CODES.MISSING_LOCALE) {
108
+ throw new Error(
109
+ `Missing locale field in ${PATHS.CONFIG}, please ask the user for the main language for image generation, add the locale field to ${PATHS.CONFIG}, then try executing the command again`,
110
+ );
111
+ }
112
+ throw error;
113
+ }
114
+
115
+ // 2. Load document structure
116
+ let validPaths;
117
+ try {
118
+ validPaths = await loadDocumentPaths();
119
+ } catch (error) {
120
+ if (error.message === ERROR_CODES.MISSING_STRUCTURE_FILE) {
121
+ throw new Error(
122
+ `Document structure file does not exist: ${PATHS.DOCUMENT_STRUCTURE}, please generate documents using doc-smith skill first`,
123
+ );
124
+ }
125
+ if (error.message === ERROR_CODES.INVALID_STRUCTURE_FILE) {
126
+ throw new Error(
127
+ `Invalid document structure file format, please ensure ${PATHS.DOCUMENT_STRUCTURE} contains a valid documents array, otherwise cannot scan image slots in documents, please refer to references/document-structure-schema.md for file structure`,
128
+ );
129
+ }
130
+ throw error;
131
+ }
132
+
133
+ // 3. Collect or validate document paths
134
+ let docPaths;
135
+ if (!docs || docs.length === 0) {
136
+ // Scan all documents
137
+ docPaths = Array.from(validPaths);
138
+ } else {
139
+ // Validate specified document paths
140
+ const { validPaths: validDocPaths, invalidPaths } = filterValidPaths(docs, validPaths);
141
+
142
+ if (invalidPaths.length > 0) {
143
+ throw new Error(
144
+ `The following document paths do not exist in document structure: ${invalidPaths.join(", ")}, please check if document paths are correct`,
145
+ );
146
+ }
147
+
148
+ docPaths = validDocPaths;
149
+ }
150
+
151
+ // 4. Scan all documents
152
+ const scanResults = await Promise.all(docPaths.map((path) => scanDocument(path, locale)));
153
+
154
+ // 5. Group by key
155
+ const slotMap = groupSlotsByKey(scanResults);
156
+ const slots = Array.from(slotMap.values());
157
+
158
+ // 6. Return result
159
+ return {
160
+ success: true,
161
+ locale,
162
+ slots,
163
+ totalDocs: docPaths.length,
164
+ totalSlots: slots.length,
165
+ message: `Scanned ${docPaths.length} documents, found ${slots.length} image slots`,
166
+ };
167
+ } catch (error) {
168
+ throw new Error(`Error scanning image slots: ${error.message}`);
169
+ }
170
+ }
171
+
172
+ // Add description
173
+ scanImageSlots.description =
174
+ "Scan AFS image slots in main language documents, parse id, key, desc, " +
175
+ "calculate document content hash, group by key and return all slot information.";
176
+
177
+ // Define input schema
178
+ scanImageSlots.input_schema = {
179
+ type: "object",
180
+ properties: {
181
+ docs: {
182
+ type: "array",
183
+ items: { type: "string" },
184
+ description: "Document path list to scan (optional, scans all documents if not provided)",
185
+ },
186
+ },
187
+ };
188
+
189
+ // Define output schema
190
+ scanImageSlots.output_schema = {
191
+ type: "object",
192
+ required: ["success"],
193
+ properties: {
194
+ success: {
195
+ type: "boolean",
196
+ description: "Whether operation succeeded",
197
+ },
198
+ locale: {
199
+ type: "string",
200
+ description: "Main language code",
201
+ },
202
+ slots: {
203
+ type: "array",
204
+ description: "Slot list grouped by key",
205
+ items: {
206
+ type: "object",
207
+ properties: {
208
+ key: { type: "string", description: "Image directory name" },
209
+ id: { type: "string", description: "Slot id of the last usage of this key" },
210
+ desc: { type: "string", description: "Slot description" },
211
+ documents: {
212
+ type: "array",
213
+ description: "Document list referencing this key",
214
+ items: {
215
+ type: "object",
216
+ properties: {
217
+ path: { type: "string" },
218
+ hash: { type: "string" },
219
+ content: { type: "string" },
220
+ },
221
+ },
222
+ },
223
+ },
224
+ },
225
+ },
226
+ totalDocs: {
227
+ type: "number",
228
+ description: "Total documents scanned",
229
+ },
230
+ totalSlots: {
231
+ type: "number",
232
+ description: "Total slots found",
233
+ },
234
+ message: {
235
+ type: "string",
236
+ description: "Operation result description",
237
+ },
238
+ error: {
239
+ type: "string",
240
+ description: "Error code (present on failure)",
241
+ },
242
+ suggestion: {
243
+ type: "string",
244
+ description: "Suggested action (present on failure)",
245
+ },
246
+ },
247
+ };
@@ -2,61 +2,38 @@ type: team
2
2
  name: localize
3
3
  alias:
4
4
  - translate
5
- description: Translate documents into other languages
5
+ description: |
6
+ Batch translate documents to multiple languages, supports translating multiple documents and multiple languages at once.
6
7
  skills:
7
- - url: ../init/index.mjs
8
- default_input:
9
- skipIfExists: true
10
- checkOnly: true
11
- - ../utils/load-sources.mjs
12
- - url: ../init/check.mjs
13
- - type: transform
14
- task_render_mode: hide
15
- jsonata: |
16
- $merge([
17
- $,
18
- {
19
- 'documentStructure': originalDocumentStructure
20
- }
21
- ])
22
- - url: ../update/check-diagram-flag.mjs
23
- - url: ../utils/choose-docs.mjs
24
- default_input:
25
- isTranslate: true
26
- - ../localize/choose-language.mjs
8
+ - url: ./translate-documents/prepare-translation.mjs # Check and prepare translation tasks
9
+ - url: ./translate-documents/load-glossary.mjs # Load glossary (once)
27
10
  - type: team
28
- name: batchTranslateDocument
11
+ name: processAllDocuments # Process all documents
29
12
  skills:
30
- - ../localize/translate-multilingual.yaml
31
- iterate_on: selectedDocs
32
- concurrency: 5
33
- - url: ../utils/check-feedback-refiner.mjs
34
- default_input:
35
- stage: translation_refine
36
- - url: ./record-translation-history.mjs
37
- - url: ../utils/action-success.mjs
38
- default_input:
39
- action: '✅ Translation completed'
13
+ - url: ./translate-documents/translate-to-languages.yaml
14
+ iterate_on: translationTasks
15
+ concurrency: 3
16
+ - url: ./translate-documents/generate-summary.mjs # Generate final summary report
40
17
  input_schema:
41
18
  type: object
42
19
  properties:
43
- glossary:
44
- type: string
45
- description: Glossary file for consistent terminology (use @filename.md)
46
20
  docs:
47
21
  type: array
48
22
  items:
49
23
  type: string
50
- description: Documents to translate
24
+ description: |
25
+ List of document paths to translate (optional, e.g., ["/overview", "/api/auth"]), must exist in planning/document-structure.yaml.
26
+ If not provided or empty array, translates all documents; if paths are provided, only translates specified documents and validates path validity.
51
27
  langs:
52
28
  type: array
53
29
  items:
54
30
  type: string
55
- description: 'Target languages (available: en, zh, zh-TW, ja, fr, de, es, it, ru, ko, pt, ar)'
56
- feedback:
57
- type: string
58
- description: Tell us how to improve the translation style
59
- diagram:
31
+ description: |
32
+ Target language list (required, e.g., ["en", "ja", "fr"]), using standard language codes.
33
+ force:
60
34
  type: boolean
61
- description: Translate only diagram images without translating document content (use --diagram flag)
35
+ description: |
36
+ Whether to force re-translation (optional, default false). When set to true, re-translates all documents even if source documents haven't changed.
37
+ required:
38
+ - langs
62
39
  mode: sequential
@@ -21,36 +21,9 @@ Translation Requirements:
21
21
  - Use Terminology Reference: Ensure accuracy and consistency of professional terminology.
22
22
  - Preserve Terms: Retain specific terms in their original form, avoiding translation.
23
23
  - Maintain tone consistency: use a neutral tone for developer/DevOps docs, a polite tone for end-user/client docs, and do not mix address styles (e.g., **"you"** vs **"您"**).
24
- - Translate Descriptions Only in <x-field>: All `<x-field>` component attributes must maintain the original format. Only translate the description content within `data-desc` attribute or `<x-field-desc>` elements.
25
24
 
26
- {% include "./code-block.md" %}
27
-
28
- {% include "./admonition.md" %}
29
25
  </translation_rules>
30
26
 
31
- {% if feedback %}
32
- <translation_user_feedback>
33
- {{ feedback }}
34
- </translation_user_feedback>
35
- {% endif %}
36
-
37
- {% if detailFeedback %}
38
- <translation_review_feedback>
39
- {{ detailFeedback }}
40
- </translation_review_feedback>
41
- {% endif %}
42
-
43
- {% if userPreferences %}
44
- <user_preferences>
45
- {{userPreferences}}
46
-
47
- User preference guidelines:
48
-
49
- - User preferences are derived from feedback provided in previous user interactions. When generating translations, consider user preferences to avoid repeating issues mentioned in user feedback
50
- - User preferences carry less weight than current user feedback
51
- </user_preferences>
52
- {% endif %}
53
-
54
27
  {% include "./glossary.md" %}
55
28
 
56
29
  Terms to preserve (do not translate):
@@ -81,26 +54,6 @@ Table Translation - Demonstrates how to translate table content while preserving
81
54
  </after_translate>
82
55
  </example_item>
83
56
 
84
- <example_item>
85
- XField Component Translation - Shows how to translate only description content within x-field components while preserving all attributes.
86
-
87
- <before_translate>
88
-
89
- <x-field data-name="teamDid" data-type="string" data-required="true" data-desc="The DID of the team or Blocklet managing the webhook."></x-field>
90
-
91
- <x-field data-name="apiKey" data-type="string" data-required="true">
92
- <x-field-desc markdown>Your **API key** for authentication. Generate one from the `Settings > API Keys` section.</x-field-desc>
93
- </before_translate>
94
-
95
- <after_translate>
96
- <x-field data-name="teamDid" data-type="string" data-required="true" data-desc="管理 Webhook 的团队或 Blocklet 的 DID。"></x-field>
97
-
98
- <x-field data-name="apiKey" data-type="string" data-required="true">
99
- <x-field-desc markdown>您的 **API 密钥**,用于身份验证。请从 `设置 > API 密钥` 部分生成一个。</x-field-desc>
100
- </x-field>
101
- </after_translate>
102
- </example_item>
103
-
104
57
  <example_item>
105
58
  Code Block Translation - Illustrates translating only comments in code blocks while keeping all code content unchanged.
106
59
 
@@ -201,98 +154,6 @@ Cache for server cleared: [list of cleared cache keys]
201
154
  </after_translate>
202
155
  </example_item>
203
156
 
204
- <example_item>
205
- D2 Diagram Translation - Shows how to translate only labels in D2 diagrams while preserving all syntax and structure.
206
-
207
- <before_translate>
208
-
209
- ```d2 High-Level Architecture
210
- direction: down
211
-
212
- User: {
213
- shape: c4-person
214
- }
215
-
216
- Your-Application: {
217
- label: "Your Application"
218
- shape: rectangle
219
-
220
- PaymentProvider: {
221
- label: "PaymentProvider"
222
- shape: rectangle
223
-
224
- Payment-Components: {
225
- label: "Payment Components"
226
- shape: rectangle
227
- grid-columns: 2
228
-
229
- CheckoutForm: { label: "CheckoutForm" }
230
- CheckoutTable: { label: "CheckoutTable" }
231
- CheckoutDonate: { label: "CheckoutDonate" }
232
- CustomerInvoiceList: { label: "CustomerInvoiceList" }
233
- }
234
- }
235
- }
236
-
237
- Payment-Kit-Backend: {
238
- label: "Payment Kit Backend"
239
- shape: cylinder
240
- }
241
-
242
- User -> Your-Application.PaymentProvider.Payment-Components: "Interacts with UI"
243
- Your-Application.PaymentProvider -> Payment-Kit-Backend: "Handles API Communication"
244
- Payment-Kit-Backend -> Your-Application.PaymentProvider: "Returns Data"
245
- Your-Application.PaymentProvider.Payment-Components -> User: "Renders UI Updates"
246
-
247
- ```
248
-
249
- </before_translate>
250
-
251
- <after_translate>
252
-
253
- ```d2 高层架构
254
- direction: down
255
-
256
- User: {
257
- shape: c4-person
258
- }
259
-
260
- Your-Application: {
261
- label: "您的应用程序"
262
- shape: rectangle
263
-
264
- PaymentProvider: {
265
- label: "PaymentProvider"
266
- shape: rectangle
267
-
268
- Payment-Components: {
269
- label: "支付组件"
270
- shape: rectangle
271
- grid-columns: 2
272
-
273
- CheckoutForm: { label: "CheckoutForm" }
274
- CheckoutTable: { label: "CheckoutTable" }
275
- CheckoutDonate: { label: "CheckoutDonate" }
276
- CustomerInvoiceList: { label: "CustomerInvoiceList" }
277
- }
278
- }
279
- }
280
-
281
- Payment-Kit-Backend: {
282
- label: "Payment Kit 后端"
283
- shape: cylinder
284
- }
285
-
286
- User -> Your-Application.PaymentProvider.Payment-Components: "与 UI 交互"
287
- Your-Application.PaymentProvider -> Payment-Kit-Backend: "处理 API 通信"
288
- Payment-Kit-Backend -> Your-Application.PaymentProvider: "返回数据"
289
- Your-Application.PaymentProvider.Payment-Components -> User: "渲染 UI 更新"
290
-
291
- ```
292
-
293
- </after_translate>
294
- </example_item>
295
-
296
157
  </example>
297
158
 
298
159
  Original text as follows:
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Generate final summary report for translation tasks
3
+ * @param {Object} input - Input parameters
4
+ * @param {Array} input.translationTasks - Translation task list
5
+ * @param {string} input.sourceLanguage - Source language code
6
+ * @param {Array} input.targetLanguages - Target language list
7
+ * @param {number} input.totalDocs - Total document count
8
+ * @param {boolean} input.skipped - Whether translation was skipped
9
+ * @returns {Object} - Object containing formatted message and statistics
10
+ */
11
+ export default function generateSummary(input) {
12
+ const { translationTasks, sourceLanguage, targetLanguages, totalDocs, skipped } = input;
13
+
14
+ // If translation was skipped
15
+ if (skipped) {
16
+ return {
17
+ message: `⏭️ Translation skipped: All target languages are the same as source language (${sourceLanguage})`,
18
+ summary: {
19
+ skipped: true,
20
+ sourceLanguage,
21
+ totalDocs: 0,
22
+ totalLanguages: 0,
23
+ totalTranslations: 0,
24
+ },
25
+ };
26
+ }
27
+
28
+ // Calculate statistics
29
+ const totalLanguages = targetLanguages.length;
30
+ const totalTranslations = totalDocs * totalLanguages;
31
+
32
+ // Generate document path list (show at most 5)
33
+ const docPaths = translationTasks.map((task) => task.path);
34
+ const displayDocs =
35
+ docPaths.length > 5
36
+ ? [...docPaths.slice(0, 5), `... and ${docPaths.length - 5} more documents`]
37
+ : docPaths;
38
+
39
+ // Generate formatted message
40
+ const message = `
41
+ ✅ Translation tasks completed
42
+
43
+ 📊 **Translation Statistics**:
44
+ - Source language: ${sourceLanguage}
45
+ - Target languages: ${targetLanguages.join(", ")} (${totalLanguages} languages)
46
+ - Document count: ${totalDocs}
47
+ - Total translations: ${totalTranslations}
48
+
49
+ 📄 **Translated Documents**:
50
+ ${displayDocs.map((doc) => ` - ${doc}`).join("\n")}
51
+
52
+ 💡 **Tips**:
53
+ - Translation files saved to docs/{path}/{language}.md
54
+ - Document .meta.yaml languages field has been automatically updated
55
+ - Check the corresponding language files to view translation results
56
+ `.trim();
57
+
58
+ return {
59
+ message,
60
+ summary: {
61
+ skipped: false,
62
+ sourceLanguage,
63
+ targetLanguages,
64
+ totalDocs,
65
+ totalLanguages,
66
+ totalTranslations,
67
+ documentPaths: docPaths,
68
+ },
69
+ };
70
+ }
71
+
72
+ // Add description
73
+ generateSummary.description =
74
+ "Generate final summary report for translation tasks. " +
75
+ "Summarize translation statistics (source language, target languages, document count, etc.) and generate readable formatted message. " +
76
+ "If translation was skipped, generate corresponding skip notice.";
77
+
78
+ // Define input schema
79
+ generateSummary.input_schema = {
80
+ type: "object",
81
+ properties: {
82
+ translationTasks: {
83
+ type: "array",
84
+ description: "Translation task list",
85
+ items: {
86
+ type: "object",
87
+ properties: {
88
+ path: { type: "string" },
89
+ sourceLanguage: { type: "string" },
90
+ targetLanguages: {
91
+ type: "array",
92
+ items: { type: "object", properties: { language: { type: "string" } } },
93
+ },
94
+ },
95
+ },
96
+ },
97
+ sourceLanguage: {
98
+ type: "string",
99
+ description: "Source language code",
100
+ },
101
+ targetLanguages: {
102
+ type: "array",
103
+ items: { type: "string" },
104
+ description: "Target language list",
105
+ },
106
+ totalDocs: {
107
+ type: "number",
108
+ description: "Total document count",
109
+ },
110
+ skipped: {
111
+ type: "boolean",
112
+ description: "Whether translation was skipped",
113
+ },
114
+ },
115
+ };
116
+
117
+ // Define output schema
118
+ generateSummary.output_schema = {
119
+ type: "object",
120
+ required: ["message", "summary"],
121
+ properties: {
122
+ message: {
123
+ type: "string",
124
+ description: "Formatted summary message containing translation statistics and tips",
125
+ },
126
+ summary: {
127
+ type: "object",
128
+ description: "Structured statistics data",
129
+ properties: {
130
+ skipped: {
131
+ type: "boolean",
132
+ description: "Whether translation was skipped",
133
+ },
134
+ sourceLanguage: {
135
+ type: "string",
136
+ description: "Source language code",
137
+ },
138
+ targetLanguages: {
139
+ type: "array",
140
+ items: { type: "string" },
141
+ description: "Target language list",
142
+ },
143
+ totalDocs: {
144
+ type: "number",
145
+ description: "Total document count",
146
+ },
147
+ totalLanguages: {
148
+ type: "number",
149
+ description: "Total target language count",
150
+ },
151
+ totalTranslations: {
152
+ type: "number",
153
+ description: "Total translation count (documents × languages)",
154
+ },
155
+ documentPaths: {
156
+ type: "array",
157
+ items: { type: "string" },
158
+ description: "List of all translated document paths",
159
+ },
160
+ },
161
+ },
162
+ },
163
+ };
@@ -0,0 +1,52 @@
1
+ import { readFile, access } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { PATHS } from "../../../utils/agent-constants.mjs";
4
+
5
+ /**
6
+ * Load glossary
7
+ * @returns {Promise<Object>} - Object containing glossary content
8
+ */
9
+ export default async function loadGlossary() {
10
+ const glossaryPath = PATHS.GLOSSARY;
11
+
12
+ try {
13
+ // Check if glossary file exists
14
+ await access(glossaryPath, constants.F_OK | constants.R_OK);
15
+
16
+ // Read glossary content
17
+ const glossary = await readFile(glossaryPath, "utf8");
18
+
19
+ return {
20
+ glossary: glossary.trim(),
21
+ message: `Glossary loaded: ${glossaryPath}`,
22
+ };
23
+ } catch (_error) {
24
+ // Glossary file does not exist, return empty string
25
+ return {
26
+ glossary: "",
27
+ message: "Glossary file not found, will not use glossary",
28
+ };
29
+ }
30
+ }
31
+
32
+ // Add description
33
+ loadGlossary.description =
34
+ "Load translation glossary file (intent/GLOSSARY.md). " +
35
+ "If file exists, read content; otherwise return empty string. " +
36
+ "Glossary content will be used in all translation tasks to ensure consistency of proper nouns.";
37
+
38
+ // Define output schema
39
+ loadGlossary.output_schema = {
40
+ type: "object",
41
+ required: ["glossary", "message"],
42
+ properties: {
43
+ glossary: {
44
+ type: "string",
45
+ description: "Glossary content (empty string if not exists)",
46
+ },
47
+ message: {
48
+ type: "string",
49
+ description: "Operation result description",
50
+ },
51
+ },
52
+ };