@aigne/doc-smith 0.8.6 → 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 (117) hide show
  1. package/.aigne/doc-smith/output/structure-plan.json +1 -5
  2. package/CHANGELOG.md +7 -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} +20 -20
  7. package/agents/{structure-planning.yaml → generate/generate-structure.yaml} +6 -6
  8. package/agents/{docs-generator.yaml → generate/index.yaml} +11 -12
  9. package/agents/generate/refine-document-structure.yaml +12 -0
  10. package/agents/{input-generator.mjs → init/index.mjs} +12 -5
  11. package/agents/{manage-prefs.mjs → prefs/index.mjs} +1 -1
  12. package/agents/{team-publish-docs.yaml → publish/index.yaml} +1 -2
  13. package/agents/{publish-docs.mjs → publish/publish-docs.mjs} +6 -5
  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} +11 -12
  18. package/agents/{translate.yaml → translate/translate-document.yaml} +3 -2
  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} +10 -11
  25. package/agents/{action-success.mjs → utils/action-success.mjs} +1 -1
  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} +24 -9
  29. package/agents/{docs-fs.yaml → utils/docs-fs-actor.yaml} +3 -1
  30. package/agents/{feedback-refiner.yaml → utils/feedback-refiner.yaml} +2 -4
  31. package/agents/{find-item-by-path.mjs → utils/find-item-by-path.mjs} +16 -6
  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-mcp/analyze-docs-relevance.yaml +10 -10
  40. package/docs-mcp/docs-search.yaml +5 -3
  41. package/package.json +10 -8
  42. package/prompts/{document → detail/custom}/custom-code-block.md +6 -6
  43. package/prompts/detail/custom/custom-components.md +172 -0
  44. package/prompts/{document → detail}/d2-chart/rules.md +95 -1
  45. package/prompts/{document → detail}/detail-example.md +80 -61
  46. package/prompts/{document/detail-generator.md → detail/document-rules.md} +4 -8
  47. package/prompts/{content-detail-generator.md → detail/generate-document.md} +48 -25
  48. package/prompts/{check-structure-planning-result.md → structure/check-document-structure.md} +23 -17
  49. package/prompts/{document/structure-planning.md → structure/document-rules.md} +0 -2
  50. package/prompts/{structure-planning.md → structure/generate-structure.md} +51 -30
  51. package/prompts/{document → structure}/structure-example.md +2 -2
  52. package/prompts/{document → structure}/structure-getting-started.md +2 -2
  53. package/prompts/translate/glossary.md +6 -0
  54. package/prompts/{translator.md → translate/translate-document.md} +29 -10
  55. package/prompts/{feedback-refiner.md → utils/feedback-refiner.md} +8 -8
  56. package/tests/agents/chat/chat.test.mjs +46 -0
  57. package/tests/agents/generate/check-document-structure.test.mjs +51 -0
  58. package/tests/agents/generate/check-need-generate-structure.test.mjs +292 -0
  59. package/tests/agents/generate/generate-structure.test.mjs +51 -0
  60. package/tests/{input-generator.test.mjs → agents/init/init.test.mjs} +13 -13
  61. package/tests/agents/prefs/prefs.test.mjs +431 -0
  62. package/tests/agents/publish/publish-docs.test.mjs +642 -0
  63. package/tests/agents/translate/choose-language.test.mjs +311 -0
  64. package/tests/agents/translate/translate-document.test.mjs +51 -0
  65. package/tests/agents/update/check-document.test.mjs +523 -0
  66. package/tests/agents/update/generate-document.test.mjs +51 -0
  67. package/tests/agents/utils/action-success.test.mjs +54 -0
  68. package/tests/{check-detail-result.test.mjs → agents/utils/check-detail-result.test.mjs} +98 -98
  69. package/tests/agents/utils/check-feedback-refiner.test.mjs +478 -0
  70. package/tests/agents/utils/choose-docs.test.mjs +417 -0
  71. package/tests/agents/utils/exit.test.mjs +70 -0
  72. package/tests/agents/utils/feedback-refiner.test.mjs +51 -0
  73. package/tests/agents/utils/find-item-by-path.test.mjs +526 -0
  74. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +382 -0
  75. package/tests/agents/utils/format-document-structure.test.mjs +264 -0
  76. package/tests/agents/utils/fs.test.mjs +267 -0
  77. package/tests/{load-sources.test.mjs → agents/utils/load-sources.test.mjs} +153 -25
  78. package/tests/{save-docs.test.mjs → agents/utils/save-docs.test.mjs} +11 -5
  79. package/tests/agents/utils/save-output.test.mjs +315 -0
  80. package/tests/agents/utils/save-single-doc.test.mjs +364 -0
  81. package/tests/agents/utils/transform-detail-datasources.test.mjs +363 -0
  82. package/tests/utils/auth-utils.test.mjs +358 -0
  83. package/tests/utils/blocklet.test.mjs +334 -0
  84. package/tests/{conflict-resolution.test.mjs → utils/conflict-detector.test.mjs} +3 -3
  85. package/tests/utils/constants.test.mjs +295 -0
  86. package/tests/utils/d2-utils.test.mjs +423 -0
  87. package/tests/{deploy.test.mjs → utils/deploy.test.mjs} +25 -36
  88. package/tests/utils/docs-finder-utils.test.mjs +625 -0
  89. package/tests/utils/file-utils.test.mjs +213 -0
  90. package/tests/{kroki-utils.test.mjs → utils/kroki-utils.test.mjs} +2 -2
  91. package/tests/utils/load-config.test.mjs +141 -0
  92. package/tests/{mermaid-validation.test.mjs → utils/mermaid-validator.test.mjs} +2 -2
  93. package/tests/utils/mock-chat-model.mjs +12 -0
  94. package/tests/{preferences-utils.test.mjs → utils/preferences-utils.test.mjs} +1 -1
  95. package/tests/{save-value-to-config.test.mjs → utils/save-value-to-config.test.mjs} +61 -4
  96. package/tests/utils/utils.test.mjs +939 -0
  97. package/utils/conflict-detector.mjs +1 -1
  98. package/utils/constants.mjs +5 -3
  99. package/utils/d2-utils.mjs +194 -0
  100. package/utils/docs-finder-utils.mjs +26 -26
  101. package/utils/icon-map.mjs +26 -0
  102. package/{agents → utils}/load-config.mjs +2 -18
  103. package/utils/markdown-checker.mjs +5 -5
  104. package/agents/batch-docs-detail-generator.yaml +0 -19
  105. package/agents/check-structure-planning-result.yaml +0 -30
  106. package/agents/content-detail-generator.yaml +0 -50
  107. package/agents/format-structure-plan.mjs +0 -25
  108. package/agents/reflective-structure-planner.yaml +0 -12
  109. package/agents/schema/structure-plan.yaml +0 -26
  110. package/prompts/document/custom-components.md +0 -104
  111. package/tests/README.md +0 -93
  112. package/tests/utils.test.mjs +0 -2067
  113. /package/agents/{exit.mjs → utils/exit.mjs} +0 -0
  114. /package/agents/{fs.mjs → utils/fs.mjs} +0 -0
  115. /package/agents/{save-output.mjs → utils/save-output.mjs} +0 -0
  116. /package/prompts/{document → detail}/d2-chart/official-examples.md +0 -0
  117. /package/prompts/{document → detail}/jsx/rules.md +0 -0
