@aigne/doc-smith 0.8.5 → 0.8.7

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 (126) hide show
  1. package/.aigne/doc-smith/output/structure-plan.json +1 -5
  2. package/CHANGELOG.md +25 -0
  3. package/README.md +3 -3
  4. package/agents/{chat.yaml → chat/index.yaml} +7 -7
  5. package/agents/generate/check-document-structure.yaml +30 -0
  6. package/agents/{check-structure-plan.mjs → generate/check-need-generate-structure.mjs} +21 -21
  7. package/agents/generate/generate-structure.yaml +58 -0
  8. package/agents/{docs-generator.yaml → generate/index.yaml} +15 -16
  9. package/agents/generate/refine-document-structure.yaml +12 -0
  10. package/agents/{input-generator.mjs → init/index.mjs} +34 -27
  11. package/agents/{manage-prefs.mjs → prefs/index.mjs} +16 -16
  12. package/agents/publish/index.yaml +17 -0
  13. package/agents/{publish-docs.mjs → publish/publish-docs.mjs} +15 -16
  14. package/agents/schema/{structure-plan-result.yaml → document-execution-structure.yaml} +3 -3
  15. package/agents/schema/document-structure.yaml +26 -0
  16. package/agents/{language-selector.mjs → translate/choose-language.mjs} +5 -5
  17. package/agents/{retranslate.yaml → translate/index.yaml} +17 -18
  18. package/agents/translate/translate-document.yaml +32 -0
  19. package/agents/{batch-translate.yaml → translate/translate-multilingual.yaml} +5 -5
  20. package/agents/update/batch-generate-document.yaml +19 -0
  21. package/agents/{check-detail.mjs → update/check-document.mjs} +16 -16
  22. package/agents/{detail-generator-and-translate.yaml → update/generate-and-translate-document.yaml} +23 -23
  23. package/agents/update/generate-document.yaml +50 -0
  24. package/agents/{detail-regenerator.yaml → update/index.yaml} +16 -17
  25. package/agents/{action-success.mjs → utils/action-success.mjs} +2 -2
  26. package/agents/{check-detail-result.mjs → utils/check-detail-result.mjs} +3 -3
  27. package/agents/{check-feedback-refiner.mjs → utils/check-feedback-refiner.mjs} +6 -6
  28. package/agents/{find-items-by-paths.mjs → utils/choose-docs.mjs} +25 -10
  29. package/agents/{docs-fs.yaml → utils/docs-fs-actor.yaml} +3 -1
  30. package/agents/utils/feedback-refiner.yaml +50 -0
  31. package/agents/{find-item-by-path.mjs → utils/find-item-by-path.mjs} +17 -7
  32. package/agents/{find-user-preferences-by-path.mjs → utils/find-user-preferences-by-path.mjs} +1 -1
  33. package/agents/utils/format-document-structure.mjs +25 -0
  34. package/agents/{load-sources.mjs → utils/load-sources.mjs} +41 -28
  35. package/agents/{save-docs.mjs → utils/save-docs.mjs} +16 -16
  36. package/agents/{save-single-doc.mjs → utils/save-single-doc.mjs} +2 -2
  37. package/agents/{transform-detail-datasources.mjs → utils/transform-detail-datasources.mjs} +1 -1
  38. package/aigne.yaml +35 -35
  39. package/docs/cli-reference.md +1 -1
  40. package/docs/features-generate-documentation.md +1 -1
  41. package/docs/features-update-and-refine.md +2 -2
  42. package/docs-mcp/analyze-docs-relevance.yaml +10 -10
  43. package/docs-mcp/docs-search.yaml +5 -3
  44. package/package.json +10 -8
  45. package/prompts/{document → detail/custom}/custom-code-block.md +6 -6
  46. package/prompts/detail/custom/custom-components.md +172 -0
  47. package/prompts/{document → detail}/d2-chart/rules.md +95 -1
  48. package/prompts/{document → detail}/detail-example.md +80 -61
  49. package/prompts/{document/detail-generator.md → detail/document-rules.md} +4 -8
  50. package/prompts/{content-detail-generator.md → detail/generate-document.md} +48 -25
  51. package/prompts/{check-structure-planning-result.md → structure/check-document-structure.md} +23 -17
  52. package/prompts/{document/structure-planning.md → structure/document-rules.md} +0 -2
  53. package/prompts/{structure-planning.md → structure/generate-structure.md} +51 -30
  54. package/prompts/{document → structure}/structure-example.md +2 -2
  55. package/prompts/{document → structure}/structure-getting-started.md +2 -2
  56. package/prompts/translate/glossary.md +6 -0
  57. package/prompts/{translator.md → translate/translate-document.md} +29 -10
  58. package/prompts/{feedback-refiner.md → utils/feedback-refiner.md} +8 -8
  59. package/tests/agents/chat/chat.test.mjs +46 -0
  60. package/tests/agents/generate/check-document-structure.test.mjs +51 -0
  61. package/tests/agents/generate/check-need-generate-structure.test.mjs +292 -0
  62. package/tests/agents/generate/generate-structure.test.mjs +51 -0
  63. package/tests/{input-generator.test.mjs → agents/init/init.test.mjs} +19 -17
  64. package/tests/agents/prefs/prefs.test.mjs +431 -0
  65. package/tests/agents/publish/publish-docs.test.mjs +642 -0
  66. package/tests/agents/translate/choose-language.test.mjs +311 -0
  67. package/tests/agents/translate/translate-document.test.mjs +51 -0
  68. package/tests/agents/update/check-document.test.mjs +523 -0
  69. package/tests/agents/update/generate-document.test.mjs +51 -0
  70. package/tests/agents/utils/action-success.test.mjs +54 -0
  71. package/tests/{check-detail-result.test.mjs → agents/utils/check-detail-result.test.mjs} +98 -98
  72. package/tests/agents/utils/check-feedback-refiner.test.mjs +478 -0
  73. package/tests/agents/utils/choose-docs.test.mjs +417 -0
  74. package/tests/agents/utils/exit.test.mjs +70 -0
  75. package/tests/agents/utils/feedback-refiner.test.mjs +51 -0
  76. package/tests/agents/utils/find-item-by-path.test.mjs +526 -0
  77. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +382 -0
  78. package/tests/agents/utils/format-document-structure.test.mjs +264 -0
  79. package/tests/agents/utils/fs.test.mjs +267 -0
  80. package/tests/{load-sources.test.mjs → agents/utils/load-sources.test.mjs} +153 -25
  81. package/tests/{save-docs.test.mjs → agents/utils/save-docs.test.mjs} +11 -5
  82. package/tests/agents/utils/save-output.test.mjs +315 -0
  83. package/tests/agents/utils/save-single-doc.test.mjs +364 -0
  84. package/tests/agents/utils/transform-detail-datasources.test.mjs +363 -0
  85. package/tests/utils/auth-utils.test.mjs +358 -0
  86. package/tests/utils/blocklet.test.mjs +334 -0
  87. package/tests/{conflict-resolution.test.mjs → utils/conflict-detector.test.mjs} +3 -3
  88. package/tests/utils/constants.test.mjs +295 -0
  89. package/tests/utils/d2-utils.test.mjs +423 -0
  90. package/tests/utils/deploy.test.mjs +365 -0
  91. package/tests/utils/docs-finder-utils.test.mjs +625 -0
  92. package/tests/utils/file-utils.test.mjs +213 -0
  93. package/tests/{kroki-utils.test.mjs → utils/kroki-utils.test.mjs} +2 -2
  94. package/tests/utils/load-config.test.mjs +141 -0
  95. package/tests/{mermaid-validation.test.mjs → utils/mermaid-validator.test.mjs} +2 -2
  96. package/tests/utils/mock-chat-model.mjs +12 -0
  97. package/tests/{preferences-utils.test.mjs → utils/preferences-utils.test.mjs} +1 -1
  98. package/tests/{save-value-to-config.test.mjs → utils/save-value-to-config.test.mjs} +61 -4
  99. package/tests/utils/utils.test.mjs +939 -0
  100. package/utils/auth-utils.mjs +1 -1
  101. package/utils/conflict-detector.mjs +1 -1
  102. package/utils/constants.mjs +5 -3
  103. package/utils/d2-utils.mjs +194 -0
  104. package/utils/deploy.mjs +3 -3
  105. package/utils/docs-finder-utils.mjs +26 -26
  106. package/utils/icon-map.mjs +26 -0
  107. package/{agents → utils}/load-config.mjs +2 -18
  108. package/utils/markdown-checker.mjs +5 -5
  109. package/agents/batch-docs-detail-generator.yaml +0 -19
  110. package/agents/check-structure-planning-result.yaml +0 -30
  111. package/agents/content-detail-generator.yaml +0 -50
  112. package/agents/feedback-refiner.yaml +0 -52
  113. package/agents/format-structure-plan.mjs +0 -25
  114. package/agents/reflective-structure-planner.yaml +0 -12
  115. package/agents/schema/structure-plan.yaml +0 -26
  116. package/agents/structure-planning.yaml +0 -58
  117. package/agents/team-publish-docs.yaml +0 -18
  118. package/agents/translate.yaml +0 -31
  119. package/prompts/document/custom-components.md +0 -104
  120. package/tests/README.md +0 -93
  121. package/tests/utils.test.mjs +0 -2067
  122. /package/agents/{exit.mjs → utils/exit.mjs} +0 -0
  123. /package/agents/{fs.mjs → utils/fs.mjs} +0 -0
  124. /package/agents/{save-output.mjs → utils/save-output.mjs} +0 -0
  125. /package/prompts/{document → detail}/d2-chart/official-examples.md +0 -0
  126. /package/prompts/{document → detail}/jsx/rules.md +0 -0
