@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
@@ -1,610 +0,0 @@
1
- import { copyFile, readFile, stat } from "node:fs/promises";
2
- import path from "node:path";
3
- import fs from "fs-extra";
4
- import { createHash } from "node:crypto";
5
- import {
6
- DIAGRAM_PLACEHOLDER,
7
- d2CodeBlockRegex,
8
- diagramImageBlockRegex,
9
- ensureTmpDir,
10
- } from "../../utils/d2-utils.mjs";
11
- import { DOC_SMITH_DIR, TMP_DIR, TMP_ASSETS_DIR } from "../../utils/constants/index.mjs";
12
- import { getContentHash, getFileName } from "../../utils/utils.mjs";
13
- import { getExtnameFromContentType } from "../../utils/file-utils.mjs";
14
- import { debug } from "../../utils/debug.mjs";
15
- import { compressImage } from "../../utils/image-compress.mjs";
16
- import { calculateImageTimestamp } from "../../utils/diagram-version-utils.mjs";
17
-
18
- const SIZE_THRESHOLD = 1 * 1024 * 1024; // 1MB
19
-
20
- /**
21
- * Calculate hash for an image file
22
- * For files < 1MB: use file content
23
- * For files >= 1MB: use path + size + mtime to avoid memory issues
24
- * @param {string} absolutePath - The absolute path to the image file
25
- * @returns {Promise<string>} - The hash of the file
26
- */
27
- async function calculateImageHash(absolutePath) {
28
- const stats = await stat(absolutePath);
29
-
30
- if (stats.size < SIZE_THRESHOLD) {
31
- // Small file: use full content
32
- const content = await readFile(absolutePath);
33
- return createHash("sha256").update(content).digest("hex");
34
- }
35
-
36
- // Large file: use path + size + mtime
37
- const hashInput = `${absolutePath}:${stats.size}:${stats.mtimeMs}`;
38
- return createHash("sha256").update(hashInput).digest("hex");
39
- }
40
-
41
- /**
42
- * Replace D2 code blocks with generated image in document content
43
- * This mimics the @image insertion pattern
44
- * Saves images to assets/diagram (relative to docsDir) and replaces DIAGRAM_PLACEHOLDER with image reference
45
- *
46
- * File naming: {documentFileNameWithoutExt}-{index:02d}.{ext} (e.g., "guides-getting-started-01.jpg")
47
- * - Uses getFileName() to get the actual document filename, ensuring exact match
48
- * - Example: document "guides-getting-started.md" → diagram "guides-getting-started-01.jpg"
49
- * - Uses 2-digit zero-padded sequential numbering (01, 02, 03...) for easy sorting
50
- * - Same document + same position = same filename (overwrites on update)
51
- * - File name matches document filename (without extension) for easy tracking and identification
52
- *
53
- * Note: Images are saved immediately during replacement to ensure they exist before document save.
54
- * This is necessary because the image path is embedded in the document content.
55
- */
56
- export default async function replaceD2WithImage({
57
- imageResult,
58
- images,
59
- content,
60
- documentContent,
61
- diagramType,
62
- aspectRatio,
63
- diagramIndex,
64
- originalContent,
65
- feedback,
66
- path: docPath,
67
- docsDir,
68
- locale: inputLocale,
69
- }) {
70
- // Extract locale from imageResult if not provided directly
71
- // imageResult contains all input parameters when include_input_in_output: true
72
- const locale = inputLocale || imageResult?.locale || "en";
73
-
74
- // Extract path and docsDir from imageResult if not provided directly
75
- const finalDocPath = docPath || imageResult?.path;
76
- const finalDocsDir = docsDir || imageResult?.docsDir;
77
-
78
- // Determine which content to use for finding diagrams and final replacement
79
- // Priority:
80
- // 1. documentContent (may contain DIAGRAM_PLACEHOLDER from replaceD2WithPlaceholder)
81
- // 2. originalContent (for finding existing diagrams when updating)
82
- // 3. content (fallback)
83
- const contentForFindingDiagrams = originalContent || documentContent || content || "";
84
- // For final content, prefer documentContent first (may have placeholder), then originalContent
85
- let finalContent = documentContent || originalContent || content || "";
86
-
87
- // Extract diagram index from feedback if not explicitly provided
88
- let targetDiagramIndex = diagramIndex;
89
- if (targetDiagramIndex === undefined && feedback) {
90
- const extractedIndex = extractDiagramIndexFromFeedback(feedback);
91
- if (extractedIndex !== null) {
92
- targetDiagramIndex = extractedIndex;
93
- debug(`Extracted diagram index ${targetDiagramIndex} from feedback: "${feedback}"`);
94
- }
95
- }
96
-
97
- // Extract image from the image generation result
98
- // In team agent, image agent output is merged into the context
99
- // So we need to check both imageResult and direct images field
100
- let image = null;
101
-
102
- // First check if images array is directly available (from image agent output)
103
- // Image agent outputs: { images: [{ filename, mimeType, type: "local", path }], ... }
104
- if (images && Array.isArray(images) && images.length > 0) {
105
- image = images[0];
106
- }
107
- // Then check imageResult (might be the whole output object)
108
- else if (imageResult) {
109
- // Check for images array (from image generation agents)
110
- if (imageResult.images && Array.isArray(imageResult.images) && imageResult.images.length > 0) {
111
- image = imageResult.images[0];
112
- }
113
- // Fallback to old format
114
- else if (imageResult.imageUrl || imageResult.image || imageResult.url || imageResult.path) {
115
- image = {
116
- path: imageResult.imageUrl || imageResult.image || imageResult.url || imageResult.path,
117
- filename: path.basename(
118
- imageResult.imageUrl || imageResult.image || imageResult.url || imageResult.path,
119
- ),
120
- mimeType: imageResult.mimeType || "image/jpeg",
121
- type: "local",
122
- };
123
- }
124
- // Check nested output
125
- else if (imageResult.output) {
126
- if (
127
- imageResult.output.images &&
128
- Array.isArray(imageResult.output.images) &&
129
- imageResult.output.images.length > 0
130
- ) {
131
- image = imageResult.output.images[0];
132
- } else if (
133
- imageResult.output.imageUrl ||
134
- imageResult.output.image ||
135
- imageResult.output.url
136
- ) {
137
- image = {
138
- path: imageResult.output.imageUrl || imageResult.output.image || imageResult.output.url,
139
- filename: path.basename(
140
- imageResult.output.imageUrl || imageResult.output.image || imageResult.output.url,
141
- ),
142
- mimeType: imageResult.output.mimeType || "image/jpeg",
143
- type: "local",
144
- };
145
- }
146
- }
147
- }
148
-
149
- if (!image || !image.path || image.type !== "local") {
150
- // Debug: log what we received to help diagnose the issue
151
- debug("⚠️ No valid image found in replace-d2-with-image.mjs");
152
- debug(
153
- " - images:",
154
- images ? `${Array.isArray(images) ? images.length : "not array"} items` : "undefined",
155
- );
156
- debug(" - imageResult:", imageResult ? Object.keys(imageResult).join(", ") : "undefined");
157
- debug(
158
- " - documentContent contains DIAGRAM_PLACEHOLDER:",
159
- finalContent.includes("DIAGRAM_PLACEHOLDER"),
160
- );
161
- // If no image, return content as-is (keep D2 code blocks or placeholder)
162
- return { content: finalContent };
163
- }
164
-
165
- // Determine asset directory: assets/diagram (relative to docsDir, not in .tmp)
166
- // If docsDir is provided, use it; otherwise fallback to .tmp/assets/diagram for backward compatibility
167
- let assetDir;
168
- let relativePathPrefix;
169
-
170
- if (finalDocsDir) {
171
- // New approach: save to assets/diagram relative to docsDir (can be committed to git)
172
- assetDir = path.join(process.cwd(), finalDocsDir, "assets", "diagram");
173
- relativePathPrefix = "assets/diagram";
174
- } else {
175
- // Fallback: use .tmp/assets/diagram for backward compatibility
176
- await ensureTmpDir();
177
- assetDir = path.join(process.cwd(), DOC_SMITH_DIR, TMP_DIR, TMP_ASSETS_DIR, "diagram");
178
- relativePathPrefix = path.posix.join("..", TMP_DIR, TMP_ASSETS_DIR, "diagram");
179
- }
180
-
181
- await fs.ensureDir(assetDir);
182
-
183
- // Get file extension from source path
184
- let ext = path.extname(image.path);
185
-
186
- // If no extension found, try to determine from mimeType
187
- if (!ext && image.mimeType) {
188
- const extFromMime = getExtnameFromContentType(image.mimeType);
189
- if (extFromMime) {
190
- ext = `.${extFromMime}`;
191
- }
192
- }
193
-
194
- // Ensure we have a file extension
195
- if (!ext) {
196
- console.warn(
197
- `Could not determine file extension for diagram image from ${image.path} - using .jpg as fallback`,
198
- );
199
- ext = ".jpg";
200
- }
201
-
202
- // Find all diagram locations to determine the target index
203
- const diagramLocations = findAllDiagramLocations(contentForFindingDiagrams);
204
- let targetIndex = targetDiagramIndex !== undefined ? targetDiagramIndex : 0;
205
-
206
- if (targetIndex < 0 || targetIndex >= diagramLocations.length) {
207
- // If index is out of range, use the next available index (for new diagrams)
208
- targetIndex = diagramLocations.length;
209
- }
210
-
211
- // Generate filename based on document name and diagram index
212
- // Format: {flatDocumentName}-{index:02d}.{ext} (e.g., "guides-getting-started-01.jpg")
213
- // This ensures:
214
- // - Same document + same position = same filename (overwrite on update)
215
- // - Different documents = different filenames
216
- // - Different positions in same document = different filenames
217
- // - File name matches the actual document filename (without extension) for easy tracking
218
- // - Sequential numbering (01, 02, 03...) for easy sorting and identification
219
- let fileName;
220
-
221
- if (finalDocPath) {
222
- // Use getFileName() to get the actual document filename, then remove extension
223
- // This ensures the diagram filename exactly matches the document filename format
224
- // Example: docPath "guides/getting-started" + locale "en" -> "guides-getting-started.md"
225
- // Remove .md extension -> "guides-getting-started"
226
- const documentFileName = getFileName(finalDocPath, locale);
227
- const documentNameWithoutExt = documentFileName.replace(/\.(md|markdown)$/i, "");
228
-
229
- // Format: {documentNameWithoutExt}-{index:02d}.{ext}
230
- // Example: guides-getting-started-01.jpg, guides-getting-started-02.jpg
231
- // Using 2-digit zero-padded index for better sorting and readability
232
- const indexStr = String(targetIndex + 1).padStart(2, "0"); // Convert 0-based to 1-based, pad to 2 digits
233
- fileName = `${documentNameWithoutExt}-${indexStr}${ext}`;
234
- } else {
235
- // Fallback: use hash-based naming if path is not provided
236
- try {
237
- const imageHash = await calculateImageHash(image.path);
238
- fileName = `${imageHash}${ext}`;
239
- } catch (error) {
240
- debug(`Failed to calculate image hash, using path hash: ${error.message}`);
241
- const hash = getContentHash(image.path);
242
- fileName = `diagram-${hash}${ext}`;
243
- }
244
- }
245
-
246
- const destPath = path.join(assetDir, fileName);
247
-
248
- // Copy image from temp directory to assets directory
249
- try {
250
- // Check if source file exists
251
- if (!(await fs.pathExists(image.path))) {
252
- console.error(`Source image file does not exist: ${image.path}`);
253
- return { content: finalContent };
254
- }
255
-
256
- // Always overwrite existing file (since filename is based on document + position)
257
- // This ensures updates replace old images
258
- if (await fs.pathExists(destPath)) {
259
- debug(`Overwriting existing diagram image: ${destPath}`);
260
- }
261
- // Compress the image directly to destination path
262
- try {
263
- debug(`Compressing image directly to destination: ${image.path} -> ${destPath}`);
264
- const compressedPath = await compressImage(image.path, {
265
- quality: 85,
266
- outputPath: destPath,
267
- });
268
-
269
- // If compression failed, fallback to copying original file
270
- if (compressedPath === image.path) {
271
- debug(`Compression failed, copying original file: ${image.path}`);
272
- await copyFile(image.path, destPath);
273
- }
274
- debug(`✅ Diagram image saved to: ${destPath}`);
275
- } catch (error) {
276
- debug(`Image compression failed, copying original: ${error.message}`);
277
- // Fallback to copying original file if compression fails
278
- await copyFile(image.path, destPath);
279
- debug(`✅ Diagram image saved to: ${destPath}`);
280
- }
281
- } catch (error) {
282
- console.error(
283
- `Failed to copy diagram image from ${image.path} to ${destPath}: ${error.message}`,
284
- );
285
- debug(` Source exists: ${await fs.pathExists(image.path)}`);
286
- debug(` Dest dir exists: ${await fs.pathExists(assetDir)}`);
287
- // If copy fails, return content as-is (keep D2 code blocks or placeholder)
288
- return { content: finalContent };
289
- }
290
-
291
- // Generate alt text from document content
292
- const altText = extractAltText(documentContent);
293
-
294
- // Create relative path from markdown file to assets directory
295
- // Documents are saved in docsDir root (flattened paths), images are in docsDir/assets/diagram/
296
- // So relative path is always: assets/diagram/filename.jpg (same directory level)
297
- let relativePath;
298
- if (finalDocsDir && finalDocPath) {
299
- // All documents are in docsDir root (paths are flattened), assets are in docsDir/assets/diagram/
300
- // So relative path is simply: assets/diagram/filename.jpg
301
- relativePath = path.posix.join("assets", "diagram", fileName);
302
- } else {
303
- // Fallback: use the relativePathPrefix determined earlier
304
- relativePath = path.posix.join(relativePathPrefix, fileName);
305
- }
306
-
307
- // Create markdown image reference with markers for easy replacement
308
- // Format: <!-- DIAGRAM_IMAGE_START:type:aspectRatio:timestamp -->![alt](path)<!-- DIAGRAM_IMAGE_END -->
309
- const diagramTypeTag = diagramType || "unknown";
310
- const aspectRatioTag = aspectRatio || "unknown";
311
-
312
- // Calculate timestamp for the saved image (for version tracking)
313
- let imageTimestamp = "0";
314
- try {
315
- imageTimestamp = await calculateImageTimestamp(destPath);
316
- } catch (error) {
317
- debug(`Failed to calculate image timestamp: ${error.message}, using default 0`);
318
- }
319
-
320
- const imageMarkdown = `<!-- DIAGRAM_IMAGE_START:${diagramTypeTag}:${aspectRatioTag}:${imageTimestamp} -->\n![${altText}](${relativePath})\n<!-- DIAGRAM_IMAGE_END -->`;
321
-
322
- // Note: diagramLocations was already found above for filename generation, reuse it
323
-
324
- // Debug: log found locations
325
- if (diagramLocations.length > 0) {
326
- debug(
327
- `Found ${diagramLocations.length} diagram location(s):`,
328
- diagramLocations.map((loc) => `${loc.type} at ${loc.start}-${loc.end}`).join(", "),
329
- );
330
- }
331
-
332
- // Determine which diagram to replace
333
- // Note: targetIndex was already calculated above for filename generation, reuse it
334
-
335
- if (targetIndex < 0 || targetIndex >= diagramLocations.length) {
336
- // If index is out of range, default to first available or insert new
337
- targetIndex = diagramLocations.length > 0 ? 0 : -1;
338
- }
339
-
340
- // Replace DIAGRAM_PLACEHOLDER first (highest priority)
341
- // Check both finalContent and documentContent for placeholder
342
- const hasPlaceholder =
343
- finalContent.includes(DIAGRAM_PLACEHOLDER) || documentContent?.includes(DIAGRAM_PLACEHOLDER);
344
-
345
- if (hasPlaceholder) {
346
- debug("Replacing DIAGRAM_PLACEHOLDER");
347
- // Use documentContent if it has placeholder, otherwise use finalContent
348
- const contentWithPlaceholder = documentContent?.includes(DIAGRAM_PLACEHOLDER)
349
- ? documentContent
350
- : finalContent;
351
- finalContent = contentWithPlaceholder.replace(DIAGRAM_PLACEHOLDER, imageMarkdown);
352
- } else if (diagramLocations.length > 0 && targetIndex >= 0) {
353
- // Replace the diagram at the specified index
354
- // Use originalContent if available (for accurate position), otherwise use finalContent
355
- const contentToReplace = originalContent || finalContent;
356
- const targetLocation = diagramLocations[targetIndex];
357
- if (targetLocation) {
358
- debug(
359
- `Replacing diagram at index ${targetIndex} (type: ${targetLocation.type}, position: ${targetLocation.start}-${targetLocation.end})`,
360
- );
361
- const beforeReplace = contentToReplace.slice(0, targetLocation.start);
362
- const afterReplace = contentToReplace.slice(targetLocation.end);
363
- finalContent = beforeReplace + imageMarkdown + afterReplace;
364
- } else {
365
- debug(`⚠️ Target location at index ${targetIndex} not found`);
366
- }
367
- } else {
368
- // No diagrams found and no placeholder
369
- // This can happen when:
370
- // 1. User requests to update a diagram but no diagrams exist in the document
371
- // 2. New document generation without any diagram markers
372
- // In this case, append the diagram to the end of the document
373
- debug("⚠️ No diagram location found to replace. Appending diagram to end of document.");
374
- debug(` - Content length: ${finalContent.length}`);
375
- debug(` - Contains DIAGRAM_PLACEHOLDER: ${finalContent.includes(DIAGRAM_PLACEHOLDER)}`);
376
- debug(` - Contains DIAGRAM_IMAGE_START: ${finalContent.includes("DIAGRAM_IMAGE_START")}`);
377
- debug(` - Contains \`\`\`d2: ${finalContent.includes("```d2")}`);
378
- debug(` - Contains \`\`\`mermaid: ${finalContent.includes("```mermaid")}`);
379
-
380
- // Append diagram to the end of the document with proper spacing
381
- const trimmedContent = finalContent.trimEnd();
382
- const separator = trimmedContent && !trimmedContent.endsWith("\n") ? "\n\n" : "\n";
383
- finalContent = trimmedContent + separator + imageMarkdown;
384
- }
385
-
386
- return { content: finalContent };
387
- }
388
-
389
- /**
390
- * Find all diagram locations in content
391
- * Returns array of { type, start, end } for each diagram found
392
- * Types: 'placeholder', 'image', 'd2', 'mermaid'
393
- */
394
- function findAllDiagramLocations(content) {
395
- const locations = [];
396
-
397
- // 1. Find DIAGRAM_PLACEHOLDER
398
- let placeholderIndex = content.indexOf(DIAGRAM_PLACEHOLDER);
399
- while (placeholderIndex !== -1) {
400
- locations.push({
401
- type: "placeholder",
402
- start: placeholderIndex,
403
- end: placeholderIndex + DIAGRAM_PLACEHOLDER.length,
404
- });
405
- placeholderIndex = content.indexOf(DIAGRAM_PLACEHOLDER, placeholderIndex + 1);
406
- }
407
-
408
- // 2. Find DIAGRAM_IMAGE_START markers
409
- // Format: <!-- DIAGRAM_IMAGE_START:type:aspectRatio -->...<!-- DIAGRAM_IMAGE_END -->
410
- // Note: aspectRatio can contain colon (e.g., "16:9"), so we need to match until -->
411
- const imageMatches = Array.from(content.matchAll(diagramImageBlockRegex));
412
- for (const match of imageMatches) {
413
- locations.push({
414
- type: "image",
415
- start: match.index,
416
- end: match.index + match[0].length,
417
- });
418
- }
419
-
420
- // 3. Find D2 code blocks
421
- // Note: .* matches title or other text after ```d2 (e.g., ```d2 Vault 驗證流程)
422
- const d2Matches = Array.from(content.matchAll(d2CodeBlockRegex));
423
- for (const match of d2Matches) {
424
- locations.push({
425
- type: "d2",
426
- start: match.index,
427
- end: match.index + match[0].length,
428
- });
429
- }
430
-
431
- // 4. Find Mermaid code blocks
432
- // Note: .* matches title or other text after ```mermaid (e.g., ```mermaid Flow Chart)
433
- const mermaidCodeBlockRegex = /```mermaid.*\n([\s\S]*?)```/g;
434
- const mermaidMatches = Array.from(content.matchAll(mermaidCodeBlockRegex));
435
- for (const match of mermaidMatches) {
436
- locations.push({
437
- type: "mermaid",
438
- start: match.index,
439
- end: match.index + match[0].length,
440
- });
441
- }
442
-
443
- // Sort by position in document (top to bottom)
444
- locations.sort((a, b) => a.start - b.start);
445
-
446
- return locations;
447
- }
448
-
449
- /**
450
- * Extract diagram index from feedback
451
- * Returns 0-based index, or null if not specified
452
- * Examples: "first diagram" -> 0, "second diagram" -> 1, "第2张图" -> 1
453
- */
454
- export function extractDiagramIndexFromFeedback(feedback) {
455
- if (!feedback) return null;
456
-
457
- const feedbackLower = feedback.toLowerCase();
458
-
459
- // Check Chinese patterns first (more specific)
460
- // Examples: "第一张图", "第二张图", "第2张图"
461
- const chinesePattern = /第([一二三四五六七八九十]|\d+)[张个]图/i;
462
- const chineseMatch = feedbackLower.match(chinesePattern);
463
- if (chineseMatch?.[1]) {
464
- const chineseNumbers = {
465
- 一: 1,
466
- 二: 2,
467
- 三: 3,
468
- 四: 4,
469
- 五: 5,
470
- 六: 6,
471
- 七: 7,
472
- 八: 8,
473
- 九: 9,
474
- 十: 10,
475
- };
476
- const numStr = chineseMatch[1];
477
- const num = chineseNumbers[numStr] || parseInt(numStr, 10);
478
- return num > 0 ? num - 1 : 0; // Convert to 0-based index
479
- }
480
-
481
- // Check number patterns (diagram #2, image 3, etc.)
482
- const numberPattern = /(?:diagram|image|picture|chart|graph)\s*#?(\d+)/i;
483
- const numberMatch = feedbackLower.match(numberPattern);
484
- if (numberMatch?.[1]) {
485
- const num = parseInt(numberMatch[1], 10);
486
- return num > 0 ? num - 1 : 0; // Convert to 0-based index
487
- }
488
-
489
- // Check ordinal patterns (first, second, third, etc.)
490
- const ordinalMap = {
491
- first: 0,
492
- "1st": 0,
493
- 1: 0,
494
- second: 1,
495
- "2nd": 1,
496
- 2: 1,
497
- third: 2,
498
- "3rd": 2,
499
- 3: 2,
500
- fourth: 3,
501
- "4th": 3,
502
- 4: 3,
503
- fifth: 4,
504
- "5th": 4,
505
- 5: 4,
506
- };
507
-
508
- for (const [ordinal, index] of Object.entries(ordinalMap)) {
509
- const ordinalPattern = new RegExp(
510
- `(?:${ordinal})\\s+(?:diagram|image|picture|chart|graph)`,
511
- "i",
512
- );
513
- if (ordinalPattern.test(feedbackLower)) {
514
- return index;
515
- }
516
- }
517
-
518
- return null;
519
- }
520
-
521
- /**
522
- * Extract alt text from document content
523
- */
524
- function extractAltText(documentContent) {
525
- if (!documentContent) return "Diagram";
526
-
527
- const lines = documentContent.split("\n").filter((line) => line.trim());
528
- if (lines.length > 0) {
529
- let altText = lines[0].trim();
530
- // Remove markdown headers
531
- altText = altText.replace(/^#+\s*/, "");
532
- if (altText.length > 100) {
533
- altText = `${altText.substring(0, 97)}...`;
534
- }
535
- return altText || "Diagram";
536
- }
537
- return "Diagram";
538
- }
539
-
540
- replaceD2WithImage.input_schema = {
541
- type: "object",
542
- properties: {
543
- images: {
544
- type: "array",
545
- description: "Images array from image generation agent",
546
- },
547
- imageResult: {
548
- type: "object",
549
- description: "The result from image generation agent (fallback)",
550
- },
551
- content: {
552
- type: "string",
553
- description: "The document content (may contain DIAGRAM_PLACEHOLDER)",
554
- },
555
- documentContent: {
556
- type: "string",
557
- description: "Original document content containing DIAGRAM_PLACEHOLDER",
558
- },
559
- diagramType: {
560
- type: "string",
561
- description: "The diagram type (for marking the image)",
562
- enum: ["architecture", "flowchart", "guide", "intro", "sequence", "network"],
563
- },
564
- aspectRatio: {
565
- type: "string",
566
- description: "The aspect ratio of the diagram (for marking the image)",
567
- enum: ["1:1", "5:4", "4:3", "3:2", "16:9", "21:9"],
568
- },
569
- diagramIndex: {
570
- type: "number",
571
- description:
572
- "Index of the diagram to replace (0-based). If not provided, will try to extract from feedback (e.g., 'first diagram' -> 0, 'second diagram' -> 1), otherwise defaults to 0.",
573
- },
574
- originalContent: {
575
- type: "string",
576
- description:
577
- "Original document content before any modifications. Used to find existing diagrams when updating.",
578
- },
579
- path: {
580
- type: "string",
581
- description:
582
- "Document path (e.g., 'guides/getting-started.md') used for generating image filename",
583
- },
584
- docsDir: {
585
- type: "string",
586
- description: "Documentation directory where assets will be saved (relative to project root)",
587
- },
588
- locale: {
589
- type: "string",
590
- description: "Main language locale (e.g., 'en', 'zh') for syncing to translations",
591
- default: "en",
592
- },
593
- feedback: {
594
- type: "string",
595
- description: "User feedback (for extracting diagram index)",
596
- },
597
- },
598
- required: ["documentContent"],
599
- };
600
-
601
- replaceD2WithImage.output_schema = {
602
- type: "object",
603
- properties: {
604
- content: {
605
- type: "string",
606
- description: "Document content with D2 code blocks replaced by image",
607
- },
608
- },
609
- required: ["content"],
610
- };
@@ -1,54 +0,0 @@
1
- type: team
2
- name: updateDocumentStructure
3
- description: Update documentation structure based on user feedback and intentions using structure modification tools
4
- skills:
5
- - url: ../utils/analyze-structure-feedback-intent.yaml
6
- - type: ai
7
- instructions:
8
- - role: system
9
- url: ../../prompts/structure/update/system-prompt.md
10
- - role: user
11
- url: ../../prompts/structure/update/user-prompt.md
12
- input_schema:
13
- type: object
14
- properties:
15
- documentStructure: ../schema/document-structure.yaml
16
- rules:
17
- type: string
18
- description: User configuration rules
19
- locale:
20
- type: string
21
- description: User language, e.g. zh, en
22
- dataSourceChunk:
23
- type: string
24
- description: Context for documentation structure
25
- glossary:
26
- type: string
27
- description: Glossary of terms
28
- feedback:
29
- type: string
30
- description: User feedback for structure modifications
31
- userPreferences:
32
- type: string
33
- description: Your saved preferences for structure and documentation style
34
- needDataSources:
35
- type: boolean
36
- description: Whether data sources are needed for content modifications
37
- required:
38
- - documentStructure
39
- - feedback
40
- output_key: message
41
- afs:
42
- modules:
43
- - module: system-fs
44
- options:
45
- name: sources
46
- localPath: .
47
- description: |
48
- Codebase of the project to be documented used as context for document generation,
49
- should search and read as needed while generating document content
50
- skills:
51
- - ./document-structure-tools/add-document.mjs
52
- - ./document-structure-tools/delete-document.mjs
53
- - ./document-structure-tools/update-document.mjs
54
- - ./document-structure-tools/move-document.mjs