@aigne/doc-smith 0.9.8-alpha.2 → 0.9.8-alpha.4

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 (256) hide show
  1. package/CLAUDE.md +43 -0
  2. package/README.md +94 -250
  3. package/aigne.yaml +2 -149
  4. package/doc-smith/SKILL.md +117 -0
  5. package/doc-smith/references/changeset_schema.md +118 -0
  6. package/doc-smith/references/document_structure_schema.md +139 -0
  7. package/doc-smith/references/document_update_guide.md +193 -0
  8. package/doc-smith/references/structure_confirmation_guide.md +133 -0
  9. package/doc-smith/references/structure_planning_guide.md +146 -0
  10. package/doc-smith/references/user_intent_guide.md +172 -0
  11. package/doc-smith.yaml +114 -0
  12. package/main-system-prompt.md +56 -0
  13. package/package.json +3 -69
  14. package/scripts/README.md +90 -0
  15. package/scripts/install.sh +86 -0
  16. package/scripts/uninstall.sh +52 -0
  17. package/CHANGELOG.md +0 -994
  18. package/LICENSE +0 -93
  19. package/agentic-agents/common/base-info.md +0 -53
  20. package/agentic-agents/common/planner.md +0 -168
  21. package/agentic-agents/common/worker.md +0 -93
  22. package/agentic-agents/create/index.yaml +0 -118
  23. package/agentic-agents/create/objective.md +0 -44
  24. package/agentic-agents/create/set-custom-prompt.mjs +0 -27
  25. package/agentic-agents/detail/index.yaml +0 -95
  26. package/agentic-agents/detail/objective.md +0 -9
  27. package/agentic-agents/detail/set-custom-prompt.mjs +0 -88
  28. package/agentic-agents/predict-resources/index.yaml +0 -44
  29. package/agentic-agents/predict-resources/instructions.md +0 -61
  30. package/agentic-agents/structure/design-rules.md +0 -39
  31. package/agentic-agents/structure/index.yaml +0 -86
  32. package/agentic-agents/structure/objective.md +0 -14
  33. package/agentic-agents/structure/review-criteria.md +0 -55
  34. package/agentic-agents/structure/set-custom-prompt.mjs +0 -78
  35. package/agentic-agents/utils/init-workspace-cache.mjs +0 -171
  36. package/agentic-agents/utils/load-base-sources.mjs +0 -20
  37. package/agentic-agents/workspace-cache-sharing-design.md +0 -671
  38. package/agents/chat/chat-system.md +0 -38
  39. package/agents/chat/index.mjs +0 -59
  40. package/agents/chat/skills/generate-document.yaml +0 -15
  41. package/agents/chat/skills/list-documents.mjs +0 -15
  42. package/agents/chat/skills/update-document.yaml +0 -24
  43. package/agents/clear/choose-contents.mjs +0 -192
  44. package/agents/clear/clear-auth-tokens.mjs +0 -88
  45. package/agents/clear/clear-deployment-config.mjs +0 -49
  46. package/agents/clear/clear-document-config.mjs +0 -36
  47. package/agents/clear/clear-document-structure.mjs +0 -102
  48. package/agents/clear/clear-generated-docs.mjs +0 -142
  49. package/agents/clear/clear-media-description.mjs +0 -129
  50. package/agents/clear/index.yaml +0 -26
  51. package/agents/create/analyze-diagram-type-llm.yaml +0 -160
  52. package/agents/create/analyze-diagram-type.mjs +0 -297
  53. package/agents/create/check-document-structure.yaml +0 -30
  54. package/agents/create/check-need-generate-structure.mjs +0 -105
  55. package/agents/create/document-structure-tools/add-document.mjs +0 -85
  56. package/agents/create/document-structure-tools/delete-document.mjs +0 -116
  57. package/agents/create/document-structure-tools/move-document.mjs +0 -109
  58. package/agents/create/document-structure-tools/update-document.mjs +0 -84
  59. package/agents/create/generate-diagram-image.yaml +0 -60
  60. package/agents/create/generate-structure.yaml +0 -117
  61. package/agents/create/index.yaml +0 -49
  62. package/agents/create/refine-document-structure.yaml +0 -12
  63. package/agents/create/replace-d2-with-image.mjs +0 -625
  64. package/agents/create/update-document-structure.yaml +0 -54
  65. package/agents/create/user-add-document/add-documents-to-structure.mjs +0 -90
  66. package/agents/create/user-add-document/find-documents-to-add-links.yaml +0 -47
  67. package/agents/create/user-add-document/index.yaml +0 -46
  68. package/agents/create/user-add-document/prepare-documents-to-translate.mjs +0 -22
  69. package/agents/create/user-add-document/print-add-document-summary.mjs +0 -63
  70. package/agents/create/user-add-document/review-documents-with-new-links.mjs +0 -110
  71. package/agents/create/user-remove-document/find-documents-with-invalid-links.mjs +0 -78
  72. package/agents/create/user-remove-document/index.yaml +0 -40
  73. package/agents/create/user-remove-document/prepare-documents-to-translate.mjs +0 -22
  74. package/agents/create/user-remove-document/print-remove-document-summary.mjs +0 -53
  75. package/agents/create/user-remove-document/remove-documents-from-structure.mjs +0 -99
  76. package/agents/create/user-remove-document/review-documents-with-invalid-links.mjs +0 -115
  77. package/agents/create/user-review-document-structure.mjs +0 -140
  78. package/agents/create/utils/init-current-content.mjs +0 -34
  79. package/agents/create/utils/merge-document-structures.mjs +0 -30
  80. package/agents/evaluate/code-snippet.mjs +0 -97
  81. package/agents/evaluate/document-structure.yaml +0 -67
  82. package/agents/evaluate/document.yaml +0 -82
  83. package/agents/evaluate/generate-report.mjs +0 -85
  84. package/agents/evaluate/index.yaml +0 -46
  85. package/agents/history/index.yaml +0 -6
  86. package/agents/history/view.mjs +0 -78
  87. package/agents/init/check.mjs +0 -16
  88. package/agents/init/index.mjs +0 -275
  89. package/agents/init/validate.mjs +0 -16
  90. package/agents/localize/choose-language.mjs +0 -107
  91. package/agents/localize/index.yaml +0 -58
  92. package/agents/localize/record-translation-history.mjs +0 -23
  93. package/agents/localize/translate-document.yaml +0 -24
  94. package/agents/localize/translate-multilingual.yaml +0 -51
  95. package/agents/media/batch-generate-media-description.yaml +0 -46
  96. package/agents/media/generate-media-description.yaml +0 -50
  97. package/agents/media/load-media-description.mjs +0 -256
  98. package/agents/prefs/index.mjs +0 -203
  99. package/agents/publish/index.yaml +0 -26
  100. package/agents/publish/publish-docs.mjs +0 -356
  101. package/agents/publish/translate-meta.mjs +0 -103
  102. package/agents/schema/document-structure-item.yaml +0 -26
  103. package/agents/schema/document-structure-refine-item.yaml +0 -23
  104. package/agents/schema/document-structure.yaml +0 -29
  105. package/agents/update/batch-generate-document.yaml +0 -27
  106. package/agents/update/batch-update-document.yaml +0 -7
  107. package/agents/update/check-diagram-flag.mjs +0 -116
  108. package/agents/update/check-document.mjs +0 -162
  109. package/agents/update/check-generate-diagram.mjs +0 -106
  110. package/agents/update/check-sync-image-flag.mjs +0 -55
  111. package/agents/update/check-update-is-single.mjs +0 -53
  112. package/agents/update/document-tools/update-document-content.mjs +0 -303
  113. package/agents/update/generate-diagram.yaml +0 -63
  114. package/agents/update/generate-document.yaml +0 -70
  115. package/agents/update/handle-document-update.yaml +0 -103
  116. package/agents/update/index.yaml +0 -79
  117. package/agents/update/pre-check-generate-diagram.yaml +0 -44
  118. package/agents/update/save-and-translate-document.mjs +0 -76
  119. package/agents/update/sync-images-and-exit.mjs +0 -148
  120. package/agents/update/update-document-detail.yaml +0 -71
  121. package/agents/update/update-single/update-single-document-detail.mjs +0 -280
  122. package/agents/update/update-single-document.yaml +0 -7
  123. package/agents/update/user-review-document.mjs +0 -272
  124. package/agents/utils/action-success.mjs +0 -16
  125. package/agents/utils/analyze-document-feedback-intent.yaml +0 -32
  126. package/agents/utils/analyze-feedback-intent.mjs +0 -136
  127. package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
  128. package/agents/utils/check-detail-result.mjs +0 -38
  129. package/agents/utils/check-feedback-refiner.mjs +0 -81
  130. package/agents/utils/choose-docs.mjs +0 -293
  131. package/agents/utils/document-icon-generate.yaml +0 -52
  132. package/agents/utils/document-title-streamline.yaml +0 -48
  133. package/agents/utils/ensure-document-icons.mjs +0 -129
  134. package/agents/utils/exit.mjs +0 -6
  135. package/agents/utils/feedback-refiner.yaml +0 -50
  136. package/agents/utils/find-item-by-path.mjs +0 -114
  137. package/agents/utils/find-user-preferences-by-path.mjs +0 -37
  138. package/agents/utils/format-document-structure.mjs +0 -35
  139. package/agents/utils/generate-document-or-skip.mjs +0 -41
  140. package/agents/utils/handle-diagram-operations.mjs +0 -263
  141. package/agents/utils/load-all-document-content.mjs +0 -30
  142. package/agents/utils/load-document-all-content.mjs +0 -84
  143. package/agents/utils/load-sources.mjs +0 -405
  144. package/agents/utils/map-reasoning-effort-level.mjs +0 -15
  145. package/agents/utils/post-generate.mjs +0 -144
  146. package/agents/utils/read-current-document-content.mjs +0 -46
  147. package/agents/utils/save-doc-translation.mjs +0 -61
  148. package/agents/utils/save-doc.mjs +0 -88
  149. package/agents/utils/save-output.mjs +0 -26
  150. package/agents/utils/save-sidebar.mjs +0 -51
  151. package/agents/utils/skip-if-content-exists.mjs +0 -27
  152. package/agents/utils/streamline-document-titles-if-needed.mjs +0 -88
  153. package/agents/utils/transform-detail-data-sources.mjs +0 -45
  154. package/agents/utils/update-branding.mjs +0 -84
  155. package/assets/report-template/report.html +0 -198
  156. package/docs-mcp/analyze-content-relevance.yaml +0 -50
  157. package/docs-mcp/analyze-docs-relevance.yaml +0 -59
  158. package/docs-mcp/docs-search.yaml +0 -42
  159. package/docs-mcp/get-docs-detail.mjs +0 -41
  160. package/docs-mcp/get-docs-structure.mjs +0 -16
  161. package/docs-mcp/read-doc-content.mjs +0 -119
  162. package/prompts/common/document/content-rules-core.md +0 -20
  163. package/prompts/common/document/markdown-syntax-rules.md +0 -65
  164. package/prompts/common/document/media-file-list-usage-rules.md +0 -18
  165. package/prompts/common/document/openapi-usage-rules.md +0 -189
  166. package/prompts/common/document/role-and-personality.md +0 -16
  167. package/prompts/common/document/user-preferences.md +0 -9
  168. package/prompts/common/document-structure/conflict-resolution-guidance.md +0 -16
  169. package/prompts/common/document-structure/document-icon-generate.md +0 -116
  170. package/prompts/common/document-structure/document-structure-rules.md +0 -43
  171. package/prompts/common/document-structure/document-title-streamline.md +0 -86
  172. package/prompts/common/document-structure/glossary.md +0 -7
  173. package/prompts/common/document-structure/intj-traits.md +0 -5
  174. package/prompts/common/document-structure/openapi-usage-rules.md +0 -28
  175. package/prompts/common/document-structure/output-constraints.md +0 -18
  176. package/prompts/common/document-structure/user-locale-rules.md +0 -10
  177. package/prompts/common/document-structure/user-preferences.md +0 -9
  178. package/prompts/detail/custom/admonition-usage-rules.md +0 -94
  179. package/prompts/detail/custom/code-block-usage-rules.md +0 -163
  180. package/prompts/detail/custom/custom-components/x-card-usage-rules.md +0 -63
  181. package/prompts/detail/custom/custom-components/x-cards-usage-rules.md +0 -83
  182. package/prompts/detail/custom/custom-components/x-field-desc-usage-rules.md +0 -120
  183. package/prompts/detail/custom/custom-components/x-field-group-usage-rules.md +0 -80
  184. package/prompts/detail/custom/custom-components/x-field-usage-rules.md +0 -189
  185. package/prompts/detail/custom/custom-components-usage-rules.md +0 -18
  186. package/prompts/detail/diagram/generate-image-system.md +0 -135
  187. package/prompts/detail/diagram/generate-image-user.md +0 -32
  188. package/prompts/detail/diagram/guide.md +0 -29
  189. package/prompts/detail/diagram/official-examples.md +0 -712
  190. package/prompts/detail/diagram/pre-check.md +0 -23
  191. package/prompts/detail/diagram/role-and-personality.md +0 -2
  192. package/prompts/detail/diagram/rules.md +0 -46
  193. package/prompts/detail/diagram/system-prompt.md +0 -1139
  194. package/prompts/detail/diagram/user-prompt.md +0 -43
  195. package/prompts/detail/generate/detail-example.md +0 -457
  196. package/prompts/detail/generate/document-rules.md +0 -45
  197. package/prompts/detail/generate/system-prompt.md +0 -61
  198. package/prompts/detail/generate/user-prompt.md +0 -99
  199. package/prompts/detail/jsx/rules.md +0 -6
  200. package/prompts/detail/update/system-prompt.md +0 -121
  201. package/prompts/detail/update/user-prompt.md +0 -41
  202. package/prompts/evaluate/document-structure.md +0 -93
  203. package/prompts/evaluate/document.md +0 -149
  204. package/prompts/media/media-description/system-prompt.md +0 -43
  205. package/prompts/media/media-description/user-prompt.md +0 -17
  206. package/prompts/structure/check-document-structure.md +0 -93
  207. package/prompts/structure/document-rules.md +0 -21
  208. package/prompts/structure/find-documents-to-add-links.md +0 -52
  209. package/prompts/structure/generate/system-prompt.md +0 -13
  210. package/prompts/structure/generate/user-prompt.md +0 -137
  211. package/prompts/structure/review/structure-review-system.md +0 -81
  212. package/prompts/structure/structure-example.md +0 -89
  213. package/prompts/structure/structure-getting-started.md +0 -10
  214. package/prompts/structure/update/system-prompt.md +0 -93
  215. package/prompts/structure/update/user-prompt.md +0 -43
  216. package/prompts/translate/admonition.md +0 -20
  217. package/prompts/translate/code-block.md +0 -33
  218. package/prompts/translate/glossary.md +0 -6
  219. package/prompts/translate/translate-document.md +0 -305
  220. package/prompts/utils/analyze-document-feedback-intent.md +0 -54
  221. package/prompts/utils/analyze-structure-feedback-intent.md +0 -43
  222. package/prompts/utils/feedback-refiner.md +0 -105
  223. package/types/document-schema.mjs +0 -55
  224. package/types/document-structure-schema.mjs +0 -261
  225. package/utils/auth-utils.mjs +0 -275
  226. package/utils/blocklet.mjs +0 -104
  227. package/utils/check-document-has-diagram.mjs +0 -95
  228. package/utils/conflict-detector.mjs +0 -149
  229. package/utils/constants/index.mjs +0 -620
  230. package/utils/constants/linter.mjs +0 -102
  231. package/utils/d2-utils.mjs +0 -198
  232. package/utils/debug.mjs +0 -3
  233. package/utils/delete-diagram-images.mjs +0 -99
  234. package/utils/deploy.mjs +0 -86
  235. package/utils/docs-finder-utils.mjs +0 -623
  236. package/utils/evaluate/report-utils.mjs +0 -132
  237. package/utils/extract-api.mjs +0 -32
  238. package/utils/file-utils.mjs +0 -960
  239. package/utils/history-utils.mjs +0 -203
  240. package/utils/icon-map.mjs +0 -26
  241. package/utils/image-compress.mjs +0 -75
  242. package/utils/kroki-utils.mjs +0 -173
  243. package/utils/linter/index.mjs +0 -50
  244. package/utils/load-config.mjs +0 -107
  245. package/utils/markdown/index.mjs +0 -26
  246. package/utils/markdown-checker.mjs +0 -694
  247. package/utils/mermaid-validator.mjs +0 -140
  248. package/utils/mermaid-worker-pool.mjs +0 -250
  249. package/utils/mermaid-worker.mjs +0 -233
  250. package/utils/openapi/index.mjs +0 -28
  251. package/utils/preferences-utils.mjs +0 -175
  252. package/utils/request.mjs +0 -10
  253. package/utils/store/index.mjs +0 -45
  254. package/utils/sync-diagram-to-translations.mjs +0 -262
  255. package/utils/upload-files.mjs +0 -231
  256. package/utils/utils.mjs +0 -1354