@@ -136,11 +136,7 @@
136
136
  "description": "Understand the built-in checks DocSmith performs to ensure high-quality, well-formatted, and error-free documentation, including link checking and diagram validation.",
137
137
  "path": "/advanced/quality-assurance",
138
138
  "parentId": "/advanced",
139
- "sourceIds": [
140
- "utils/markdown-checker.mjs",
141
- "utils/mermaid-validator.mjs",
142
- "utils/kroki-utils.mjs"
143
- ]
139
+ "sourceIds": ["utils/markdown-checker.mjs", "utils/mermaid-validator.mjs", "utils/d2-utils.mjs"]
144
140
  },
145
141
  {
146
142
  "title": "Changelog",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.7](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.6...v0.9.0) (2025-09-12)
4
+
5
+
6
+ ### Features
7
+
8
+ * support defining API parameters with field element ([#104](https://github.com/AIGNE-io/aigne-doc-smith/issues/104)) ([2296ead](https://github.com/AIGNE-io/aigne-doc-smith/commit/2296ead15a00aaf809b3854bf349361f0213f522))
9
+
10
+ ## [0.8.6](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.5...v0.8.6) (2025-09-11)
11
+
12
+
13
+ ### Features
14
+
15
+ * add deploy unit tests and improve publish workflow with better logging ([e33a94b](https://github.com/AIGNE-io/aigne-doc-smith/commit/e33a94bef5eda09398901fa1f953e662ae5fbd16))
16
+ * **publish:** display publish url for the default publish processing ([9d1d018](https://github.com/AIGNE-io/aigne-doc-smith/commit/9d1d0180dc9c8bb0a4393a893eed2395eec300ab))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **deploy:** ensure log is saved after await to prevent save failure ([793343f](https://github.com/AIGNE-io/aigne-doc-smith/commit/793343fc7f96ab962e70eb310cb07f4e7eaec9e0))
22
+
23
+
24
+ ### Miscellaneous Chores
25
+
26
+ * release 0.8.6 ([1e25cb4](https://github.com/AIGNE-io/aigne-doc-smith/commit/1e25cb49a26d8bcc3c83ec36120b6bad4042cadf))
27
+
3
28
  ## [0.8.5](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.4...v0.8.5) (2025-09-10)
4
29
 
5
30
 
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  [![GitHub star chart](https://img.shields.io/github/stars/AIGNE-io/aigne-doc-smith?style=flat-square)](https://star-history.com/#AIGNE-io/aigne-doc-smith)
2
2
  [![Open Issues](https://img.shields.io/github/issues-raw/AIGNE-io/aigne-doc-smith?style=flat-square)](https://github.com/AIGNE-io/aigne-doc-smith/issues)
3
3
  [![codecov](https://codecov.io/gh/AIGNE-io/aigne-doc-smith/graph/badge.svg?token=95TQO2NKYC)](https://codecov.io/gh/AIGNE-io/aigne-doc-smith)
4
- [![NPM Version](https://img.shields.io/npm/v/@aigne/core)](https://www.npmjs.com/package/@aigne/doc-smith)
4
+ [![NPM Version](https://img.shields.io/npm/v/@aigne/doc-smith)](https://www.npmjs.com/package/@aigne/doc-smith)
5
5
 
6
6
  # AIGNE DocSmith
7
7
 
@@ -17,7 +17,7 @@ As shown in the diagram, DocSmith integrates seamlessly with other [AIGNE](https
17
17
 
18
18
  ## Features
19
19
 
20
- - **Automated Structure Planning:** Intelligently analyzes your codebase to generate a comprehensive and logical document structure.
20
+ - **Automated Generate Document Structure:** Intelligently analyzes your codebase to generate a comprehensive and logical document structure.
21
21
  - **AI-Powered Content Generation:** Populates the document structure with detailed, high-quality content.
22
22
  - **Multi-Language Support:** Seamlessly translates your documentation into 12 languages including English, Chinese, Japanese, Korean, Spanish, French, German, Portuguese, Russian, Italian, and Arabic.
23
23
  - **AIGNE Hub Integration:** Use [AIGNE Hub](https://www.aigne.io/en/hub) as your LLM provider without needing your own API keys, with easy switching between different large language models.
@@ -185,7 +185,7 @@ aigne doc update --docs overview.md --feedback "Add more comprehensive FAQ entri
185
185
 
186
186
  **Interactive Mode:** When run without parameters, `aigne doc update` will present an interactive menu for you to select which document to regenerate and provide feedback.
187
187
 
188
- #### Optimize Structure Planning
188
+ #### Optimize Document Structure
189
189
 
190
190
  Improve the overall documentation structure based on feedback:
191
191
 
@@ -21,10 +21,10 @@ instructions: |
21
21
  input_key: message
22
22
  memory: true
23
23
  skills:
24
- - ./input-generator.mjs
25
- - ./docs-generator.yaml
26
- - ./detail-regenerator.yaml
27
- - ./team-publish-docs.yaml
28
- - ./retranslate.yaml
29
- - ./docs-fs.yaml
30
- - ./exit.mjs
24
+ - ../init/index.mjs
25
+ - ../generate/index.yaml
26
+ - ../update/index.yaml
27
+ - ../publish/index.yaml
28
+ - ../translate/index.yaml
29
+ - ../utils/docs-fs-actor.yaml
30
+ - ../utils/exit.mjs
@@ -0,0 +1,30 @@
1
+ name: checkDocumentStructure
2
+ description: Check the Document Structure to ensure it meets expectations, especially in scenarios with previous generation results and user feedback.
3
+ instructions:
4
+ url: ../../prompts/structure/check-document-structure.md
5
+ input_schema:
6
+ type: object
7
+ properties:
8
+ documentStructure:
9
+ $ref: ../schema/document-structure.yaml
10
+ description: Newly generated document structure.
11
+ originalDocumentStructure:
12
+ $ref: ../schema/document-structure.yaml
13
+ description: Previous generation's document structure for comparison. If it doesn't exist, the check passes by default.
14
+ feedback:
15
+ type: string
16
+ description: User feedback provided for the previous generation's results.
17
+ required:
18
+ - documentStructure
19
+ output_schema:
20
+ type: object
21
+ properties:
22
+ isValid:
23
+ type: boolean
24
+ description: Whether the check passes. true indicates pass, false indicates failure.
25
+ structureReviewFeedback:
26
+ type: string
27
+ description: Detailed explanation of the check results. If it fails, clearly specify which parts do not meet requirements.
28
+ required:
29
+ - isValid
30
+ - structureReviewFeedback
@@ -1,27 +1,27 @@
1
1
  import { access } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { getActiveRulesForScope } from "../utils/preferences-utils.mjs";
3
+ import { getActiveRulesForScope } from "../../utils/preferences-utils.mjs";
4
4
  import {
5
5
  getCurrentGitHead,
6
6
  getProjectInfo,
7
7
  hasFileChangesBetweenCommits,
8
8
  loadConfigFromFile,
9
9
  saveValueToConfig,
10
- } from "../utils/utils.mjs";
10
+ } from "../../utils/utils.mjs";
11
11
 
12
- export default async function checkStructurePlan(
13
- { originalStructurePlan, feedback, lastGitHead, docsDir, forceRegenerate, ...rest },
12
+ export default async function checkNeedGenerateStructure(
13
+ { originalDocumentStructure, feedback, lastGitHead, docsDir, forceRegenerate, ...rest },
14
14
  options,
15
15
  ) {
16
- // Check if we need to regenerate structure plan
16
+ // Check if we need to regenerate document structure
17
17
  let shouldRegenerate = false;
18
18
  let finalFeedback = feedback;
19
19
  let submittedFeedback = feedback;
20
20
 
21
- // Prompt for feedback if originalStructurePlan exists and no feedback provided
22
- if (originalStructurePlan && !feedback) {
21
+ // Prompt for feedback if originalDocumentStructure exists and no feedback provided
22
+ if (originalDocumentStructure && !feedback) {
23
23
  const userFeedback = await options.prompts.input({
24
- message: "Please provide feedback for structure planning (press Enter to skip):",
24
+ message: "How can we improve the documentation structure? (press Enter to skip):",
25
25
  });
26
26
 
27
27
  if (userFeedback?.trim()) {
@@ -30,8 +30,8 @@ export default async function checkStructurePlan(
30
30
  }
31
31
  }
32
32
 
33
- // If no feedback and originalStructurePlan exists, check for git changes
34
- if (originalStructurePlan) {
33
+ // If no feedback and originalDocumentStructure exists, check for git changes
34
+ if (originalDocumentStructure) {
35
35
  // If no lastGitHead, check if _sidebar.md exists to determine if we should regenerate
36
36
  if (!lastGitHead) {
37
37
  try {
@@ -78,16 +78,16 @@ export default async function checkStructurePlan(
78
78
  `;
79
79
  }
80
80
 
81
- // If no regeneration needed, return original structure plan
82
- if (originalStructurePlan && !finalFeedback && !shouldRegenerate) {
81
+ // If no regeneration needed, return original document structure
82
+ if (originalDocumentStructure && !finalFeedback && !shouldRegenerate) {
83
83
  return {
84
- structurePlan: originalStructurePlan,
84
+ documentStructure: originalDocumentStructure,
85
85
  };
86
86
  }
87
87
 
88
- const panningAgent = options.context.agents["structurePlanning"];
88
+ const panningAgent = options.context.agents["refineDocumentStructure"];
89
89
 
90
- // Get user preferences for structure planning and global scope
90
+ // Get user preferences for document structure and global scope
91
91
  const structureRules = getActiveRulesForScope("structure", []);
92
92
  const globalRules = getActiveRulesForScope("global", []);
93
93
 
@@ -100,7 +100,7 @@ export default async function checkStructurePlan(
100
100
 
101
101
  const result = await options.context.invoke(panningAgent, {
102
102
  feedback: finalFeedback || "",
103
- originalStructurePlan,
103
+ originalDocumentStructure,
104
104
  userPreferences,
105
105
  ...rest,
106
106
  });
@@ -155,12 +155,12 @@ export default async function checkStructurePlan(
155
155
  return {
156
156
  ...result,
157
157
  feedback: "", // clear feedback
158
- structurePlanFeedback: submittedFeedback,
158
+ documentStructureFeedback: submittedFeedback,
159
159
  projectInfoMessage: message,
160
- originalStructurePlan: originalStructurePlan
161
- ? originalStructurePlan
162
- : JSON.parse(JSON.stringify(result.structurePlan || [])),
160
+ originalDocumentStructure: originalDocumentStructure
161
+ ? originalDocumentStructure
162
+ : JSON.parse(JSON.stringify(result.documentStructure || [])),
163
163
  };
164
164
  }
165
165
 
166
- checkStructurePlan.taskTitle = "Check if structure plan needs regeneration";
166
+ checkNeedGenerateStructure.taskTitle = "Check if document structure needs generate or update";
@@ -0,0 +1,58 @@
1
+ name: generateStructure
2
+ description: Generate the structure and organization of your documentation
3
+ instructions:
4
+ url: ../../prompts/structure/generate-structure.md
5
+ input_schema:
6
+ type: object
7
+ properties:
8
+ rules:
9
+ type: string
10
+ description: Your specific requirements for documentation structure
11
+ locale:
12
+ type: string
13
+ description: Primary language for documentation (e.g., zh, en, ja)
14
+ datasources:
15
+ type: string
16
+ description: Project content and context to help generate document structure
17
+ targetAudience:
18
+ type: string
19
+ description: Target audience for the documentation
20
+ nodeName:
21
+ type: string
22
+ description: Specific section or page name to focus on
23
+ glossary:
24
+ type: string
25
+ description: Glossary for consistent terminology
26
+ feedback:
27
+ type: string
28
+ description: Tell us how to improve the documentation structure
29
+ userPreferences:
30
+ type: string
31
+ description: Your saved preferences for structure and documentation style
32
+ docsType:
33
+ type: string
34
+ description: "Documentation type (options: general, getting-started, reference, faq)"
35
+ default: general
36
+ required:
37
+ - rules
38
+ - datasources
39
+ output_schema:
40
+ type: object
41
+ properties:
42
+ projectName:
43
+ type: string
44
+ description: Project name identified from your content sources
45
+ projectDesc:
46
+ type: string
47
+ description: Brief project description generated from content analysis (under 50 words)
48
+ documentStructure: ../schema/document-structure.yaml
49
+ documentStructureTree:
50
+ type: string
51
+ description: |
52
+ Visual tree structure showing documentation hierarchy with indented levels for easy review:
53
+ ```
54
+ - Home
55
+ - Getting Started
56
+ - Installation
57
+ - Requirements
58
+ ```
@@ -3,17 +3,16 @@ name: generate
3
3
  alias:
4
4
  - gen
5
5
  - g
6
- description: Automatically generates comprehensive project documentation
6
+ description: Generate complete documentation for your project
7
7
  skills:
8
- - url: ./input-generator.mjs
8
+ - url: ../init/index.mjs
9
9
  default_input:
10
10
  skipIfExists: true
11
- - ./load-config.mjs
12
- - ./load-sources.mjs
13
- - ./check-structure-plan.mjs
14
- - url: ./save-output.mjs
11
+ - ../utils/load-sources.mjs
12
+ - ./check-need-generate-structure.mjs
13
+ - url: ../utils/save-output.mjs
15
14
  default_input:
16
- saveKey: structurePlan
15
+ saveKey: documentStructure
17
16
  savePath:
18
17
  $get: outputDir
19
18
  fileName: structure-plan.json
@@ -24,7 +23,7 @@ skills:
24
23
  $merge([
25
24
  $,
26
25
  {
27
- 'structurePlanResult': $map(structurePlan, function($item) {
26
+ 'documentExecutionStructure': $map(documentStructure, function($item) {
28
27
  $merge([
29
28
  $item,
30
29
  {
@@ -35,25 +34,25 @@ skills:
35
34
  "datasources": ""
36
35
  }
37
36
  ])
38
- - ./format-structure-plan.mjs
39
- - ./batch-docs-detail-generator.yaml
40
- - url: ./check-feedback-refiner.mjs
37
+ - ../utils/format-document-structure.mjs
38
+ - ../update/batch-generate-document.yaml
39
+ - url: ../utils/check-feedback-refiner.mjs
41
40
  default_input:
42
- stage: structure_planning
43
- - ./save-docs.mjs
41
+ stage: document_structure
42
+ - ../utils/save-docs.mjs
44
43
 
45
44
  input_schema:
46
45
  type: object
47
46
  properties:
48
47
  glossary:
49
48
  type: string
50
- description: Glossary of terms for consistent terminology, use @<file> to read from a file
49
+ description: Glossary file for consistent terminology (use @filename.md)
51
50
  feedback:
52
51
  type: string
53
- description: Feedback for structure planning adjustments
52
+ description: Tell us how to improve the documentation structure
54
53
  forceRegenerate:
55
54
  type: boolean
56
- description: Force regenerate all documentation
55
+ description: Rebuild all documentation from scratch
57
56
  required:
58
57
  - config
59
58
  mode: sequential
@@ -0,0 +1,12 @@
1
+ type: team
2
+ name: refineDocumentStructure
3
+ description: A team of agents that generate the structure of the documentation.
4
+ skills:
5
+ - generate-structure.yaml
6
+ task_title: Generate the structure of the documentation
7
+ task_render_mode: collapse
8
+ reflection:
9
+ reviewer: check-document-structure.yaml
10
+ is_approved: isValid
11
+ max_iterations: 3
12
+ return_last_on_max_iterations: true
@@ -2,7 +2,7 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import chalk from "chalk";
4
4
  import { stringify as yamlStringify } from "yaml";
5
- import { getFilteredOptions } from "../utils/conflict-detector.mjs";
5
+ import { getFilteredOptions } from "../../utils/conflict-detector.mjs";
6
6
  import {
7
7
  DEPTH_RECOMMENDATION_LOGIC,
8
8
  DOCUMENT_STYLES,
@@ -11,14 +11,15 @@ import {
11
11
  READER_KNOWLEDGE_LEVELS,
12
12
  SUPPORTED_LANGUAGES,
13
13
  TARGET_AUDIENCES,
14
- } from "../utils/constants.mjs";
14
+ } from "../../utils/constants.mjs";
15
+ import loadConfig from "../../utils/load-config.mjs";
15
16
  import {
16
17
  detectSystemLanguage,
17
18
  getAvailablePaths,
18
19
  getProjectInfo,
19
20
  isGlobPattern,
20
21
  validatePath,
21
- } from "../utils/utils.mjs";
22
+ } from "../../utils/utils.mjs";
22
23
 
23
24
  // UI constants
24
25
  const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
@@ -31,7 +32,7 @@ const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
31
32
  * @returns {Promise<Object>}
32
33
  */
33
34
  export default async function init(
34
- { outputPath = ".aigne/doc-smith", fileName = "config.yaml", skipIfExists = false },
35
+ { outputPath = ".aigne/doc-smith", fileName = "config.yaml", skipIfExists = false, appUrl },
35
36
  options,
36
37
  ) {
37
38
  if (skipIfExists) {
@@ -39,19 +40,20 @@ export default async function init(
39
40
  const configContent = await readFile(filePath, "utf8").catch(() => null);
40
41
  // Only skip if file exists AND has non-empty content
41
42
  if (configContent && configContent.trim() !== "") {
42
- return {};
43
+ // load config from file
44
+ return loadConfig({ config: filePath, appUrl });
43
45
  }
44
46
  }
45
47
 
46
48
  console.log("🚀 Welcome to AIGNE DocSmith!");
47
- console.log("Let's create your documentation configuration.\n");
49
+ console.log("Let's set up your documentation preferences.\n");
48
50
 
49
51
  // Collect user information
50
52
  const input = {};
51
53
 
52
54
  // 1. Primary purpose - what's the main outcome you want readers to achieve?
53
55
  const purposeChoices = await options.prompts.checkbox({
54
- message: "📝 [1/8]: What is the primary goal for your readers? (Select all that apply)",
56
+ message: "📝 [1/8]: What should your documentation help readers achieve?",
55
57
  choices: Object.entries(DOCUMENT_STYLES)
56
58
  .filter(([key]) => key !== "custom") // Remove custom option for multiselect
57
59
  .map(([key, style]) => ({
@@ -61,7 +63,7 @@ export default async function init(
61
63
  })),
62
64
  validate: (input) => {
63
65
  if (input.length === 0) {
64
- return "Please select at least one purpose.";
66
+ return "Please choose at least one goal for your documentation.";
65
67
  }
66
68
  return true;
67
69
  },
@@ -81,10 +83,10 @@ export default async function init(
81
83
  })),
82
84
  validate: (input) => {
83
85
  if (input.length === 0) {
84
- return "Please select at least one priority.";
86
+ return "Please choose at least one priority.";
85
87
  }
86
88
  if (input.length > 2) {
87
- return "Please select maximum 2 priorities.";
89
+ return "Please choose maximum 2 priorities.";
88
90
  }
89
91
  return true;
90
92
  },
@@ -99,7 +101,7 @@ export default async function init(
99
101
 
100
102
  // 2. Target audience - who will be reading this most often?
101
103
  const audienceChoices = await options.prompts.checkbox({
102
- message: "👥 [2/8]: Who is the primary audience for this documentation?",
104
+ message: "👥 [2/8]: Who will be reading your documentation?",
103
105
  choices: Object.entries(TARGET_AUDIENCES)
104
106
  .filter(([key]) => key !== "custom") // Remove custom option for multiselect
105
107
  .map(([key, audience]) => ({
@@ -109,7 +111,7 @@ export default async function init(
109
111
  })),
110
112
  validate: (input) => {
111
113
  if (input.length === 0) {
112
- return "Please select at least one audience.";
114
+ return "Please choose at least one audience.";
113
115
  }
114
116
  return true;
115
117
  },
@@ -133,7 +135,7 @@ export default async function init(
133
135
  );
134
136
 
135
137
  const knowledgeChoice = await options.prompts.select({
136
- message: "🧠 [3/8]: What is your reader's typical starting knowledge level?",
138
+ message: "🧠 [3/8]: How much do readers already know about your project?",
137
139
  choices: Object.entries(filteredKnowledgeOptions).map(([key, level]) => ({
138
140
  name: `${level.name}`,
139
141
  description: level.description,
@@ -178,7 +180,7 @@ export default async function init(
178
180
  );
179
181
 
180
182
  const depthChoice = await options.prompts.select({
181
- message: "📊 [4/8]: How comprehensive should the documentation be?",
183
+ message: "📊 [4/8]: How detailed should your documentation be?",
182
184
  choices: Object.entries(filteredDepthOptions).map(([key, depth]) => ({
183
185
  name: `${depth.name}`,
184
186
  description: depth.description,
@@ -196,7 +198,7 @@ export default async function init(
196
198
 
197
199
  // Let user select primary language from supported list
198
200
  const primaryLanguageChoice = await options.prompts.select({
199
- message: "🌐 [5/8]: Choose primary documentation language:",
201
+ message: "🌐 [5/8]: What's your main documentation language?",
200
202
  choices: SUPPORTED_LANGUAGES.map((lang) => ({
201
203
  name: `${lang.label} - ${lang.sample}`,
202
204
  value: lang.code,
@@ -213,7 +215,7 @@ export default async function init(
213
215
  );
214
216
 
215
217
  const translateLanguageChoices = await options.prompts.checkbox({
216
- message: "🔄 [6/8]: Select translation languages:",
218
+ message: "🔄 [6/8]: Which languages should we translate to?",
217
219
  choices: availableTranslationLanguages.map((lang) => ({
218
220
  name: `${lang.label} - ${lang.sample}`,
219
221
  value: lang.code,
@@ -224,21 +226,23 @@ export default async function init(
224
226
 
225
227
  // 7. Documentation directory
226
228
  const docsDirInput = await options.prompts.input({
227
- message: `📁 [7/8]: Where to save generated docs:`,
229
+ message: `📁 [7/8]: Where should we save your documentation?`,
228
230
  default: `${outputPath}/docs`,
229
231
  });
230
232
  input.docsDir = docsDirInput.trim() || `${outputPath}/docs`;
231
233
 
232
- // 8. Source code paths
233
- console.log("\n🔍 [8/8]: Source Code Paths");
234
- console.log("Enter paths to analyze for documentation (e.g., ./src, ./lib)");
235
- console.log("💡 You can also enter glob patterns (e.g., src/**/*.js, **/*.md)");
236
- console.log("💡 If no paths are configured, './' will be used as default");
234
+ // 8. Content sources
235
+ console.log("\n🔍 [8/8]: Content Sources");
236
+ console.log(
237
+ "What folders/files should we analyze for documentation? (e.g., ./src, ./docs, ./README.md)",
238
+ );
239
+ console.log("💡 Advanced: Use patterns like src/**/*.js or docs/**/*.md for specific files");
240
+ console.log("💡 Leave empty to scan everything");
237
241
 
238
242
  const sourcePaths = [];
239
243
  while (true) {
240
244
  const selectedPath = await options.prompts.search({
241
- message: "Path or glob pattern:",
245
+ message: "File/folder path or pattern:",
242
246
  source: async (input) => {
243
247
  if (!input || input.trim() === "") {
244
248
  return [
@@ -330,15 +334,18 @@ export default async function init(
330
334
  await mkdir(dirPath, { recursive: true });
331
335
 
332
336
  await writeFile(filePath, yamlContent, "utf8");
333
- console.log(`\n🎉 Configuration saved to: ${chalk.cyan(filePath)}`);
337
+ console.log(`\n Setup complete! Configuration saved to: ${chalk.cyan(filePath)}`);
334
338
  // Print YAML content for user review
335
339
  console.log(chalk.cyan("---"));
336
340
  console.log(chalk.cyan(yamlContent));
337
341
  console.log(chalk.cyan("---"));
338
342
  console.log("💡 You can edit the configuration file anytime to modify settings.\n");
339
- console.log(
340
- `🚀 Run ${chalk.cyan("'aigne doc generate'")} to start documentation generation!\n`,
341
- );
343
+ console.log(`🚀 Ready to generate docs? Run: ${chalk.cyan("aigne doc generate")}\n`);
344
+
345
+ // load config from file
346
+ if (skipIfExists) {
347
+ return loadConfig({ config: filePath, appUrl });
348
+ }
342
349
 
343
350
  return {};
344
351
  } catch (error) {
@@ -1,4 +1,4 @@
1
- import { readPreferences, removeRule, writePreferences } from "../utils/preferences-utils.mjs";
1
+ import { readPreferences, removeRule, writePreferences } from "../../utils/preferences-utils.mjs";
2
2
 
3
3
  /**
4
4
  * List all user preferences with formatted display
@@ -8,7 +8,7 @@ function listPreferences() {
8
8
  const preferences = readPreferences();
9
9
 
10
10
  if (preferences.rules.length === 0) {
11
- return { message: "No preferences found." };
11
+ return { message: "No saved preferences found." };
12
12
  }
13
13
 
14
14
  let message = "# User Preferences\n\n";
@@ -53,7 +53,7 @@ async function removePreferences(id, options) {
53
53
  if (!targetIds || targetIds.length === 0) {
54
54
  // Interactive selection
55
55
  if (preferences.rules.length === 0) {
56
- return { message: "No preferences found to remove." };
56
+ return { message: "No preferences available to remove." };
57
57
  }
58
58
 
59
59
  const choices = preferences.rules.map((rule) => ({
@@ -63,18 +63,18 @@ async function removePreferences(id, options) {
63
63
  }));
64
64
 
65
65
  targetIds = await options.prompts.checkbox({
66
- message: "Select preferences to remove:",
66
+ message: "Choose preferences to delete:",
67
67
  choices,
68
68
  validate: (answer) => {
69
69
  if (answer.length === 0) {
70
- return "Please select at least one preference to remove";
70
+ return "Please choose at least one preference to delete";
71
71
  }
72
72
  return true;
73
73
  },
74
74
  });
75
75
 
76
76
  if (!targetIds || targetIds.length === 0) {
77
- return { message: "No preferences selected for removal." };
77
+ return { message: "No preferences selected for deletion." };
78
78
  }
79
79
  }
80
80
 
@@ -108,7 +108,7 @@ async function togglePreferences(id, options) {
108
108
  if (!targetIds || targetIds.length === 0) {
109
109
  // Interactive selection
110
110
  if (preferences.rules.length === 0) {
111
- return { message: "No preferences found to toggle." };
111
+ return { message: "No preferences available to toggle." };
112
112
  }
113
113
 
114
114
  const choices = preferences.rules.map((rule) => ({
@@ -118,18 +118,18 @@ async function togglePreferences(id, options) {
118
118
  }));
119
119
 
120
120
  targetIds = await options.prompts.checkbox({
121
- message: "Select preferences to toggle active status:",
121
+ message: "Choose preferences to enable/disable:",
122
122
  choices,
123
123
  validate: (answer) => {
124
124
  if (answer.length === 0) {
125
- return "Please select at least one preference to toggle";
125
+ return "Please choose at least one preference to toggle";
126
126
  }
127
127
  return true;
128
128
  },
129
129
  });
130
130
 
131
131
  if (!targetIds || targetIds.length === 0) {
132
- return { message: "No preferences selected for toggling." };
132
+ return { message: "No preferences selected to toggle." };
133
133
  }
134
134
  }
135
135
 
@@ -172,7 +172,7 @@ export default async function prefs({ list, remove, toggle, id }, options) {
172
172
  return await togglePreferences(id, options);
173
173
  }
174
174
 
175
- return { message: "Please specify an action: --list, --remove, or --toggle." };
175
+ return { message: "Please choose an action: --list, --remove, or --toggle." };
176
176
  }
177
177
 
178
178
  prefs.input_schema = {
@@ -180,24 +180,24 @@ prefs.input_schema = {
180
180
  properties: {
181
181
  list: {
182
182
  type: "boolean",
183
- description: "List all preferences",
183
+ description: "Show all saved preferences",
184
184
  },
185
185
  remove: {
186
186
  type: "boolean",
187
- description: "Remove preferences",
187
+ description: "Delete saved preferences",
188
188
  },
189
189
  toggle: {
190
190
  type: "boolean",
191
- description: "Toggle preferences active status",
191
+ description: "Enable/disable preferences",
192
192
  },
193
193
  id: {
194
194
  type: "array",
195
195
  items: {
196
196
  type: "string",
197
197
  },
198
- description: "Preference IDs to manage",
198
+ description: "Specific preference IDs to work with",
199
199
  },
200
200
  },
201
201
  };
202
202
 
203
- prefs.description = "Manage user preferences learned from feedback";
203
+ prefs.description = "Manage your saved documentation preferences";