@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.
- package/.aigne/doc-smith/output/structure-plan.json +1 -5
- package/CHANGELOG.md +25 -0
- package/README.md +3 -3
- package/agents/{chat.yaml → chat/index.yaml} +7 -7
- package/agents/generate/check-document-structure.yaml +30 -0
- package/agents/{check-structure-plan.mjs → generate/check-need-generate-structure.mjs} +21 -21
- package/agents/generate/generate-structure.yaml +58 -0
- package/agents/{docs-generator.yaml → generate/index.yaml} +15 -16
- package/agents/generate/refine-document-structure.yaml +12 -0
- package/agents/{input-generator.mjs → init/index.mjs} +34 -27
- package/agents/{manage-prefs.mjs → prefs/index.mjs} +16 -16
- package/agents/publish/index.yaml +17 -0
- package/agents/{publish-docs.mjs → publish/publish-docs.mjs} +15 -16
- package/agents/schema/{structure-plan-result.yaml → document-execution-structure.yaml} +3 -3
- package/agents/schema/document-structure.yaml +26 -0
- package/agents/{language-selector.mjs → translate/choose-language.mjs} +5 -5
- package/agents/{retranslate.yaml → translate/index.yaml} +17 -18
- package/agents/translate/translate-document.yaml +32 -0
- package/agents/{batch-translate.yaml → translate/translate-multilingual.yaml} +5 -5
- package/agents/update/batch-generate-document.yaml +19 -0
- package/agents/{check-detail.mjs → update/check-document.mjs} +16 -16
- package/agents/{detail-generator-and-translate.yaml → update/generate-and-translate-document.yaml} +23 -23
- package/agents/update/generate-document.yaml +50 -0
- package/agents/{detail-regenerator.yaml → update/index.yaml} +16 -17
- package/agents/{action-success.mjs → utils/action-success.mjs} +2 -2
- package/agents/{check-detail-result.mjs → utils/check-detail-result.mjs} +3 -3
- package/agents/{check-feedback-refiner.mjs → utils/check-feedback-refiner.mjs} +6 -6
- package/agents/{find-items-by-paths.mjs → utils/choose-docs.mjs} +25 -10
- package/agents/{docs-fs.yaml → utils/docs-fs-actor.yaml} +3 -1
- package/agents/utils/feedback-refiner.yaml +50 -0
- package/agents/{find-item-by-path.mjs → utils/find-item-by-path.mjs} +17 -7
- package/agents/{find-user-preferences-by-path.mjs → utils/find-user-preferences-by-path.mjs} +1 -1
- package/agents/utils/format-document-structure.mjs +25 -0
- package/agents/{load-sources.mjs → utils/load-sources.mjs} +41 -28
- package/agents/{save-docs.mjs → utils/save-docs.mjs} +16 -16
- package/agents/{save-single-doc.mjs → utils/save-single-doc.mjs} +2 -2
- package/agents/{transform-detail-datasources.mjs → utils/transform-detail-datasources.mjs} +1 -1
- package/aigne.yaml +35 -35
- package/docs/cli-reference.md +1 -1
- package/docs/features-generate-documentation.md +1 -1
- package/docs/features-update-and-refine.md +2 -2
- package/docs-mcp/analyze-docs-relevance.yaml +10 -10
- package/docs-mcp/docs-search.yaml +5 -3
- package/package.json +10 -8
- package/prompts/{document → detail/custom}/custom-code-block.md +6 -6
- package/prompts/detail/custom/custom-components.md +172 -0
- package/prompts/{document → detail}/d2-chart/rules.md +95 -1
- package/prompts/{document → detail}/detail-example.md +80 -61
- package/prompts/{document/detail-generator.md → detail/document-rules.md} +4 -8
- package/prompts/{content-detail-generator.md → detail/generate-document.md} +48 -25
- package/prompts/{check-structure-planning-result.md → structure/check-document-structure.md} +23 -17
- package/prompts/{document/structure-planning.md → structure/document-rules.md} +0 -2
- package/prompts/{structure-planning.md → structure/generate-structure.md} +51 -30
- package/prompts/{document → structure}/structure-example.md +2 -2
- package/prompts/{document → structure}/structure-getting-started.md +2 -2
- package/prompts/translate/glossary.md +6 -0
- package/prompts/{translator.md → translate/translate-document.md} +29 -10
- package/prompts/{feedback-refiner.md → utils/feedback-refiner.md} +8 -8
- package/tests/agents/chat/chat.test.mjs +46 -0
- package/tests/agents/generate/check-document-structure.test.mjs +51 -0
- package/tests/agents/generate/check-need-generate-structure.test.mjs +292 -0
- package/tests/agents/generate/generate-structure.test.mjs +51 -0
- package/tests/{input-generator.test.mjs → agents/init/init.test.mjs} +19 -17
- package/tests/agents/prefs/prefs.test.mjs +431 -0
- package/tests/agents/publish/publish-docs.test.mjs +642 -0
- package/tests/agents/translate/choose-language.test.mjs +311 -0
- package/tests/agents/translate/translate-document.test.mjs +51 -0
- package/tests/agents/update/check-document.test.mjs +523 -0
- package/tests/agents/update/generate-document.test.mjs +51 -0
- package/tests/agents/utils/action-success.test.mjs +54 -0
- package/tests/{check-detail-result.test.mjs → agents/utils/check-detail-result.test.mjs} +98 -98
- package/tests/agents/utils/check-feedback-refiner.test.mjs +478 -0
- package/tests/agents/utils/choose-docs.test.mjs +417 -0
- package/tests/agents/utils/exit.test.mjs +70 -0
- package/tests/agents/utils/feedback-refiner.test.mjs +51 -0
- package/tests/agents/utils/find-item-by-path.test.mjs +526 -0
- package/tests/agents/utils/find-user-preferences-by-path.test.mjs +382 -0
- package/tests/agents/utils/format-document-structure.test.mjs +264 -0
- package/tests/agents/utils/fs.test.mjs +267 -0
- package/tests/{load-sources.test.mjs → agents/utils/load-sources.test.mjs} +153 -25
- package/tests/{save-docs.test.mjs → agents/utils/save-docs.test.mjs} +11 -5
- package/tests/agents/utils/save-output.test.mjs +315 -0
- package/tests/agents/utils/save-single-doc.test.mjs +364 -0
- package/tests/agents/utils/transform-detail-datasources.test.mjs +363 -0
- package/tests/utils/auth-utils.test.mjs +358 -0
- package/tests/utils/blocklet.test.mjs +334 -0
- package/tests/{conflict-resolution.test.mjs → utils/conflict-detector.test.mjs} +3 -3
- package/tests/utils/constants.test.mjs +295 -0
- package/tests/utils/d2-utils.test.mjs +423 -0
- package/tests/utils/deploy.test.mjs +365 -0
- package/tests/utils/docs-finder-utils.test.mjs +625 -0
- package/tests/utils/file-utils.test.mjs +213 -0
- package/tests/{kroki-utils.test.mjs → utils/kroki-utils.test.mjs} +2 -2
- package/tests/utils/load-config.test.mjs +141 -0
- package/tests/{mermaid-validation.test.mjs → utils/mermaid-validator.test.mjs} +2 -2
- package/tests/utils/mock-chat-model.mjs +12 -0
- package/tests/{preferences-utils.test.mjs → utils/preferences-utils.test.mjs} +1 -1
- package/tests/{save-value-to-config.test.mjs → utils/save-value-to-config.test.mjs} +61 -4
- package/tests/utils/utils.test.mjs +939 -0
- package/utils/auth-utils.mjs +1 -1
- package/utils/conflict-detector.mjs +1 -1
- package/utils/constants.mjs +5 -3
- package/utils/d2-utils.mjs +194 -0
- package/utils/deploy.mjs +3 -3
- package/utils/docs-finder-utils.mjs +26 -26
- package/utils/icon-map.mjs +26 -0
- package/{agents → utils}/load-config.mjs +2 -18
- package/utils/markdown-checker.mjs +5 -5
- package/agents/batch-docs-detail-generator.yaml +0 -19
- package/agents/check-structure-planning-result.yaml +0 -30
- package/agents/content-detail-generator.yaml +0 -50
- package/agents/feedback-refiner.yaml +0 -52
- package/agents/format-structure-plan.mjs +0 -25
- package/agents/reflective-structure-planner.yaml +0 -12
- package/agents/schema/structure-plan.yaml +0 -26
- package/agents/structure-planning.yaml +0 -58
- package/agents/team-publish-docs.yaml +0 -18
- package/agents/translate.yaml +0 -31
- package/prompts/document/custom-components.md +0 -104
- package/tests/README.md +0 -93
- package/tests/utils.test.mjs +0 -2067
- /package/agents/{exit.mjs → utils/exit.mjs} +0 -0
- /package/agents/{fs.mjs → utils/fs.mjs} +0 -0
- /package/agents/{save-output.mjs → utils/save-output.mjs} +0 -0
- /package/prompts/{document → detail}/d2-chart/official-examples.md +0 -0
- /package/prompts/{document → detail}/jsx/rules.md +0 -0
|
@@ -2,21 +2,20 @@ type: team
|
|
|
2
2
|
name: update
|
|
3
3
|
alias:
|
|
4
4
|
- up
|
|
5
|
-
description:
|
|
5
|
+
description: Update specific documents and their translations
|
|
6
6
|
skills:
|
|
7
|
-
- url:
|
|
7
|
+
- url: ../init/index.mjs
|
|
8
8
|
default_input:
|
|
9
9
|
skipIfExists: true
|
|
10
|
-
-
|
|
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
|
-
'
|
|
19
|
-
'
|
|
17
|
+
'documentStructure': originalDocumentStructure,
|
|
18
|
+
'documentExecutionStructure': $map(originalDocumentStructure, function($item) {
|
|
20
19
|
$merge([
|
|
21
20
|
$item,
|
|
22
21
|
{
|
|
@@ -26,37 +25,37 @@ skills:
|
|
|
26
25
|
})
|
|
27
26
|
}
|
|
28
27
|
])
|
|
29
|
-
-
|
|
30
|
-
-
|
|
28
|
+
- ../utils/choose-docs.mjs
|
|
29
|
+
- ../utils/format-document-structure.mjs
|
|
31
30
|
- type: team
|
|
32
|
-
name:
|
|
31
|
+
name: batchUpdateDocument
|
|
33
32
|
skills:
|
|
34
|
-
-
|
|
33
|
+
- ../update/generate-and-translate-document.yaml
|
|
35
34
|
iterate_on: selectedDocs
|
|
36
35
|
concurrency: 3
|
|
37
|
-
- url:
|
|
36
|
+
- url: ../utils/check-feedback-refiner.mjs
|
|
38
37
|
default_input:
|
|
39
38
|
stage: document_refine
|
|
40
|
-
- url:
|
|
39
|
+
- url: ../utils/action-success.mjs
|
|
41
40
|
default_input:
|
|
42
|
-
action: "
|
|
41
|
+
action: "✅ Documents updated successfully"
|
|
43
42
|
input_schema:
|
|
44
43
|
type: object
|
|
45
44
|
properties:
|
|
46
45
|
glossary:
|
|
47
46
|
type: string
|
|
48
|
-
description: Glossary
|
|
47
|
+
description: Glossary file for consistent terminology (use @filename.md)
|
|
49
48
|
docs:
|
|
50
49
|
type: array
|
|
51
50
|
items:
|
|
52
51
|
type: string
|
|
53
|
-
description:
|
|
52
|
+
description: Documents to update
|
|
54
53
|
feedback:
|
|
55
54
|
type: string
|
|
56
|
-
description:
|
|
55
|
+
description: Tell us what to change in this content
|
|
57
56
|
reset:
|
|
58
57
|
type: boolean
|
|
59
|
-
description:
|
|
58
|
+
description: Start fresh - ignore previous versions
|
|
60
59
|
output_schema:
|
|
61
60
|
type: object
|
|
62
61
|
properties:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { shutdownMermaidWorkerPool } from "
|
|
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
|
|
@@ -9,7 +9,7 @@ export default async function actionSuccess({ action }) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
return {
|
|
12
|
-
message:
|
|
12
|
+
message: `${action}`,
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { checkMarkdown } from "
|
|
1
|
+
import { checkMarkdown } from "../../utils/markdown-checker.mjs";
|
|
2
2
|
|
|
3
|
-
export default async function checkDetailResult({
|
|
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
|
-
|
|
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 "
|
|
2
|
+
import { addPreferenceRule, readPreferences } from "../../utils/preferences-utils.mjs";
|
|
3
3
|
|
|
4
4
|
export default async function checkFeedbackRefiner(
|
|
5
|
-
{ feedback, stage, selectedPaths,
|
|
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 && !
|
|
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 ||
|
|
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
|
-
|
|
63
|
+
documentStructureFeedback: {
|
|
64
64
|
type: "string",
|
|
65
|
-
description: "Feedback from structure
|
|
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 "
|
|
8
|
-
|
|
9
|
-
export default async function
|
|
10
|
-
{
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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
|
|
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(
|
|
97
|
+
throw new Error(
|
|
98
|
+
"None of the specified document paths were found in documentExecutionStructure",
|
|
99
|
+
);
|
|
85
100
|
}
|
|
86
101
|
}
|
|
87
102
|
|
|
@@ -90,7 +105,7 @@ export default async function selectedDocs(
|
|
|
90
105
|
if (!userFeedback) {
|
|
91
106
|
const feedbackMessage = getActionText(
|
|
92
107
|
isTranslate,
|
|
93
|
-
"
|
|
108
|
+
"How should we improve this {action}? (press Enter to skip):",
|
|
94
109
|
);
|
|
95
110
|
|
|
96
111
|
userFeedback = await options.prompts.input({
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
getActionText,
|
|
6
6
|
getMainLanguageFiles,
|
|
7
7
|
readFileContent,
|
|
8
|
-
} from "
|
|
8
|
+
} from "../../utils/docs-finder-utils.mjs";
|
|
9
9
|
|
|
10
10
|
export default async function findItemByPath(
|
|
11
|
-
{ doc,
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
94
|
+
throw new Error(`Item with path "${docPath}" not found in documentExecutionStructure`);
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
// Prompt for feedback if not provided
|
|
@@ -89,7 +99,7 @@ export default async function findItemByPath(
|
|
|
89
99
|
if (!userFeedback) {
|
|
90
100
|
const feedbackMessage = getActionText(
|
|
91
101
|
isTranslate,
|
|
92
|
-
"
|
|
102
|
+
"How should we improve this {action}? (press Enter to skip):",
|
|
93
103
|
);
|
|
94
104
|
|
|
95
105
|
userFeedback = await options.prompts.input({
|
|
@@ -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 {
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS } from "
|
|
4
|
-
import { getFilesWithGlob, loadGitignore } from "
|
|
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 "
|
|
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
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
211
|
-
filePath = path.join(docsDir,
|
|
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
|
-
|
|
302
|
+
originalDocumentStructure,
|
|
290
303
|
files,
|
|
291
304
|
modifiedFiles,
|
|
292
305
|
totalWords,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { readdir, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { shutdownMermaidWorkerPool } from "
|
|
4
|
-
import { getCurrentGitHead, saveGitHeadToConfig } from "
|
|
3
|
+
import { shutdownMermaidWorkerPool } from "../../utils/mermaid-worker-pool.mjs";
|
|
4
|
+
import { getCurrentGitHead, saveGitHeadToConfig } from "../../utils/utils.mjs";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {Object} params
|
|
8
|
-
* @param {Array<{path: string, content: string, title: string}>} params.
|
|
8
|
+
* @param {Array<{path: string, content: string, title: string}>} params.documentStructure
|
|
9
9
|
* @param {string} params.docsDir
|
|
10
10
|
* @param {Array<string>} [params.translateLanguages] - Translation languages
|
|
11
11
|
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
12
12
|
*/
|
|
13
13
|
export default async function saveDocs({
|
|
14
|
-
|
|
14
|
+
documentExecutionStructure: documentStructure,
|
|
15
15
|
docsDir,
|
|
16
16
|
translateLanguages = [],
|
|
17
17
|
locale,
|
|
@@ -28,23 +28,23 @@ export default async function saveDocs({
|
|
|
28
28
|
|
|
29
29
|
// Generate _sidebar.md
|
|
30
30
|
try {
|
|
31
|
-
const sidebar = generateSidebar(
|
|
31
|
+
const sidebar = generateSidebar(documentStructure);
|
|
32
32
|
const sidebarPath = join(docsDir, "_sidebar.md");
|
|
33
33
|
await writeFile(sidebarPath, sidebar, "utf8");
|
|
34
34
|
} catch (err) {
|
|
35
35
|
console.error("Failed to save _sidebar.md:", err.message);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// Clean up invalid .md files that are no longer in the structure
|
|
38
|
+
// Clean up invalid .md files that are no longer in the document structure
|
|
39
39
|
try {
|
|
40
|
-
await cleanupInvalidFiles(
|
|
40
|
+
await cleanupInvalidFiles(documentStructure, docsDir, translateLanguages, locale);
|
|
41
41
|
} catch (err) {
|
|
42
42
|
console.error("Failed to cleanup invalid .md files:", err.message);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const message = `## ✅ Documentation Generated Successfully!
|
|
46
46
|
|
|
47
|
-
Successfully generated **${
|
|
47
|
+
Successfully generated **${documentStructure.length}** documents and saved to:
|
|
48
48
|
\`${docsDir}\`
|
|
49
49
|
${projectInfoMessage || ""}
|
|
50
50
|
### 🚀 Next Steps
|
|
@@ -100,14 +100,14 @@ function generateFileName(flatName, language) {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Clean up .md files that are no longer in the structure
|
|
104
|
-
* @param {Array<{path: string, title: string}>}
|
|
103
|
+
* Clean up .md files that are no longer in the document structure
|
|
104
|
+
* @param {Array<{path: string, title: string}>} documentStructure
|
|
105
105
|
* @param {string} docsDir
|
|
106
106
|
* @param {Array<string>} translateLanguages
|
|
107
107
|
* @param {string} locale - Main language locale (e.g., 'en', 'zh', 'fr')
|
|
108
108
|
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
109
109
|
*/
|
|
110
|
-
async function cleanupInvalidFiles(
|
|
110
|
+
async function cleanupInvalidFiles(documentStructure, docsDir, translateLanguages, locale) {
|
|
111
111
|
const results = [];
|
|
112
112
|
|
|
113
113
|
try {
|
|
@@ -115,11 +115,11 @@ async function cleanupInvalidFiles(structurePlan, docsDir, translateLanguages, l
|
|
|
115
115
|
const files = await readdir(docsDir);
|
|
116
116
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
117
117
|
|
|
118
|
-
// Generate expected file names from structure
|
|
118
|
+
// Generate expected file names from document structure
|
|
119
119
|
const expectedFiles = new Set();
|
|
120
120
|
|
|
121
121
|
// Add main document files
|
|
122
|
-
for (const { path } of
|
|
122
|
+
for (const { path } of documentStructure) {
|
|
123
123
|
const flatName = path.replace(/^\//, "").replace(/\//g, "-");
|
|
124
124
|
|
|
125
125
|
// Main language file
|
|
@@ -166,11 +166,11 @@ async function cleanupInvalidFiles(structurePlan, docsDir, translateLanguages, l
|
|
|
166
166
|
return results;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
// Generate sidebar content, support nested structure, and the order is consistent with
|
|
170
|
-
function generateSidebar(
|
|
169
|
+
// Generate sidebar content, support nested structure, and the order is consistent with documentStructure
|
|
170
|
+
function generateSidebar(documentStructure) {
|
|
171
171
|
// Build tree structure
|
|
172
172
|
const root = {};
|
|
173
|
-
for (const { path, title, parentId } of
|
|
173
|
+
for (const { path, title, parentId } of documentStructure) {
|
|
174
174
|
const relPath = path.replace(/^\//, "");
|
|
175
175
|
const segments = relPath.split("/");
|
|
176
176
|
let node = root;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { shutdownMermaidWorkerPool } from "
|
|
2
|
-
import { saveDocWithTranslations } from "
|
|
1
|
+
import { shutdownMermaidWorkerPool } from "../../utils/mermaid-worker-pool.mjs";
|
|
2
|
+
import { saveDocWithTranslations } from "../../utils/utils.mjs";
|
|
3
3
|
|
|
4
4
|
export default async function saveSingleDoc({
|
|
5
5
|
path,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { normalizePath, toRelativePath } from "
|
|
1
|
+
import { normalizePath, toRelativePath } from "../../utils/utils.mjs";
|
|
2
2
|
|
|
3
3
|
export default function transformDetailDatasources({ sourceIds, datasourcesList }) {
|
|
4
4
|
// Build a map for fast lookup, with path normalization for compatibility
|