@@ -1,129 +0,0 @@
1
- import { promises as fs } from "node:fs";
2
- import { join } from "node:path";
3
- import { loadConfigFromFile, processConfigFields } from "../../utils/utils.mjs";
4
-
5
- /**
6
- * Ensure all root-level document entries have icons
7
- * Batch processing: Collects all entries without icons and generates them in a single call
8
- * Conditionally saves the updated structure if icons were generated
9
- * This is a reusable agent that can be used in structure planning and before publishing
10
- */
11
- export default async function ensureDocumentIcons(inputOrParams, options) {
12
- // Handle multiple calling patterns:
13
- // 1. As function skill: (input, options) where input.documentStructure exists
14
- // 2. As function skill: (input, options) where input.originalDocumentStructure exists
15
- // 3. As standalone function: ({ documentStructure }, options)
16
- const documentStructure =
17
- inputOrParams?.documentStructure ||
18
- inputOrParams?.originalDocumentStructure ||
19
- (Array.isArray(inputOrParams) ? inputOrParams : null);
20
-
21
- if (!documentStructure || !Array.isArray(documentStructure)) {
22
- // Return input unchanged if no documentStructure to process
23
- return inputOrParams || {};
24
- }
25
-
26
- // Batch collect all root-level items that need icon generation
27
- // Only process root-level items (parentId is null, undefined, or empty string)
28
- // Only generate icons for items that don't have one
29
- const itemsNeedingIcon = documentStructure.filter((item) => {
30
- // Only process root-level items
31
- const isRootLevel = !item.parentId || item.parentId === "null" || item.parentId === "";
32
- if (!isRootLevel) return false;
33
-
34
- // Must have title and description for icon generation
35
- if (!item.title || !item.description) return false;
36
-
37
- // Only generate if icon is missing
38
- const hasNoIcon = !item.icon || !item.icon.trim();
39
- return hasNoIcon;
40
- });
41
-
42
- // If all items already have icons, skip
43
- if (itemsNeedingIcon.length === 0) {
44
- return inputOrParams || {};
45
- }
46
-
47
- // Prepare batch list for icon generation
48
- const documentList = itemsNeedingIcon.map((item) => ({
49
- path: item.path,
50
- title: item.title,
51
- description: item.description,
52
- }));
53
-
54
- const iconAgent = options?.context?.agents?.["documentIconGenerate"];
55
- if (!iconAgent) {
56
- console.warn("⚠️ documentIconGenerate agent not found. Skipping icon generation.");
57
- return inputOrParams || {};
58
- }
59
-
60
- let iconsGenerated = false;
61
-
62
- try {
63
- // Batch generate all missing icons in a single call
64
- const iconResult = await options.context.invoke(iconAgent, {
65
- documentList,
66
- });
67
-
68
- // Batch update all document items with generated icons using path as the key
69
- if (iconResult.documentList && Array.isArray(iconResult.documentList)) {
70
- const iconMap = new Map(iconResult.documentList.map((item) => [item.path, item.icon]));
71
-
72
- for (const item of documentStructure) {
73
- const generatedIcon = iconMap.get(item.path);
74
- if (generatedIcon) {
75
- item.icon = generatedIcon;
76
- iconsGenerated = true;
77
- }
78
- }
79
- }
80
-
81
- // Conditionally save the updated structure if icons were generated
82
- // Use the same save pattern as save-output.mjs for consistency
83
- if (iconsGenerated) {
84
- // Try to get outputDir from multiple sources (same as create flow)
85
- let outputDir =
86
- inputOrParams?.outputDir ||
87
- options?.context?.userContext?.outputDir ||
88
- options?.context?.config?.outputDir;
89
-
90
- // If still not found, load from config file and process defaults
91
- if (!outputDir) {
92
- try {
93
- const config = await loadConfigFromFile();
94
- const processedConfig = await processConfigFields(config || {});
95
- outputDir = processedConfig?.outputDir;
96
- } catch {
97
- // Ignore config load errors
98
- }
99
- }
100
-
101
- if (outputDir) {
102
- try {
103
- // Use the same save pattern as save-output.mjs
104
- const savePath = outputDir;
105
- const fileName = "structure-plan.json";
106
- const content = JSON.stringify(documentStructure, null, 2);
107
-
108
- await fs.mkdir(savePath, { recursive: true });
109
- const filePath = join(savePath, fileName);
110
- await fs.writeFile(filePath, content, "utf8");
111
- } catch (saveError) {
112
- console.warn("⚠️ Failed to save updated structure:", saveError.message);
113
- // Continue even if save fails
114
- }
115
- }
116
- }
117
- } catch (error) {
118
- console.warn("⚠️ Failed to generate document icons:", error.message);
119
- console.warn("Continuing without icons.");
120
- }
121
-
122
- // Return input unchanged (documentStructure is modified in place)
123
- return inputOrParams || {};
124
- }
125
-
126
- ensureDocumentIcons.taskTitle = "Ensure document icons";
127
- ensureDocumentIcons.description =
128
- "Check each root-level document entry for icons - if missing, generate one; if present, skip";
129
- ensureDocumentIcons.task_render_mode = "hide";
@@ -1,6 +0,0 @@
1
- export default async function exit() {
2
- process.exit(0);
3
- }
4
-
5
- exit.description =
6
- "Exit the chat session. Equivalent to saying goodbye, quit, exit, close, or see you. Must print a bye message before calling this tool, as it will exit the process immediately.";
@@ -1,50 +0,0 @@
1
- name: feedbackRefiner
2
- description: Learn from your feedback to improve future documentation
3
- instructions:
4
- url: ../../prompts/utils/feedback-refiner.md
5
-
6
- input_schema:
7
- type: object
8
- properties:
9
- feedback:
10
- type: string
11
- description: Tell us what you think about the documentation
12
- stage:
13
- type: string
14
- description: Which part of the process this feedback is about (document_structure, document_refine, translation_refine)
15
- paths:
16
- type: array
17
- items:
18
- type: string
19
- description: Specific documents this feedback applies to (optional)
20
- existingPreferences:
21
- type: string
22
- description: Your existing preferences to avoid duplicates (optional)
23
- required:
24
- - feedback
25
- - stage
26
-
27
- output_schema:
28
- type: object
29
- properties:
30
- rule:
31
- type: string
32
- description: General rule created from your feedback
33
- scope:
34
- type: string
35
- description: Where this rule applies (global, structure, document, translation)
36
- save:
37
- type: boolean
38
- description: Should we remember this preference for next time?
39
- limitToInputPaths:
40
- type: boolean
41
- description: Apply only to the specific documents mentioned?
42
- reason:
43
- type: string
44
- description: Why we made this decision and how the rule was created
45
- required:
46
- - rule
47
- - scope
48
- - save
49
- - limitToInputPaths
50
- - reason
@@ -1,114 +0,0 @@
1
- import { DOC_ACTION } from "../../utils/constants/index.mjs";
2
- import {
3
- fileNameToFlatPath,
4
- findItemByFlatName,
5
- findItemByPath as findItemByPathUtil,
6
- getActionText,
7
- getMainLanguageFiles,
8
- readFileContent,
9
- } from "../../utils/docs-finder-utils.mjs";
10
-
11
- export default async function findItemByPath(
12
- { doc, documentStructure, boardId, docsDir, isTranslate, feedback, locale },
13
- options,
14
- ) {
15
- let foundItem = null;
16
- let selectedFileContent = null;
17
- let docPath = doc;
18
- const docAction = isTranslate ? DOC_ACTION.translate : DOC_ACTION.update;
19
-
20
- // If docPath is empty, let user select from available documents
21
- if (!docPath) {
22
- try {
23
- // Get all main language .md files in docsDir
24
- const mainLanguageFiles = await getMainLanguageFiles(docsDir, locale, documentStructure);
25
-
26
- if (mainLanguageFiles.length === 0) {
27
- throw new Error("No documents found in the docs directory");
28
- }
29
-
30
- // Let user select a file
31
- const selectedFile = await options.prompts.search({
32
- message: getActionText("Select a document to {action}:", docAction),
33
- source: async (input) => {
34
- if (!input || input.trim() === "") {
35
- return mainLanguageFiles.map((file) => ({
36
- name: file,
37
- value: file,
38
- }));
39
- }
40
-
41
- const searchTerm = input.trim().toLowerCase();
42
- const filteredFiles = mainLanguageFiles.filter((file) =>
43
- file.toLowerCase().includes(searchTerm),
44
- );
45
-
46
- return filteredFiles.map((file) => ({
47
- name: file,
48
- value: file,
49
- }));
50
- },
51
- });
52
-
53
- if (!selectedFile) {
54
- throw new Error("No document selected");
55
- }
56
-
57
- // Read the selected .md file content
58
- selectedFileContent = await readFileContent(docsDir, selectedFile);
59
-
60
- // Convert filename back to path
61
- const flatName = fileNameToFlatPath(selectedFile);
62
-
63
- // Try to find matching item by comparing flattened paths
64
- const foundItemByFile = findItemByFlatName(documentStructure, flatName);
65
-
66
- if (!foundItemByFile) {
67
- throw new Error("No document found");
68
- }
69
-
70
- docPath = foundItemByFile.path;
71
- } catch (error) {
72
- console.debug(error?.message);
73
- throw new Error(
74
- getActionText(
75
- "Please run 'aigne doc create' first to create documents, then select which document to {action}",
76
- docAction,
77
- ),
78
- );
79
- }
80
- }
81
-
82
- // Use the utility function to find item and read content
83
- foundItem = await findItemByPathUtil(documentStructure, docPath, boardId, docsDir, locale);
84
-
85
- if (!foundItem) {
86
- throw new Error(`Item with path "${docPath}" not found in documentStructure`);
87
- }
88
-
89
- // Prompt for feedback if not provided
90
- let userFeedback = feedback;
91
- if (!userFeedback) {
92
- const feedbackMessage = "How should we improve this document? (press Enter to skip):";
93
- userFeedback = await options.prompts.input({
94
- message: feedbackMessage,
95
- });
96
- }
97
-
98
- // Merge the found item and ensure content is available
99
- const result = {
100
- ...foundItem,
101
- };
102
-
103
- // Add content if we read it from user selection (takes precedence over utility method content)
104
- if (selectedFileContent !== null) {
105
- result.content = selectedFileContent;
106
- }
107
-
108
- // Add feedback to result if provided
109
- if (userFeedback?.trim()) {
110
- result.feedback = userFeedback.trim();
111
- }
112
-
113
- return result;
114
- }
@@ -1,37 +0,0 @@
1
- import { getActiveRulesForScope } from "../../utils/preferences-utils.mjs";
2
-
3
- export default async function findUserPreferencesByPath({ path, scope }) {
4
- // Get global rules (always applicable)
5
- const globalRules = getActiveRulesForScope("global", []);
6
-
7
- // Get scope-specific rules (document/translation based on scope parameter)
8
- const scopeRules = getActiveRulesForScope(scope, path ? [path] : []);
9
-
10
- // Combine all applicable rules
11
- const allApplicableRules = [...globalRules, ...scopeRules];
12
-
13
- // Extract only rule text and join with double newlines
14
- const ruleTexts = allApplicableRules.map((rule) => rule.rule);
15
- const userPreferences = ruleTexts.length > 0 ? ruleTexts.join("\n\n") : "";
16
-
17
- return {
18
- userPreferences,
19
- };
20
- }
21
-
22
- findUserPreferencesByPath.input_schema = {
23
- type: "object",
24
- properties: {
25
- path: {
26
- type: "string",
27
- description: "Document path to find preferences for",
28
- },
29
- scope: {
30
- type: "string",
31
- description:
32
- "Preference scope: 'document' for update operations, 'translation' for translate operations",
33
- enum: ["document", "translation"],
34
- },
35
- },
36
- required: ["scope"],
37
- };
@@ -1,35 +0,0 @@
1
- import { stringify } from "yaml";
2
-
3
- export default async function formatDocumentStructure({
4
- documentStructure,
5
- originalDocumentStructure,
6
- }) {
7
- if (!documentStructure && !originalDocumentStructure) {
8
- return {
9
- documentStructureYaml: "",
10
- documentStructure: [],
11
- };
12
- }
13
-
14
- // Extract required fields from each item in documentStructure
15
- const formattedData = (documentStructure || originalDocumentStructure)?.map((item) => ({
16
- title: item.title,
17
- path: item.path,
18
- parentId: item.parentId,
19
- description: item.description,
20
- }));
21
-
22
- // Convert to YAML string
23
- const yamlString = stringify(formattedData, {
24
- indent: 2,
25
- lineWidth: 120,
26
- minContentWidth: 20,
27
- });
28
-
29
- return {
30
- documentStructureYaml: yamlString,
31
- documentStructure,
32
- };
33
- }
34
-
35
- formatDocumentStructure.task_render_mode = "hide";
@@ -1,41 +0,0 @@
1
- /**
2
- * Conditionally call generateDocument. If we already have content for diagram-only intents,
3
- * skip LLM generation and pass through the existing content.
4
- */
5
- export default async function generateDocumentOrSkip(input, options) {
6
- const { intentType, content, skipGenerateDocument } = input;
7
-
8
- const isDiagramIntent =
9
- intentType && ["addDiagram", "updateDiagram", "deleteDiagram"].includes(intentType);
10
- const shouldSkip = Boolean(skipGenerateDocument || (isDiagramIntent && content));
11
-
12
- if (shouldSkip) {
13
- // Return the existing content and mark the generation as skipped
14
- return {
15
- ...input,
16
- content,
17
- documentContent: content,
18
- originalContent: content,
19
- reviewContent: content,
20
- };
21
- }
22
-
23
- const generateAgent = options.context?.agents?.["generateDocument"];
24
- if (!generateAgent) {
25
- throw new Error("generateDocument agent not found");
26
- }
27
-
28
- const result = await options.context.invoke(generateAgent, input);
29
- const generatedContent = result?.content ?? result;
30
-
31
- return {
32
- ...input,
33
- ...result,
34
- content: generatedContent,
35
- documentContent: generatedContent,
36
- originalContent: generatedContent,
37
- reviewContent: generatedContent,
38
- };
39
- }
40
-
41
- generateDocumentOrSkip.task_render_mode = "hide";
@@ -1,263 +0,0 @@
1
- import { AIAgent } from "@aigne/core";
2
- import { pick } from "@aigne/core/utils/type-utils.js";
3
- import z from "zod";
4
- import {
5
- DIAGRAM_PLACEHOLDER,
6
- replaceD2WithPlaceholder,
7
- replaceDiagramsWithPlaceholder,
8
- } from "../../utils/d2-utils.mjs";
9
- import { readFileContent } from "../../utils/docs-finder-utils.mjs";
10
- import { getFileName, userContextAt } from "../../utils/utils.mjs";
11
- import { debug } from "../../utils/debug.mjs";
12
-
13
- /**
14
- * Read current document content from file system
15
- * Reuses the same logic as initCurrentContent but returns the content
16
- * First checks userContext, then reads from file if not in context
17
- */
18
- async function readCurrentContent(input, options) {
19
- const { path, docsDir, locale = "en" } = input;
20
-
21
- if (!path || !docsDir) {
22
- return null;
23
- }
24
-
25
- // First check if content is already in userContext
26
- const contentContext = userContextAt(options, `currentContents.${path}`);
27
- const existingContent = contentContext.get();
28
- if (existingContent) {
29
- return existingContent;
30
- }
31
-
32
- // If not in context, read from file (same logic as initCurrentContent)
33
- try {
34
- const fileName = getFileName(path, locale);
35
- const content = await readFileContent(docsDir, fileName);
36
-
37
- if (!content) {
38
- console.warn(`⚠️ Could not read content from ${fileName}`);
39
- return null;
40
- }
41
-
42
- // Set in userContext for future use
43
- contentContext.set(content);
44
-
45
- return content;
46
- } catch (error) {
47
- console.warn(`Failed to read current content for ${path}: ${error.message}`);
48
- return null;
49
- }
50
- }
51
-
52
- /**
53
- * Save document content
54
- */
55
- async function saveDoc(input, options, { content, intentType }) {
56
- const saveAgent = options.context?.agents?.["saveDoc"];
57
- if (!saveAgent) {
58
- console.warn("saveDoc agent not found");
59
- return;
60
- }
61
- await options.context.invoke(saveAgent, {
62
- ...pick(input, ["path", "docsDir", "labels", "locale"]),
63
- content,
64
- intentType, // Pass intentType so saveDoc can handle translation sync
65
- });
66
- }
67
-
68
- /**
69
- * Handle addDiagram intent
70
- */
71
- async function addDiagram(input, options) {
72
- // readCurrentContent will check userContext first, then read from file if needed
73
- const currentContent = await readCurrentContent(input, options);
74
- if (!currentContent) {
75
- throw new Error(`Could not read current content for ${input.path}`);
76
- }
77
-
78
- const contentContext = userContextAt(options, `currentContents.${input.path}`);
79
-
80
- const generateDiagramAgent = options.context.agents["checkGenerateDiagram"];
81
- if (!generateDiagramAgent) {
82
- throw new Error("checkGenerateDiagram agent not found");
83
- }
84
-
85
- const generateDiagramResult = await options.context.invoke(generateDiagramAgent, {
86
- ...pick(input, ["locale", "diagramming", "feedback", "path", "docsDir"]),
87
- documentContent: currentContent,
88
- originalContent: currentContent,
89
- });
90
-
91
- const content = generateDiagramResult.content;
92
- contentContext.set(content);
93
- // Pass intentType to saveDoc so it can handle translation sync automatically
94
- await saveDoc(input, options, { content, intentType: "addDiagram" });
95
- return { content };
96
- }
97
-
98
- /**
99
- * Handle updateDiagram intent
100
- */
101
- async function updateDiagram(input, options) {
102
- // readCurrentContent will check userContext first, then read from file if needed
103
- const currentContent = await readCurrentContent(input, options);
104
- if (!currentContent) {
105
- throw new Error(`Could not read current content for ${input.path}`);
106
- }
107
-
108
- const contentContext = userContextAt(options, `currentContents.${input.path}`);
109
-
110
- let [content] = replaceD2WithPlaceholder({
111
- content: currentContent,
112
- });
113
-
114
- const generateAgent = options.context?.agents?.["generateDiagram"];
115
- if (!generateAgent) {
116
- throw new Error("generateDiagram agent not found");
117
- }
118
-
119
- const result = await options.context.invoke(generateAgent, {
120
- documentContent: content,
121
- locale: input.locale,
122
- diagramming: input.diagramming || {},
123
- feedback: input.feedback,
124
- originalContent: currentContent, // Pass original content to find existing diagrams
125
- path: input.path,
126
- docsDir: input.docsDir,
127
- });
128
-
129
- // generateDiagram now returns { content } with image already inserted
130
- // The image replaces DIAGRAM_PLACEHOLDER or D2 code blocks
131
- if (result?.content) {
132
- content = result.content;
133
- }
134
-
135
- contentContext.set(content);
136
- // Pass intentType to saveDoc so it can handle translation sync automatically
137
- await saveDoc(input, options, { content, intentType: "updateDiagram" });
138
- return { content };
139
- }
140
-
141
- /**
142
- * Handle deleteDiagram intent
143
- */
144
- async function deleteDiagram(input, options) {
145
- // readCurrentContent will check userContext first, then read from file if needed
146
- const currentContent = await readCurrentContent(input, options);
147
- if (!currentContent) {
148
- throw new Error(`Could not read current content for ${input.path}`);
149
- }
150
-
151
- const contentContext = userContextAt(options, `currentContents.${input.path}`);
152
-
153
- // Extract diagram index from feedback if provided
154
- // This allows deleting a specific diagram when multiple diagrams exist
155
- let diagramIndex = input.diagramIndex;
156
- if (diagramIndex === undefined && input.feedback) {
157
- // Import extractDiagramIndexFromFeedback from replace-d2-with-image.mjs
158
- const { extractDiagramIndexFromFeedback } = await import("../create/replace-d2-with-image.mjs");
159
- const extractedIndex = extractDiagramIndexFromFeedback(input.feedback);
160
- if (extractedIndex !== null) {
161
- diagramIndex = extractedIndex;
162
- debug(`Extracted diagram index ${diagramIndex} from feedback: "${input.feedback}"`);
163
- }
164
- }
165
-
166
- // Replace all diagrams (D2 code blocks, generated images, Mermaid) with placeholder
167
- // If diagramIndex is provided, only replace that specific diagram
168
- // This ensures LLM can identify and remove the diagram regardless of its type
169
- const documentContent = replaceDiagramsWithPlaceholder({
170
- content: currentContent,
171
- diagramIndex,
172
- });
173
-
174
- const instructions = `<role>
175
- Your task is to remove ${DIAGRAM_PLACEHOLDER} and adjust the document context (based on the user's feedback) to make it easier to understand.
176
- </role>
177
-
178
- <document_content>
179
- {{documentContent}}
180
- </document_content>
181
-
182
- <user_feedback>
183
- {{feedback}}
184
- </user_feedback>
185
-
186
- <output_constraints>
187
- - Do not provide any explanations; include only the document content itself
188
- </output_constraints>`;
189
-
190
- const deleteAgent = AIAgent.from({
191
- name: "deleteDiagram",
192
- description: "Remove a diagram from the document content",
193
- task_render_mode: "hide",
194
- instructions,
195
- inputSchema: z.object({
196
- documentContent: z.string().describe("Source content of the document"),
197
- feedback: z.string().describe("User feedback for content modifications"),
198
- }),
199
- outputKey: "message",
200
- });
201
-
202
- const { message: content } = await options.context.invoke(deleteAgent, {
203
- documentContent,
204
- feedback: input.feedback,
205
- });
206
-
207
- // Delete associated diagram image files
208
- if (input.docsDir) {
209
- try {
210
- const { deleteDiagramImages } = await import("../../utils/delete-diagram-images.mjs");
211
- const { deleted } = await deleteDiagramImages(currentContent, input.path, input.docsDir);
212
- if (deleted > 0) {
213
- debug(`Deleted ${deleted} diagram image file(s) for ${input.path}`);
214
- }
215
- } catch (error) {
216
- // Don't fail the operation if image deletion fails
217
- console.warn(`Failed to delete diagram images: ${error.message}`);
218
- }
219
- }
220
-
221
- contentContext.set(content);
222
- // Pass intentType to saveDoc so it can handle translation sync automatically
223
- await saveDoc(input, options, { content, intentType: "deleteDiagram" });
224
-
225
- return { content };
226
- }
227
-
228
- /**
229
- * Handle diagram operations based on intent type
230
- * Supports: addDiagram, updateDiagram, deleteDiagram
231
- */
232
- export default async function handleDiagramOperations(
233
- { intentType, path, docsDir, locale, feedback, diagramming, labels },
234
- options,
235
- ) {
236
- if (!intentType || !["addDiagram", "updateDiagram", "deleteDiagram"].includes(intentType)) {
237
- throw new Error(`Invalid intent type for diagram operations: ${intentType}`);
238
- }
239
-
240
- const input = {
241
- path,
242
- docsDir,
243
- locale,
244
- feedback,
245
- diagramming,
246
- labels,
247
- };
248
-
249
- const fnMap = {
250
- addDiagram,
251
- updateDiagram,
252
- deleteDiagram,
253
- };
254
-
255
- if (fnMap[intentType]) {
256
- const result = await fnMap[intentType](input, options);
257
- return result;
258
- }
259
-
260
- throw new Error(`Unsupported intent type: ${intentType}`);
261
- }
262
-
263
- handleDiagramOperations.task_render_mode = "hide";