@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,225 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { parse as yamlParse } from "yaml";
4
+ import { calculateFileHash, findImageFile } from "../../../utils/image-utils.mjs";
5
+
6
+ /**
7
+ * Check if images need translation
8
+ * @param {Object} input - Input parameters
9
+ * @param {Array} input.slots - Image slot list (from scan-doc-images output)
10
+ * @param {string} input.targetLanguage - Target language
11
+ * @param {string} input.sourceLanguage - Source language (main language)
12
+ * @returns {Promise<Object>} - Check result
13
+ */
14
+ export default async function checkImageTranslation(input) {
15
+ const { slots, targetLanguage, sourceLanguage } = input;
16
+
17
+ if (!slots || slots.length === 0) {
18
+ return {
19
+ success: true,
20
+ translationTasks: [],
21
+ message: "No images to check",
22
+ };
23
+ }
24
+
25
+ const translationTasks = [];
26
+ let sharedCount = 0;
27
+ let alreadyTranslatedCount = 0;
28
+ let needUpdateCount = 0;
29
+
30
+ for (const slot of slots) {
31
+ const { key, desc, assetDir, metaPath, exists } = slot;
32
+
33
+ // If image asset does not exist, skip
34
+ if (!exists) {
35
+ continue;
36
+ }
37
+
38
+ // Read .meta.yaml
39
+ let meta;
40
+ try {
41
+ const metaContent = await readFile(metaPath, "utf8");
42
+ meta = yamlParse(metaContent);
43
+ } catch (_error) {
44
+ // Failed to read .meta.yaml, skip
45
+ continue;
46
+ }
47
+
48
+ // 1. Check if it's a text-free shared image
49
+ if (meta.generation?.shared === true) {
50
+ sharedCount++;
51
+ continue; // Skip text-free images
52
+ }
53
+
54
+ // 2. Check if target language already exists
55
+ const languages = meta.languages || [];
56
+ const alreadyTranslated = languages.includes(targetLanguage);
57
+
58
+ // 3. Find source language image
59
+ const imagesDir = join(assetDir, "images");
60
+ const sourceImagePath = await findImageFile(imagesDir, sourceLanguage);
61
+ if (!sourceImagePath) {
62
+ // Source image does not exist, skip
63
+ continue;
64
+ }
65
+
66
+ // 4. Calculate source image hash
67
+ const sourceHash = await calculateFileHash(sourceImagePath);
68
+
69
+ // 5. Determine if translation is needed
70
+ let needsTranslation = false;
71
+ let reason = "";
72
+
73
+ if (!alreadyTranslated) {
74
+ // Target language version does not exist, needs translation
75
+ needsTranslation = true;
76
+ reason = "missing";
77
+ } else {
78
+ // Already translated, check if source image is updated
79
+ const translations = meta.translations || {};
80
+ const translationInfo = translations[targetLanguage];
81
+
82
+ if (!translationInfo || !translationInfo.sourceHash) {
83
+ // No source hash recorded, needs re-translation
84
+ needsTranslation = true;
85
+ reason = "no_hash";
86
+ } else if (translationInfo.sourceHash !== sourceHash) {
87
+ // Source image has been updated, needs re-translation
88
+ needsTranslation = true;
89
+ reason = "source_updated";
90
+ needUpdateCount++;
91
+ } else {
92
+ // Already translated and source image unchanged, skip
93
+ alreadyTranslatedCount++;
94
+ }
95
+ }
96
+
97
+ if (needsTranslation) {
98
+ // Get image aspect ratio (from meta or default)
99
+ const aspectRatio = meta.generation?.aspectRatio || "4:3";
100
+ const size = meta.generation?.size || "2K";
101
+
102
+ translationTasks.push({
103
+ key,
104
+ desc,
105
+ assetDir,
106
+ sourceImagePath,
107
+ sourceHash,
108
+ aspectRatio,
109
+ size,
110
+ reason,
111
+ });
112
+ }
113
+ }
114
+
115
+ return {
116
+ success: true,
117
+ translationTasks,
118
+ sourceLanguage,
119
+ targetLanguage,
120
+ stats: {
121
+ total: slots.length,
122
+ shared: sharedCount,
123
+ alreadyTranslated: alreadyTranslatedCount,
124
+ needUpdate: needUpdateCount,
125
+ needTranslation: translationTasks.length,
126
+ },
127
+ message:
128
+ `Checked ${slots.length} images: ` +
129
+ `${sharedCount} text-free shared images, ` +
130
+ `${alreadyTranslatedCount} already translated, ` +
131
+ `${translationTasks.length} need translation` +
132
+ (needUpdateCount > 0 ? ` (${needUpdateCount} need update)` : ""),
133
+ };
134
+ }
135
+
136
+ // Add description
137
+ checkImageTranslation.description =
138
+ "Check if images need translation to target language. " +
139
+ "Skip text-free shared images, check source image hash to determine if re-translation is needed. " +
140
+ "Return list of image translation tasks.";
141
+
142
+ // Define input schema
143
+ checkImageTranslation.input_schema = {
144
+ type: "object",
145
+ required: ["slots", "targetLanguage", "sourceLanguage"],
146
+ properties: {
147
+ slots: {
148
+ type: "array",
149
+ description: "Image slot list (from scan-doc-images output)",
150
+ items: {
151
+ type: "object",
152
+ properties: {
153
+ key: { type: "string" },
154
+ desc: { type: "string" },
155
+ assetDir: { type: "string", nullable: true },
156
+ metaPath: { type: "string", nullable: true },
157
+ exists: { type: "boolean" },
158
+ },
159
+ },
160
+ },
161
+ targetLanguage: {
162
+ type: "string",
163
+ description: "Target language code",
164
+ },
165
+ sourceLanguage: {
166
+ type: "string",
167
+ description: "Source language code (main language)",
168
+ },
169
+ },
170
+ };
171
+
172
+ // Define output schema
173
+ checkImageTranslation.output_schema = {
174
+ type: "object",
175
+ required: ["success"],
176
+ properties: {
177
+ success: {
178
+ type: "boolean",
179
+ description: "Whether operation succeeded",
180
+ },
181
+ translationTasks: {
182
+ type: "array",
183
+ description: "List of image translation tasks",
184
+ items: {
185
+ type: "object",
186
+ properties: {
187
+ key: { type: "string", description: "Image key" },
188
+ desc: { type: "string", description: "Image description" },
189
+ assetDir: { type: "string", description: "Image asset directory" },
190
+ sourceImagePath: { type: "string", description: "Source image file path" },
191
+ sourceHash: { type: "string", description: "Source image hash" },
192
+ aspectRatio: { type: "string", description: "Aspect ratio" },
193
+ size: { type: "string", description: "Image size" },
194
+ reason: {
195
+ type: "string",
196
+ description: "Translation reason (missing/no_hash/source_updated)",
197
+ },
198
+ },
199
+ },
200
+ },
201
+ sourceLanguage: {
202
+ type: "string",
203
+ description: "Source language code",
204
+ },
205
+ targetLanguage: {
206
+ type: "string",
207
+ description: "Target language code",
208
+ },
209
+ stats: {
210
+ type: "object",
211
+ description: "Statistics",
212
+ properties: {
213
+ total: { type: "number", description: "Total image count" },
214
+ shared: { type: "number", description: "Text-free shared image count" },
215
+ alreadyTranslated: { type: "number", description: "Already translated count" },
216
+ needUpdate: { type: "number", description: "Need update count" },
217
+ needTranslation: { type: "number", description: "Need translation count" },
218
+ },
219
+ },
220
+ message: {
221
+ type: "string",
222
+ description: "Operation result description",
223
+ },
224
+ },
225
+ };
@@ -0,0 +1,148 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join, basename } from "node:path";
3
+ import { parse as yamlParse } from "yaml";
4
+ import { findImageFile, getImageMimeType } from "../../../../utils/image-utils.mjs";
5
+
6
+ /**
7
+ * Detect if image contains text and update .meta.yaml shared field
8
+ * @param {Object} input - Input parameters
9
+ * @param {Array} input.slots - Image slot list (from scan-doc-images output)
10
+ * @param {string} input.sourceLanguage - Source language (main language)
11
+ * @returns {Promise<Object>} - Processing result
12
+ */
13
+ export default async function detectAndUpdateShared(input) {
14
+ const { slots, sourceLanguage } = input;
15
+
16
+ if (!slots || slots.length === 0 || !slots.some((s) => s.exists)) {
17
+ return {
18
+ success: true,
19
+ detectionTasks: [],
20
+ message: "No images to detect",
21
+ };
22
+ }
23
+
24
+ const detectionTasks = [];
25
+
26
+ for (const slot of slots) {
27
+ const { key, assetDir, metaPath, exists } = slot;
28
+
29
+ // If image asset does not exist, skip
30
+ if (!exists) {
31
+ continue;
32
+ }
33
+
34
+ // Read .meta.yaml
35
+ let meta;
36
+ try {
37
+ const metaContent = await readFile(metaPath, "utf8");
38
+ meta = yamlParse(metaContent);
39
+ } catch (_error) {
40
+ // Failed to read .meta.yaml, skip
41
+ continue;
42
+ }
43
+
44
+ // Check if shared field has already been detected
45
+ if (meta.generation?.shared === true) {
46
+ // Already detected, skip shared images
47
+ continue;
48
+ }
49
+
50
+ // Find main language image
51
+ const imagesDir = join(assetDir, "images");
52
+ const sourceImagePath = await findImageFile(imagesDir, sourceLanguage);
53
+
54
+ if (!sourceImagePath) {
55
+ // Main language image does not exist, skip
56
+ continue;
57
+ }
58
+
59
+ // Add to detection task list
60
+ detectionTasks.push({
61
+ key,
62
+ assetDir,
63
+ metaPath,
64
+ sourceImagePath,
65
+ // Prepare imageFile parameter (mediaFile format)
66
+ imageFile: [
67
+ {
68
+ type: "local",
69
+ path: sourceImagePath,
70
+ filename: basename(sourceImagePath),
71
+ mimeType: getImageMimeType(sourceImagePath),
72
+ },
73
+ ],
74
+ });
75
+ }
76
+
77
+ return {
78
+ success: true,
79
+ detectionTasks,
80
+ sourceLanguage,
81
+ message: `${detectionTasks.length} images need text detection`,
82
+ };
83
+ }
84
+
85
+ // Add description
86
+ detectAndUpdateShared.description =
87
+ "Detect if images contain text, prepare batch detection tasks. " +
88
+ "Only detect images without generation.shared field set.";
89
+
90
+ // Define input schema
91
+ detectAndUpdateShared.input_schema = {
92
+ type: "object",
93
+ required: ["slots", "sourceLanguage"],
94
+ properties: {
95
+ slots: {
96
+ type: "array",
97
+ description: "Image slot list (from scan-doc-images output)",
98
+ items: {
99
+ type: "object",
100
+ properties: {
101
+ key: { type: "string" },
102
+ desc: { type: "string" },
103
+ assetDir: { type: "string", nullable: true },
104
+ metaPath: { type: "string", nullable: true },
105
+ exists: { type: "boolean" },
106
+ },
107
+ },
108
+ },
109
+ sourceLanguage: {
110
+ type: "string",
111
+ description: "Source language code (main language)",
112
+ },
113
+ },
114
+ };
115
+
116
+ // Define output schema
117
+ detectAndUpdateShared.output_schema = {
118
+ type: "object",
119
+ required: ["success"],
120
+ properties: {
121
+ success: {
122
+ type: "boolean",
123
+ description: "Whether operation succeeded",
124
+ },
125
+ detectionTasks: {
126
+ type: "array",
127
+ description: "List of image detection tasks",
128
+ items: {
129
+ type: "object",
130
+ properties: {
131
+ key: { type: "string", description: "Image key" },
132
+ assetDir: { type: "string", description: "Image asset directory" },
133
+ metaPath: { type: "string", description: ".meta.yaml file path" },
134
+ sourceImagePath: { type: "string", description: "Main language image path" },
135
+ imageFile: { type: "array", description: "imageFile mediaFile object array" },
136
+ },
137
+ },
138
+ },
139
+ sourceLanguage: {
140
+ type: "string",
141
+ description: "Source language code",
142
+ },
143
+ message: {
144
+ type: "string",
145
+ description: "Operation result description",
146
+ },
147
+ },
148
+ };
@@ -0,0 +1,44 @@
1
+ name: detectImageText
2
+ description: Detect if image contains text content
3
+ model: gemini-2.5-flash
4
+ modalities: ["text", "image"]
5
+ instructions:
6
+ - role: system
7
+ url: ./prompts/detect-image-text-system.md
8
+ - role: user
9
+ url: ./prompts/detect-image-text-user.md
10
+ input_file_key: imageFile
11
+ include_input_in_output: true
12
+ input_schema:
13
+ type: object
14
+ properties:
15
+ key:
16
+ type: string
17
+ description: Image key
18
+ imageFile:
19
+ type: array
20
+ description: Array of mediaFile objects for image files
21
+ items:
22
+ type: object
23
+ properties:
24
+ type:
25
+ type: string
26
+ description: File type, should be "local"
27
+ path:
28
+ type: string
29
+ description: Absolute path to the image file
30
+ filename:
31
+ type: string
32
+ description: Image filename
33
+ mimeType:
34
+ type: string
35
+ description: MIME type (e.g., "image/png", "image/jpeg")
36
+ required:
37
+ - key
38
+ - imageFile
39
+ output_schema:
40
+ type: object
41
+ properties:
42
+ hasText:
43
+ type: boolean
44
+ description: Whether the image contains text
@@ -0,0 +1,21 @@
1
+ type: team
2
+ name: detectImagesText
3
+ description: Detect if images contain text and update shared field
4
+ skills:
5
+ - url: ./detect-and-update-shared.mjs # Prepare detection tasks
6
+ - type: team
7
+ name: processTextDetections # Batch detect image text
8
+ skills:
9
+ - type: team
10
+ name: detectSingleImageText
11
+ description: Detect if a single image contains text and save result
12
+ skills:
13
+ - url: ./detect-image-text.yaml # Detect image text
14
+ - url: ./save-text-detection.mjs # Save detection result
15
+ mode: sequential
16
+ include_input_in_output: true
17
+
18
+ iterate_on: detectionTasks
19
+ concurrency: 1
20
+ mode: sequential
21
+ include_input_in_output: true
@@ -0,0 +1,43 @@
1
+ You are an AI assistant specialized in analyzing diagram images to detect the presence of text content.
2
+
3
+ # YOUR TASK
4
+
5
+ Analyze the provided diagram image and determine whether it contains any text or textual labels.
6
+
7
+ # WHAT COUNTS AS TEXT
8
+
9
+ Text includes:
10
+ - ✅ Words, labels, or text annotations in any language
11
+ - ✅ Abbreviations, acronyms, or code snippets
12
+ - ✅ Numbers used as labels or identifiers (e.g., "Step 1", "v2.0")
13
+ - ✅ Technical terms or variable names
14
+ - ✅ Arrows or connectors with text labels
15
+
16
+ # WHAT DOES NOT COUNT AS TEXT
17
+
18
+ The following should NOT be considered as text:
19
+ - ❌ Pure icons or symbols without text
20
+ - ❌ Standalone numbers used decoratively (not as labels)
21
+ - ❌ Colors, shapes, or visual patterns
22
+ - ❌ Logos that are purely graphical
23
+
24
+ # OUTPUT FORMAT
25
+
26
+ You must respond with ONLY one of these two values:
27
+ - `true` - if the image contains ANY text content
28
+ - `false` - if the image contains NO text (pure visual diagram)
29
+
30
+ # IMPORTANT RULES
31
+
32
+ 1. Be strict: even a single word or label means the image has text → return `true`
33
+ 2. Ignore watermarks or metadata that are not part of the diagram content
34
+ 3. Focus on the actual diagram content, not borders or backgrounds
35
+ 4. Your response must be ONLY `true` or `false`, nothing else
36
+
37
+ # EXAMPLES
38
+
39
+ **Image with node labels like "User", "API", "Database"** → `true`
40
+ **Flowchart with text like "Start", "Process", "End"** → `true`
41
+ **Architecture diagram with component names** → `true`
42
+ **Pure icon-based diagram with no text labels** → `false`
43
+ **Diagram with only arrows and shapes, no text** → `false`
@@ -0,0 +1,14 @@
1
+ # Text Detection Task
2
+
3
+ Analyze the provided diagram image and determine if it contains any text content.
4
+
5
+ **Image Key:** {{ key }}
6
+
7
+ [The diagram image is provided as input to the model]
8
+
9
+ **Your task:**
10
+ 1. Carefully examine the entire image
11
+ 2. Look for any words, labels, text annotations, or textual content
12
+ 3. Respond with ONLY `true` (has text) or `false` (no text)
13
+
14
+ **Response:** (true or false only)
@@ -0,0 +1,105 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
3
+ import { ERROR_CODES } from "../../../../utils/agent-constants.mjs";
4
+
5
+ /**
6
+ * Save text detection result to .meta.yaml
7
+ * @param {Object} input - Input parameters
8
+ * @param {string} input.key - Image key
9
+ * @param {string} input.metaPath - .meta.yaml file path
10
+ * @param {boolean} input.hasText - Whether contains text (from detect-image-text.yaml output)
11
+ * @returns {Promise<Object>} - Operation result
12
+ */
13
+ export default async function saveTextDetection(input) {
14
+ const { key, metaPath, hasText } = input;
15
+
16
+ try {
17
+ // Read .meta.yaml
18
+ const metaContent = await readFile(metaPath, "utf8");
19
+ const meta = yamlParse(metaContent);
20
+
21
+ // Update generation.shared field
22
+ if (!meta.generation) {
23
+ meta.generation = {};
24
+ }
25
+
26
+ // shared = !hasText (no text means shared)
27
+ meta.generation.shared = !hasText;
28
+
29
+ // Save updated .meta.yaml
30
+ const updatedMetaContent = yamlStringify(meta);
31
+ await writeFile(metaPath, updatedMetaContent, "utf8");
32
+
33
+ return {
34
+ success: true,
35
+ key,
36
+ hasText,
37
+ shared: !hasText,
38
+ message: `Updated shared field: ${key} (hasText=${hasText}, shared=${!hasText})`,
39
+ };
40
+ } catch (error) {
41
+ return {
42
+ success: false,
43
+ error: ERROR_CODES.SAVE_ERROR,
44
+ message: `Error saving text detection result: ${error.message}`,
45
+ key,
46
+ };
47
+ }
48
+ }
49
+
50
+ // Add description
51
+ saveTextDetection.description =
52
+ "Save image text detection result to .meta.yaml file. " +
53
+ "Update generation.shared field based on detection result: text-free images shared=true, images with text shared=false.";
54
+
55
+ // Define input schema
56
+ saveTextDetection.input_schema = {
57
+ type: "object",
58
+ required: ["key", "metaPath", "hasText"],
59
+ properties: {
60
+ key: {
61
+ type: "string",
62
+ description: "Image key",
63
+ },
64
+ metaPath: {
65
+ type: "string",
66
+ description: ".meta.yaml file path",
67
+ },
68
+ hasText: {
69
+ type: "boolean",
70
+ description: "Whether image contains text (from detect-image-text.yaml output)",
71
+ },
72
+ },
73
+ };
74
+
75
+ // Define output schema
76
+ saveTextDetection.output_schema = {
77
+ type: "object",
78
+ required: ["success"],
79
+ properties: {
80
+ success: {
81
+ type: "boolean",
82
+ description: "Whether operation succeeded",
83
+ },
84
+ key: {
85
+ type: "string",
86
+ description: "Image key",
87
+ },
88
+ hasText: {
89
+ type: "boolean",
90
+ description: "Whether image contains text (present on success)",
91
+ },
92
+ shared: {
93
+ type: "boolean",
94
+ description: "Whether it is a shared image (present on success)",
95
+ },
96
+ message: {
97
+ type: "string",
98
+ description: "Operation result description",
99
+ },
100
+ error: {
101
+ type: "string",
102
+ description: "Error code (present on failure)",
103
+ },
104
+ },
105
+ };