@@ -2,19 +2,19 @@ import { access, readFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { TeamAgent } from "@aigne/core";
5
- import { hasSourceFilesChanged } from "../utils/utils.mjs";
6
- import checkDetailResult from "./check-detail-result.mjs";
5
+ import { hasSourceFilesChanged } from "../../utils/utils.mjs";
6
+ import checkDetailResult from "../utils/check-detail-result.mjs";
7
7
 
8
8
  // Get current script directory
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
 
11
- export default async function checkDetail(
11
+ export default async function checkDocument(
12
12
  {
13
13
  path,
14
14
  docsDir,
15
15
  sourceIds,
16
- originalStructurePlan,
17
- structurePlan,
16
+ originalDocumentStructure,
17
+ documentStructure,
18
18
  modifiedFiles,
19
19
  forceRegenerate,
20
20
  ...rest
@@ -36,11 +36,11 @@ export default async function checkDetail(
36
36
  detailGenerated = false;
37
37
  }
38
38
 
39
- // Check if sourceIds have changed by comparing with original structure plan
39
+ // Check if sourceIds have changed by comparing with original document structure
40
40
  let sourceIdsChanged = false;
41
- if (originalStructurePlan && sourceIds) {
42
- // Find the original node in the structure plan
43
- const originalNode = originalStructurePlan.find((node) => node.path === path);
41
+ if (originalDocumentStructure && sourceIds) {
42
+ // Find the original node in the document structure
43
+ const originalNode = originalDocumentStructure.find((node) => node.path === path);
44
44
 
45
45
  if (originalNode?.sourceIds) {
46
46
  const originalSourceIds = originalNode.sourceIds;
@@ -82,9 +82,9 @@ export default async function checkDetail(
82
82
  // If file exists, check content validation
83
83
  let contentValidationFailed = false;
84
84
  let validationResult = {};
85
- if (detailGenerated && fileContent && structurePlan) {
85
+ if (detailGenerated && fileContent && documentStructure) {
86
86
  validationResult = await checkDetailResult({
87
- structurePlan,
87
+ documentStructure,
88
88
  reviewContent: fileContent,
89
89
  docsDir,
90
90
  });
@@ -111,8 +111,8 @@ export default async function checkDetail(
111
111
  }
112
112
 
113
113
  const teamAgent = TeamAgent.from({
114
- name: "generateDetail",
115
- skills: [options.context.agents["detailGeneratorAndTranslate"]],
114
+ name: "generateDocument",
115
+ skills: [options.context.agents["generateAndTranslateDocument"]],
116
116
  });
117
117
 
118
118
  const result = await options.context.invoke(teamAgent, {
@@ -120,8 +120,8 @@ export default async function checkDetail(
120
120
  docsDir,
121
121
  path,
122
122
  sourceIds,
123
- originalStructurePlan,
124
- structurePlan,
123
+ originalDocumentStructure,
124
+ documentStructure,
125
125
  detailFeedback: contentValidationFailed ? validationResult.detailFeedback : "",
126
126
  });
127
127
 
@@ -133,4 +133,4 @@ export default async function checkDetail(
133
133
  };
134
134
  }
135
135
 
136
- checkDetail.taskTitle = "Check if '{{ title }}' needs regeneration";
136
+ checkDocument.taskTitle = "Check if '{{ title }}' needs generate or update";
@@ -1,16 +1,16 @@
1
1
  type: team
2
- name: detailGeneratorAndTranslate
3
- description: 生成文档详情并翻译
2
+ name: generateAndTranslateDocument
3
+ description: Generate document and translate
4
4
  skills:
5
- - ./transform-detail-datasources.mjs
5
+ - ../utils/transform-detail-datasources.mjs
6
6
  - type: team
7
7
  task_render_mode: collapse
8
- name: detailGenerate
8
+ name: generateDocumentContent
9
9
  skills:
10
- - url: ./find-user-preferences-by-path.mjs
10
+ - url: ../utils/find-user-preferences-by-path.mjs
11
11
  default_input:
12
12
  scope: document
13
- - ./content-detail-generator.yaml
13
+ - ../update/generate-document.yaml
14
14
  - type: transform
15
15
  jsonata: |
16
16
  $merge([
@@ -18,11 +18,11 @@ skills:
18
18
  { "reviewContent": content }
19
19
  ])
20
20
  reflection:
21
- reviewer: ./check-detail-result.mjs
21
+ reviewer: ../utils/check-detail-result.mjs
22
22
  is_approved: isApproved
23
23
  max_iterations: 5
24
24
  return_last_on_max_iterations: true
25
- task_title: Generate detail for '{{ title }}'
25
+ task_title: Generate document for '{{ title }}'
26
26
  - type: transform
27
27
  task_render_mode: hide
28
28
  jsonata: |
@@ -30,63 +30,63 @@ skills:
30
30
  $,
31
31
  { "feedback": "" }
32
32
  ])
33
- - ./batch-translate.yaml
34
- - ./save-single-doc.mjs
33
+ - ../translate/translate-multilingual.yaml
34
+ - ../utils/save-single-doc.mjs
35
35
  input_schema:
36
36
  type: object
37
37
  properties:
38
38
  nodeName:
39
39
  type: string
40
- description: 节点名称
40
+ description: Node name
41
41
  default: Section
42
42
  locale:
43
43
  type: string
44
- description: 语言
44
+ description: Language
45
45
  targetAudience:
46
46
  type: string
47
- description: 目标受众
47
+ description: Target audience
48
48
  glossary:
49
49
  type: string
50
- description: 术语表
50
+ description: Glossary
51
51
  doc-path:
52
52
  type: string
53
- description: 当前路径
53
+ description: Current path
54
54
  feedback:
55
55
  type: string
56
- description: 反馈
56
+ description: Feedback
57
57
  sources:
58
58
  type: array
59
59
  items:
60
60
  type: string
61
- description: 源码路径
61
+ description: Source code path
62
62
  sourcesPath:
63
63
  type: array
64
64
  items:
65
65
  type: string
66
- description: 源码路径
66
+ description: Source code path
67
67
  default:
68
68
  - ./
69
69
  includePatterns:
70
70
  type: array
71
71
  items:
72
72
  type: string
73
- description: 包含的文件名
73
+ description: Included file names
74
74
  excludePatterns:
75
75
  type: array
76
76
  items:
77
77
  type: string
78
- description: 排除的文件名
78
+ description: Excluded file names
79
79
  outputDir:
80
80
  type: string
81
- description: 输出目录
81
+ description: Output directory
82
82
  default: ./aigne-docs/output
83
83
  docsDir:
84
84
  type: string
85
- description: 文档目录
85
+ description: Documentation directory
86
86
  default: ./aigne-docs/docs
87
87
  additionalInformation:
88
88
  type: string
89
- description: 额外补充信息
89
+ description: Additional information
90
90
  output_schema:
91
91
  type: object
92
92
  properties:
@@ -0,0 +1,50 @@
1
+ name: generateDocument
2
+ description: Comprehensive content generator for documentation that creates detailed, high-quality document content from various data sources with intelligent analysis.
3
+ instructions:
4
+ url: ../../prompts/detail/generate-document.md
5
+ input_schema:
6
+ type: object
7
+ properties:
8
+ rules:
9
+ type: string
10
+ description: User's content generation rules and requirements
11
+ locale:
12
+ type: string
13
+ description: User language, such as zh, en
14
+ datasources:
15
+ type: string
16
+ description: Source data and context for document content generation
17
+ targetAudience:
18
+ type: string
19
+ description: Target audience for document content
20
+ nodeName:
21
+ type: string
22
+ description: Document node name for content generation
23
+ originalDocumentStructure: ../schema/document-structure.yaml
24
+ title:
25
+ type: string
26
+ description:
27
+ type: string
28
+ path:
29
+ type: string
30
+ parentId:
31
+ type:
32
+ - string
33
+ - "null"
34
+ glossary:
35
+ type: string
36
+ description: Glossary
37
+ additionalInformation:
38
+ type: string
39
+ description: Additional supplementary information
40
+ required:
41
+ - rules
42
+ - datasources
43
+ - originalDocumentStructure
44
+ output_schema:
45
+ type: object
46
+ properties:
47
+ content:
48
+ type: string
49
+ required:
50
+ - content
@@ -4,19 +4,18 @@ alias:
4
4
  - up
5
5
  description: Update specific documents and their translations
6
6
  skills:
7
- - url: ./input-generator.mjs
7
+ - url: ../init/index.mjs
8
8
  default_input:
9
9
  skipIfExists: true
10
- - ./load-config.mjs
11
- - ./load-sources.mjs
10
+ - ../utils/load-sources.mjs
12
11
  - type: transform
13
12
  task_render_mode: hide
14
13
  jsonata: |
15
14
  $merge([
16
15
  $,
17
16
  {
18
- 'structurePlan': originalStructurePlan,
19
- 'structurePlanResult': $map(originalStructurePlan, function($item) {
17
+ 'documentStructure': originalDocumentStructure,
18
+ 'documentExecutionStructure': $map(originalDocumentStructure, function($item) {
20
19
  $merge([
21
20
  $item,
22
21
  {
@@ -26,18 +25,18 @@ skills:
26
25
  })
27
26
  }
28
27
  ])
29
- - ./find-items-by-paths.mjs
30
- - ./format-structure-plan.mjs
28
+ - ../utils/choose-docs.mjs
29
+ - ../utils/format-document-structure.mjs
31
30
  - type: team
32
- name: batchDocsUpdate
31
+ name: batchUpdateDocument
33
32
  skills:
34
- - ./detail-generator-and-translate.yaml
33
+ - ../update/generate-and-translate-document.yaml
35
34
  iterate_on: selectedDocs
36
35
  concurrency: 3
37
- - url: ./check-feedback-refiner.mjs
36
+ - url: ../utils/check-feedback-refiner.mjs
38
37
  default_input:
39
38
  stage: document_refine
40
- - url: ./action-success.mjs
39
+ - url: ../utils/action-success.mjs
41
40
  default_input:
42
41
  action: "✅ Documents updated successfully"
43
42
  input_schema:
@@ -1,4 +1,4 @@
1
- import { shutdownMermaidWorkerPool } from "../utils/mermaid-worker-pool.mjs";
1
+ import { shutdownMermaidWorkerPool } from "../../utils/mermaid-worker-pool.mjs";
2
2
 
3
3
  export default async function actionSuccess({ action }) {
4
4
  // Shutdown mermaid worker pool to ensure clean exit
@@ -1,6 +1,6 @@
1
- import { checkMarkdown } from "../utils/markdown-checker.mjs";
1
+ import { checkMarkdown } from "../../utils/markdown-checker.mjs";
2
2
 
3
- export default async function checkDetailResult({ structurePlan, reviewContent, docsDir }) {
3
+ export default async function checkDetailResult({ documentStructure, reviewContent, docsDir }) {
4
4
  if (!reviewContent || reviewContent.trim() === "") {
5
5
  return {
6
6
  isApproved: false,
@@ -13,7 +13,7 @@ export default async function checkDetailResult({ structurePlan, reviewContent,
13
13
 
14
14
  // Create a set of allowed links, including both original paths and processed .md paths
15
15
  const allowedLinks = new Set();
16
- structurePlan.forEach((item) => {
16
+ documentStructure.forEach((item) => {
17
17
  // Add original path
18
18
  allowedLinks.add(item.path);
19
19
 
@@ -1,12 +1,12 @@
1
1
  import { stringify } from "yaml";
2
- import { addPreferenceRule, readPreferences } from "../utils/preferences-utils.mjs";
2
+ import { addPreferenceRule, readPreferences } from "../../utils/preferences-utils.mjs";
3
3
 
4
4
  export default async function checkFeedbackRefiner(
5
- { feedback, stage, selectedPaths, structurePlanFeedback },
5
+ { feedback, stage, selectedPaths, documentStructureFeedback },
6
6
  options,
7
7
  ) {
8
8
  // If feedback is empty, no need to save user preferences
9
- if (!feedback && !structurePlanFeedback) {
9
+ if (!feedback && !documentStructureFeedback) {
10
10
  return {};
11
11
  }
12
12
 
@@ -18,7 +18,7 @@ export default async function checkFeedbackRefiner(
18
18
  const activePreferencesYaml =
19
19
  activePreferences.length > 0 ? stringify({ rules: activePreferences }, { indent: 2 }) : "";
20
20
 
21
- const feedbackToUse = feedback || structurePlanFeedback;
21
+ const feedbackToUse = feedback || documentStructureFeedback;
22
22
  const result = await options.context.invoke(options.context.agents["feedbackRefiner"], {
23
23
  feedback: feedbackToUse,
24
24
  stage,
@@ -60,9 +60,9 @@ checkFeedbackRefiner.input_schema = {
60
60
  type: "string",
61
61
  description: "User feedback to refine",
62
62
  },
63
- structurePlanFeedback: {
63
+ documentStructureFeedback: {
64
64
  type: "string",
65
- description: "Feedback from structure planning stage",
65
+ description: "Feedback from document structure stage",
66
66
  },
67
67
  stage: {
68
68
  type: "string",
@@ -4,10 +4,19 @@ import {
4
4
  getActionText,
5
5
  getMainLanguageFiles,
6
6
  processSelectedFiles,
7
- } from "../utils/docs-finder-utils.mjs";
8
-
9
- export default async function selectedDocs(
10
- { docs, structurePlanResult, boardId, docsDir, isTranslate, feedback, locale, reset = false },
7
+ } from "../../utils/docs-finder-utils.mjs";
8
+
9
+ export default async function chooseDocs(
10
+ {
11
+ docs,
12
+ documentExecutionStructure,
13
+ boardId,
14
+ docsDir,
15
+ isTranslate,
16
+ feedback,
17
+ locale,
18
+ reset = false,
19
+ },
11
20
  options,
12
21
  ) {
13
22
  let foundItems = [];
@@ -17,7 +26,11 @@ export default async function selectedDocs(
17
26
  if (!docs || docs.length === 0) {
18
27
  try {
19
28
  // Get all main language .md files in docsDir
20
- const mainLanguageFiles = await getMainLanguageFiles(docsDir, locale, structurePlanResult);
29
+ const mainLanguageFiles = await getMainLanguageFiles(
30
+ docsDir,
31
+ locale,
32
+ documentExecutionStructure,
33
+ );
21
34
 
22
35
  if (mainLanguageFiles.length === 0) {
23
36
  throw new Error("No documents found in the docs directory");
@@ -49,7 +62,7 @@ export default async function selectedDocs(
49
62
  }
50
63
 
51
64
  // Process selected files and convert to found items
52
- foundItems = await processSelectedFiles(selectedFiles, structurePlanResult, docsDir);
65
+ foundItems = await processSelectedFiles(selectedFiles, documentExecutionStructure, docsDir);
53
66
  } catch (error) {
54
67
  console.error(error);
55
68
  throw new Error(
@@ -63,7 +76,7 @@ export default async function selectedDocs(
63
76
  // Process the provided docs array
64
77
  for (const docPath of docs) {
65
78
  const foundItem = await findItemByPath(
66
- structurePlanResult,
79
+ documentExecutionStructure,
67
80
  docPath,
68
81
  boardId,
69
82
  docsDir,
@@ -71,7 +84,7 @@ export default async function selectedDocs(
71
84
  );
72
85
 
73
86
  if (!foundItem) {
74
- console.warn(`⚠️ Item with path "${docPath}" not found in structurePlanResult`);
87
+ console.warn(`⚠️ Item with path "${docPath}" not found in documentExecutionStructure`);
75
88
  continue;
76
89
  }
77
90
 
@@ -81,7 +94,9 @@ export default async function selectedDocs(
81
94
  }
82
95
 
83
96
  if (foundItems.length === 0) {
84
- throw new Error("None of the specified document paths were found in structurePlanResult");
97
+ throw new Error(
98
+ "None of the specified document paths were found in documentExecutionStructure",
99
+ );
85
100
  }
86
101
  }
87
102
 
@@ -2,7 +2,9 @@ type: team
2
2
  name: docs_fs_actor
3
3
  description: File system operations for documentation management
4
4
  skills:
5
- - ./load-config.mjs
5
+ - url: ../init/index.mjs
6
+ default_input:
7
+ skipIfExists: true
6
8
  - url: ./fs.mjs
7
9
  default_input:
8
10
  rootDir:
@@ -1,9 +1,7 @@
1
1
  name: feedbackRefiner
2
2
  description: Learn from your feedback to improve future documentation
3
-
4
- # The instructions file contains the core logic (the prompt) for this Agent.
5
3
  instructions:
6
- url: ../prompts/feedback-refiner.md
4
+ url: ../../prompts/utils/feedback-refiner.md
7
5
 
8
6
  input_schema:
9
7
  type: object
@@ -13,7 +11,7 @@ input_schema:
13
11
  description: Tell us what you think about the documentation
14
12
  stage:
15
13
  type: string
16
- description: Which part of the process this feedback is about (structure_planning, document_refine, translation_refine)
14
+ description: Which part of the process this feedback is about (document_structure, document_refine, translation_refine)
17
15
  paths:
18
16
  type: array
19
17
  items:
@@ -5,10 +5,10 @@ import {
5
5
  getActionText,
6
6
  getMainLanguageFiles,
7
7
  readFileContent,
8
- } from "../utils/docs-finder-utils.mjs";
8
+ } from "../../utils/docs-finder-utils.mjs";
9
9
 
10
10
  export default async function findItemByPath(
11
- { doc, structurePlanResult, boardId, docsDir, isTranslate, feedback, locale },
11
+ { doc, documentExecutionStructure, boardId, docsDir, isTranslate, feedback, locale },
12
12
  options,
13
13
  ) {
14
14
  let foundItem = null;
@@ -19,7 +19,11 @@ export default async function findItemByPath(
19
19
  if (!docPath) {
20
20
  try {
21
21
  // Get all main language .md files in docsDir
22
- const mainLanguageFiles = await getMainLanguageFiles(docsDir, locale, structurePlanResult);
22
+ const mainLanguageFiles = await getMainLanguageFiles(
23
+ docsDir,
24
+ locale,
25
+ documentExecutionStructure,
26
+ );
23
27
 
24
28
  if (mainLanguageFiles.length === 0) {
25
29
  throw new Error("No documents found in the docs directory");
@@ -59,7 +63,7 @@ export default async function findItemByPath(
59
63
  const flatName = fileNameToFlatPath(selectedFile);
60
64
 
61
65
  // Try to find matching item by comparing flattened paths
62
- const foundItemByFile = findItemByFlatName(structurePlanResult, flatName);
66
+ const foundItemByFile = findItemByFlatName(documentExecutionStructure, flatName);
63
67
 
64
68
  if (!foundItemByFile) {
65
69
  throw new Error("No document found");
@@ -78,10 +82,16 @@ export default async function findItemByPath(
78
82
  }
79
83
 
80
84
  // Use the utility function to find item and read content
81
- foundItem = await findItemByPathUtil(structurePlanResult, docPath, boardId, docsDir, locale);
85
+ foundItem = await findItemByPathUtil(
86
+ documentExecutionStructure,
87
+ docPath,
88
+ boardId,
89
+ docsDir,
90
+ locale,
91
+ );
82
92
 
83
93
  if (!foundItem) {
84
- throw new Error(`Item with path "${docPath}" not found in structurePlanResult`);
94
+ throw new Error(`Item with path "${docPath}" not found in documentExecutionStructure`);
85
95
  }
86
96
 
87
97
  // Prompt for feedback if not provided
@@ -1,4 +1,4 @@
1
- import { getActiveRulesForScope } from "../utils/preferences-utils.mjs";
1
+ import { getActiveRulesForScope } from "../../utils/preferences-utils.mjs";
2
2
 
3
3
  export default async function findUserPreferencesByPath({ path, scope }) {
4
4
  // Get global rules (always applicable)
@@ -0,0 +1,25 @@
1
+ import { stringify } from "yaml";
2
+
3
+ export default async function formatDocumentStructure({ documentStructure }) {
4
+ // Extract required fields from each item in documentStructure
5
+ const formattedData = documentStructure.map((item) => ({
6
+ title: item.title,
7
+ path: item.path,
8
+ parentId: item.parentId,
9
+ description: item.description,
10
+ }));
11
+
12
+ // Convert to YAML string
13
+ const yamlString = stringify(formattedData, {
14
+ indent: 2,
15
+ lineWidth: 120,
16
+ minContentWidth: 20,
17
+ });
18
+
19
+ return {
20
+ documentStructureYaml: yamlString,
21
+ documentStructure,
22
+ };
23
+ }
24
+
25
+ formatDocumentStructure.task_render_mode = "hide";
@@ -1,12 +1,12 @@
1
- import { access, readFile, stat } from "node:fs/promises";
1
+ import { readFile, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS } from "../utils/constants.mjs";
4
- import { getFilesWithGlob, loadGitignore } from "../utils/file-utils.mjs";
3
+ import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS } from "../../utils/constants.mjs";
4
+ import { getFilesWithGlob, loadGitignore } from "../../utils/file-utils.mjs";
5
5
  import {
6
6
  getCurrentGitHead,
7
7
  getModifiedFilesBetweenCommits,
8
8
  isGlobPattern,
9
- } from "../utils/utils.mjs";
9
+ } from "../../utils/utils.mjs";
10
10
 
11
11
  export default async function loadSources({
12
12
  sources = [],
@@ -172,48 +172,61 @@ export default async function loadSources({
172
172
  }),
173
173
  );
174
174
 
175
- // Get the last structure plan result
176
- let originalStructurePlan;
177
- const structurePlanPath = path.join(outputDir, "structure-plan.json");
178
- try {
179
- await access(structurePlanPath);
180
- const structurePlanResult = await readFile(structurePlanPath, "utf8");
181
- if (structurePlanResult) {
182
- try {
183
- originalStructurePlan = JSON.parse(structurePlanResult);
184
- } catch (err) {
185
- console.error(`Failed to parse structure-plan.json: ${err.message}`);
175
+ // Get the last document structure
176
+ let originalDocumentStructure;
177
+ if (outputDir) {
178
+ const documentStructurePath = path.join(outputDir, "structure-plan.json");
179
+ try {
180
+ const documentExecutionStructure = await readFile(documentStructurePath, "utf8");
181
+ if (documentExecutionStructure?.trim()) {
182
+ try {
183
+ // Validate that the content looks like JSON before parsing
184
+ const trimmedContent = documentExecutionStructure.trim();
185
+ if (trimmedContent.startsWith("{") || trimmedContent.startsWith("[")) {
186
+ originalDocumentStructure = JSON.parse(documentExecutionStructure);
187
+ } else {
188
+ console.warn(`structure-plan.json contains non-JSON content, skipping parse`);
189
+ }
190
+ } catch (err) {
191
+ console.error(`Failed to parse structure-plan.json: ${err.message}`);
192
+ }
193
+ }
194
+ } catch (err) {
195
+ if (err.code !== "ENOENT") {
196
+ console.warn(`Error reading structure-plan.json: ${err.message}`);
186
197
  }
198
+ // The file does not exist or is not readable, originalDocumentStructure remains undefined
187
199
  }
188
- } catch {
189
- // The file does not exist, originalStructurePlan remains undefined
190
200
  }
191
201
 
192
202
  // Get the last output result of the specified path
193
203
  let content;
194
- if (docPath && !reset) {
195
- let fileFullName;
196
-
204
+ if (docPath && !reset && docsDir) {
197
205
  // First try direct path matching (original format)
198
206
  const flatName = docPath.replace(/^\//, "").replace(/\//g, "-");
199
- fileFullName = `${flatName}.md`;
207
+ const fileFullName = `${flatName}.md`;
200
208
  let filePath = path.join(docsDir, fileFullName);
201
209
 
202
210
  try {
203
- await access(filePath);
204
211
  content = await readFile(filePath, "utf8");
205
- } catch {
212
+ } catch (err) {
213
+ if (err.code !== "ENOENT") {
214
+ console.warn(`Error reading document file ${filePath}: ${err.message}`);
215
+ }
216
+
206
217
  // If not found and boardId is provided, try boardId-flattenedPath format
207
218
  if (boardId && docPath.startsWith(`${boardId}-`)) {
208
219
  // Extract the flattened path part after boardId-
209
220
  const flattenedPath = docPath.substring(boardId.length + 1);
210
- fileFullName = `${flattenedPath}.md`;
211
- filePath = path.join(docsDir, fileFullName);
221
+ const boardIdFileFullName = `${flattenedPath}.md`;
222
+ filePath = path.join(docsDir, boardIdFileFullName);
212
223
 
213
224
  try {
214
- await access(filePath);
215
225
  content = await readFile(filePath, "utf8");
216
- } catch {
226
+ } catch (boardIdErr) {
227
+ if (boardIdErr.code !== "ENOENT") {
228
+ console.warn(`Error reading document file ${filePath}: ${boardIdErr.message}`);
229
+ }
217
230
  // The file does not exist, content remains undefined
218
231
  }
219
232
  }
@@ -286,7 +299,7 @@ export default async function loadSources({
286
299
  datasourcesList: sourceFiles,
287
300
  datasources: allSources,
288
301
  content,
289
- originalStructurePlan,
302
+ originalDocumentStructure,
290
303
  files,
291
304
  modifiedFiles,
292
305
  totalWords,