@aigne/doc-smith 0.9.8-alpha.3 → 0.9.8-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +43 -0
- package/README.md +94 -250
- package/aigne.yaml +2 -149
- package/doc-smith/SKILL.md +117 -0
- package/doc-smith/references/changeset_schema.md +118 -0
- package/doc-smith/references/document_structure_schema.md +139 -0
- package/doc-smith/references/document_update_guide.md +193 -0
- package/doc-smith/references/structure_confirmation_guide.md +133 -0
- package/doc-smith/references/structure_planning_guide.md +146 -0
- package/doc-smith/references/user_intent_guide.md +172 -0
- package/doc-smith.yaml +114 -0
- package/main-system-prompt.md +56 -0
- package/package.json +3 -69
- package/scripts/README.md +90 -0
- package/scripts/install.sh +86 -0
- package/scripts/uninstall.sh +52 -0
- package/CHANGELOG.md +0 -994
- package/LICENSE +0 -93
- package/agentic-agents/common/base-info.md +0 -53
- package/agentic-agents/common/completer.md +0 -54
- package/agentic-agents/common/planner.md +0 -168
- package/agentic-agents/common/worker.md +0 -93
- package/agentic-agents/create/index.yaml +0 -129
- package/agentic-agents/create/objective.md +0 -44
- package/agentic-agents/create/set-custom-prompt.mjs +0 -27
- package/agentic-agents/detail/index.yaml +0 -95
- package/agentic-agents/detail/objective.md +0 -9
- package/agentic-agents/detail/set-custom-prompt.mjs +0 -88
- package/agentic-agents/predict-resources/index.yaml +0 -44
- package/agentic-agents/predict-resources/instructions.md +0 -61
- package/agentic-agents/structure/design-rules.md +0 -39
- package/agentic-agents/structure/index.yaml +0 -86
- package/agentic-agents/structure/objective.md +0 -14
- package/agentic-agents/structure/review-criteria.md +0 -55
- package/agentic-agents/structure/set-custom-prompt.mjs +0 -78
- package/agentic-agents/utils/init-workspace-cache.mjs +0 -171
- package/agentic-agents/utils/load-base-sources.mjs +0 -20
- package/agentic-agents/workspace-cache-sharing-design.md +0 -671
- package/agents/chat/chat-system.md +0 -38
- package/agents/chat/index.mjs +0 -59
- package/agents/chat/skills/generate-document.yaml +0 -15
- package/agents/chat/skills/list-documents.mjs +0 -15
- package/agents/chat/skills/update-document.yaml +0 -24
- package/agents/clear/choose-contents.mjs +0 -192
- package/agents/clear/clear-auth-tokens.mjs +0 -88
- package/agents/clear/clear-deployment-config.mjs +0 -49
- package/agents/clear/clear-document-config.mjs +0 -36
- package/agents/clear/clear-document-structure.mjs +0 -102
- package/agents/clear/clear-generated-docs.mjs +0 -142
- package/agents/clear/clear-media-description.mjs +0 -129
- package/agents/clear/index.yaml +0 -26
- package/agents/create/analyze-diagram-type-llm.yaml +0 -160
- package/agents/create/analyze-diagram-type.mjs +0 -297
- package/agents/create/check-document-structure.yaml +0 -30
- package/agents/create/check-need-generate-structure.mjs +0 -105
- package/agents/create/document-structure-tools/add-document.mjs +0 -85
- package/agents/create/document-structure-tools/delete-document.mjs +0 -116
- package/agents/create/document-structure-tools/move-document.mjs +0 -109
- package/agents/create/document-structure-tools/update-document.mjs +0 -84
- package/agents/create/generate-diagram-image.yaml +0 -60
- package/agents/create/generate-structure.yaml +0 -117
- package/agents/create/index.yaml +0 -49
- package/agents/create/refine-document-structure.yaml +0 -12
- package/agents/create/replace-d2-with-image.mjs +0 -625
- package/agents/create/update-document-structure.yaml +0 -54
- package/agents/create/user-add-document/add-documents-to-structure.mjs +0 -90
- package/agents/create/user-add-document/find-documents-to-add-links.yaml +0 -47
- package/agents/create/user-add-document/index.yaml +0 -46
- package/agents/create/user-add-document/prepare-documents-to-translate.mjs +0 -22
- package/agents/create/user-add-document/print-add-document-summary.mjs +0 -63
- package/agents/create/user-add-document/review-documents-with-new-links.mjs +0 -110
- package/agents/create/user-remove-document/find-documents-with-invalid-links.mjs +0 -78
- package/agents/create/user-remove-document/index.yaml +0 -40
- package/agents/create/user-remove-document/prepare-documents-to-translate.mjs +0 -22
- package/agents/create/user-remove-document/print-remove-document-summary.mjs +0 -53
- package/agents/create/user-remove-document/remove-documents-from-structure.mjs +0 -99
- package/agents/create/user-remove-document/review-documents-with-invalid-links.mjs +0 -115
- package/agents/create/user-review-document-structure.mjs +0 -140
- package/agents/create/utils/init-current-content.mjs +0 -34
- package/agents/create/utils/merge-document-structures.mjs +0 -30
- package/agents/evaluate/code-snippet.mjs +0 -97
- package/agents/evaluate/document-structure.yaml +0 -67
- package/agents/evaluate/document.yaml +0 -82
- package/agents/evaluate/generate-report.mjs +0 -85
- package/agents/evaluate/index.yaml +0 -46
- package/agents/history/index.yaml +0 -6
- package/agents/history/view.mjs +0 -78
- package/agents/init/check.mjs +0 -16
- package/agents/init/index.mjs +0 -275
- package/agents/init/validate.mjs +0 -16
- package/agents/localize/choose-language.mjs +0 -107
- package/agents/localize/index.yaml +0 -58
- package/agents/localize/record-translation-history.mjs +0 -23
- package/agents/localize/translate-document.yaml +0 -24
- package/agents/localize/translate-multilingual.yaml +0 -51
- package/agents/media/batch-generate-media-description.yaml +0 -46
- package/agents/media/generate-media-description.yaml +0 -50
- package/agents/media/load-media-description.mjs +0 -256
- package/agents/prefs/index.mjs +0 -203
- package/agents/publish/index.yaml +0 -26
- package/agents/publish/publish-docs.mjs +0 -356
- package/agents/publish/translate-meta.mjs +0 -103
- package/agents/schema/document-structure-item.yaml +0 -26
- package/agents/schema/document-structure-refine-item.yaml +0 -23
- package/agents/schema/document-structure.yaml +0 -29
- package/agents/update/batch-generate-document.yaml +0 -27
- package/agents/update/batch-update-document.yaml +0 -7
- package/agents/update/check-diagram-flag.mjs +0 -116
- package/agents/update/check-document.mjs +0 -162
- package/agents/update/check-generate-diagram.mjs +0 -106
- package/agents/update/check-sync-image-flag.mjs +0 -55
- package/agents/update/check-update-is-single.mjs +0 -53
- package/agents/update/document-tools/update-document-content.mjs +0 -303
- package/agents/update/generate-diagram.yaml +0 -63
- package/agents/update/generate-document.yaml +0 -70
- package/agents/update/handle-document-update.yaml +0 -103
- package/agents/update/index.yaml +0 -79
- package/agents/update/pre-check-generate-diagram.yaml +0 -44
- package/agents/update/save-and-translate-document.mjs +0 -76
- package/agents/update/sync-images-and-exit.mjs +0 -148
- package/agents/update/update-document-detail.yaml +0 -71
- package/agents/update/update-single/update-single-document-detail.mjs +0 -280
- package/agents/update/update-single-document.yaml +0 -7
- package/agents/update/user-review-document.mjs +0 -272
- package/agents/utils/action-success.mjs +0 -16
- package/agents/utils/analyze-document-feedback-intent.yaml +0 -32
- package/agents/utils/analyze-feedback-intent.mjs +0 -136
- package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
- package/agents/utils/check-detail-result.mjs +0 -38
- package/agents/utils/check-feedback-refiner.mjs +0 -81
- package/agents/utils/choose-docs.mjs +0 -293
- package/agents/utils/document-icon-generate.yaml +0 -52
- package/agents/utils/document-title-streamline.yaml +0 -48
- package/agents/utils/ensure-document-icons.mjs +0 -129
- package/agents/utils/exit.mjs +0 -6
- package/agents/utils/feedback-refiner.yaml +0 -50
- package/agents/utils/find-item-by-path.mjs +0 -114
- package/agents/utils/find-user-preferences-by-path.mjs +0 -37
- package/agents/utils/format-document-structure.mjs +0 -35
- package/agents/utils/generate-document-or-skip.mjs +0 -41
- package/agents/utils/handle-diagram-operations.mjs +0 -263
- package/agents/utils/load-all-document-content.mjs +0 -30
- package/agents/utils/load-document-all-content.mjs +0 -84
- package/agents/utils/load-sources.mjs +0 -405
- package/agents/utils/map-reasoning-effort-level.mjs +0 -15
- package/agents/utils/post-generate.mjs +0 -144
- package/agents/utils/read-current-document-content.mjs +0 -46
- package/agents/utils/save-doc-translation.mjs +0 -61
- package/agents/utils/save-doc.mjs +0 -88
- package/agents/utils/save-output.mjs +0 -26
- package/agents/utils/save-sidebar.mjs +0 -51
- package/agents/utils/skip-if-content-exists.mjs +0 -27
- package/agents/utils/streamline-document-titles-if-needed.mjs +0 -88
- package/agents/utils/transform-detail-data-sources.mjs +0 -45
- package/agents/utils/update-branding.mjs +0 -84
- package/assets/report-template/report.html +0 -198
- package/docs-mcp/analyze-content-relevance.yaml +0 -50
- package/docs-mcp/analyze-docs-relevance.yaml +0 -59
- package/docs-mcp/docs-search.yaml +0 -42
- package/docs-mcp/get-docs-detail.mjs +0 -41
- package/docs-mcp/get-docs-structure.mjs +0 -16
- package/docs-mcp/read-doc-content.mjs +0 -119
- package/prompts/common/document/content-rules-core.md +0 -20
- package/prompts/common/document/markdown-syntax-rules.md +0 -65
- package/prompts/common/document/media-file-list-usage-rules.md +0 -18
- package/prompts/common/document/openapi-usage-rules.md +0 -189
- package/prompts/common/document/role-and-personality.md +0 -16
- package/prompts/common/document/user-preferences.md +0 -9
- package/prompts/common/document-structure/conflict-resolution-guidance.md +0 -16
- package/prompts/common/document-structure/document-icon-generate.md +0 -116
- package/prompts/common/document-structure/document-structure-rules.md +0 -43
- package/prompts/common/document-structure/document-title-streamline.md +0 -86
- package/prompts/common/document-structure/glossary.md +0 -7
- package/prompts/common/document-structure/intj-traits.md +0 -5
- package/prompts/common/document-structure/openapi-usage-rules.md +0 -28
- package/prompts/common/document-structure/output-constraints.md +0 -18
- package/prompts/common/document-structure/user-locale-rules.md +0 -10
- package/prompts/common/document-structure/user-preferences.md +0 -9
- package/prompts/detail/custom/admonition-usage-rules.md +0 -94
- package/prompts/detail/custom/code-block-usage-rules.md +0 -163
- package/prompts/detail/custom/custom-components/x-card-usage-rules.md +0 -63
- package/prompts/detail/custom/custom-components/x-cards-usage-rules.md +0 -83
- package/prompts/detail/custom/custom-components/x-field-desc-usage-rules.md +0 -120
- package/prompts/detail/custom/custom-components/x-field-group-usage-rules.md +0 -80
- package/prompts/detail/custom/custom-components/x-field-usage-rules.md +0 -189
- package/prompts/detail/custom/custom-components-usage-rules.md +0 -18
- package/prompts/detail/diagram/generate-image-system.md +0 -135
- package/prompts/detail/diagram/generate-image-user.md +0 -32
- package/prompts/detail/diagram/guide.md +0 -29
- package/prompts/detail/diagram/official-examples.md +0 -712
- package/prompts/detail/diagram/pre-check.md +0 -23
- package/prompts/detail/diagram/role-and-personality.md +0 -2
- package/prompts/detail/diagram/rules.md +0 -46
- package/prompts/detail/diagram/system-prompt.md +0 -1139
- package/prompts/detail/diagram/user-prompt.md +0 -43
- package/prompts/detail/generate/detail-example.md +0 -457
- package/prompts/detail/generate/document-rules.md +0 -45
- package/prompts/detail/generate/system-prompt.md +0 -61
- package/prompts/detail/generate/user-prompt.md +0 -99
- package/prompts/detail/jsx/rules.md +0 -6
- package/prompts/detail/update/system-prompt.md +0 -121
- package/prompts/detail/update/user-prompt.md +0 -41
- package/prompts/evaluate/document-structure.md +0 -93
- package/prompts/evaluate/document.md +0 -149
- package/prompts/media/media-description/system-prompt.md +0 -43
- package/prompts/media/media-description/user-prompt.md +0 -17
- package/prompts/structure/check-document-structure.md +0 -93
- package/prompts/structure/document-rules.md +0 -21
- package/prompts/structure/find-documents-to-add-links.md +0 -52
- package/prompts/structure/generate/system-prompt.md +0 -13
- package/prompts/structure/generate/user-prompt.md +0 -137
- package/prompts/structure/review/structure-review-system.md +0 -81
- package/prompts/structure/structure-example.md +0 -89
- package/prompts/structure/structure-getting-started.md +0 -10
- package/prompts/structure/update/system-prompt.md +0 -93
- package/prompts/structure/update/user-prompt.md +0 -43
- package/prompts/translate/admonition.md +0 -20
- package/prompts/translate/code-block.md +0 -33
- package/prompts/translate/glossary.md +0 -6
- package/prompts/translate/translate-document.md +0 -305
- package/prompts/utils/analyze-document-feedback-intent.md +0 -54
- package/prompts/utils/analyze-structure-feedback-intent.md +0 -43
- package/prompts/utils/feedback-refiner.md +0 -105
- package/types/document-schema.mjs +0 -55
- package/types/document-structure-schema.mjs +0 -261
- package/utils/auth-utils.mjs +0 -275
- package/utils/blocklet.mjs +0 -104
- package/utils/check-document-has-diagram.mjs +0 -95
- package/utils/conflict-detector.mjs +0 -149
- package/utils/constants/index.mjs +0 -620
- package/utils/constants/linter.mjs +0 -102
- package/utils/d2-utils.mjs +0 -198
- package/utils/debug.mjs +0 -3
- package/utils/delete-diagram-images.mjs +0 -99
- package/utils/deploy.mjs +0 -86
- package/utils/docs-finder-utils.mjs +0 -623
- package/utils/evaluate/report-utils.mjs +0 -132
- package/utils/extract-api.mjs +0 -32
- package/utils/file-utils.mjs +0 -960
- package/utils/history-utils.mjs +0 -203
- package/utils/icon-map.mjs +0 -26
- package/utils/image-compress.mjs +0 -75
- package/utils/kroki-utils.mjs +0 -173
- package/utils/linter/index.mjs +0 -50
- package/utils/load-config.mjs +0 -107
- package/utils/markdown/index.mjs +0 -26
- package/utils/markdown-checker.mjs +0 -694
- package/utils/mermaid-validator.mjs +0 -140
- package/utils/mermaid-worker-pool.mjs +0 -250
- package/utils/mermaid-worker.mjs +0 -233
- package/utils/openapi/index.mjs +0 -28
- package/utils/preferences-utils.mjs +0 -175
- package/utils/request.mjs +0 -10
- package/utils/store/index.mjs +0 -45
- package/utils/sync-diagram-to-translations.mjs +0 -262
- package/utils/upload-files.mjs +0 -231
- package/utils/utils.mjs +0 -1354
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import pMap from "p-map";
|
|
2
|
-
import { findItemByPath } from "../../utils/docs-finder-utils.mjs";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Loads all document content from the file system based on the provided document structure.
|
|
6
|
-
*
|
|
7
|
-
* @async
|
|
8
|
-
* @function loadAllDocumentContent
|
|
9
|
-
* @param {Object} params - The parameters object
|
|
10
|
-
* @param {string} params.docsDir - The root directory path where documents are located
|
|
11
|
-
* @param {Array<Object>} params.documentStructure - The document structure array containing items with path information
|
|
12
|
-
* @param {string} params.documentStructure[].path - The file path of each document item
|
|
13
|
-
* @returns {Promise<Array>} returns.allDocumentContentList - An array of document content items loaded from the file system
|
|
14
|
-
* @example
|
|
15
|
-
* const result = await loadAllDocumentContent({
|
|
16
|
-
* docsDir: './docs',
|
|
17
|
-
* documentStructure: [{ path: 'readme.md' }, { path: 'guide.md' }]
|
|
18
|
-
* });
|
|
19
|
-
*/
|
|
20
|
-
export default async function loadAllDocumentContent({ docsDir, documentStructure = [] }) {
|
|
21
|
-
const allDocumentContentList = await pMap(documentStructure, async (item) => {
|
|
22
|
-
const itemResult = await findItemByPath(documentStructure, item.path, null, docsDir);
|
|
23
|
-
return itemResult;
|
|
24
|
-
});
|
|
25
|
-
return {
|
|
26
|
-
allDocumentContentList,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
loadAllDocumentContent.taskRenderMode = "hide";
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { readdirSync } from "node:fs";
|
|
2
|
-
import { findItemByPath, readFileContent } from "../../utils/docs-finder-utils.mjs";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Loads a document's content along with all its translations from the docs directory.
|
|
6
|
-
*
|
|
7
|
-
* This function finds a document by its path in the documentation structure, then searches
|
|
8
|
-
* for all translation files in the docs directory that match the document's naming pattern.
|
|
9
|
-
* Translation files are identified by the pattern: {flatName}.{language-code}.md
|
|
10
|
-
*
|
|
11
|
-
* @param {Object} params - The parameters object
|
|
12
|
-
* @param {string} params.path - The document path to find in the structure
|
|
13
|
-
* @param {string} params.docsDir - The directory containing document files and translations
|
|
14
|
-
* @param {Object} params.documentStructure - The documentation structure object to search in
|
|
15
|
-
* @returns {Promise<Object>} An object containing the document data with translations
|
|
16
|
-
* @throws {Error} Throws an error if the document path is not found in the structure
|
|
17
|
-
*/
|
|
18
|
-
export default async function loadDocumentAllContent({ path, docsDir, documentStructure }) {
|
|
19
|
-
// Find the document item by path in the documentation structure
|
|
20
|
-
const result = await findItemByPath(documentStructure, path, null, docsDir);
|
|
21
|
-
|
|
22
|
-
if (!result) {
|
|
23
|
-
throw new Error(`Document with path "${path}" not found in documentStructure`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Convert path to flat filename format (remove leading slash, replace slashes with dashes)
|
|
27
|
-
// e.g., "/api/users" becomes "api-users"
|
|
28
|
-
const flatName = result.path.replace(/^\//, "").replace(/\//g, "-");
|
|
29
|
-
|
|
30
|
-
// Arrays to store translation data in different formats
|
|
31
|
-
const translations = [];
|
|
32
|
-
const translationsString = [];
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
// Read all files in the docs directory
|
|
36
|
-
const files = readdirSync(docsDir);
|
|
37
|
-
|
|
38
|
-
// Filter files to find translation files matching the pattern:
|
|
39
|
-
// - Starts with the flat name
|
|
40
|
-
// - Ends with .md
|
|
41
|
-
// - Is not the main document file (flatName.md)
|
|
42
|
-
// - Matches language pattern: .{language-code}.md (e.g., .en.md, .zh-CN.md)
|
|
43
|
-
const translationFiles = files.filter(
|
|
44
|
-
(file) =>
|
|
45
|
-
file.startsWith(`${flatName}.`) &&
|
|
46
|
-
file.endsWith(".md") &&
|
|
47
|
-
file !== `${flatName}.md` &&
|
|
48
|
-
file.match(/\.\w+(-\w+)?\.md$/),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// Process each translation file
|
|
52
|
-
for (const file of translationFiles) {
|
|
53
|
-
const content = await readFileContent(docsDir, file);
|
|
54
|
-
if (content) {
|
|
55
|
-
// Extract language code from filename (e.g., "en" from "doc.en.md" or "zh-CN" from "doc.zh-CN.md")
|
|
56
|
-
const langMatch = file.match(/\.(\w+(-\w+)?)\.md$/);
|
|
57
|
-
if (langMatch) {
|
|
58
|
-
const language = langMatch[1];
|
|
59
|
-
// Store translation in structured format
|
|
60
|
-
translations.push({
|
|
61
|
-
language,
|
|
62
|
-
translation: content,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Store translation in XML-like string format for prompt templates
|
|
66
|
-
translationsString.push(`<${language}>\n${content}\n</${language}>`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.warn(`⚠️ Could not read translation files from ${docsDir}:`, error.message);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Return the original document result enhanced with translation data
|
|
75
|
-
return {
|
|
76
|
-
...result,
|
|
77
|
-
// FIXME: @zhanghan use anthoer way to evaluate translationQuality
|
|
78
|
-
// translates: translations, // Array of translation objects with language and content
|
|
79
|
-
translationsString: translationsString.join("\n\n"), // Combined translations as formatted string
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Hide this function from task rendering in the UI
|
|
84
|
-
loadDocumentAllContent.taskRenderMode = "hide";
|
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
import { statSync } from "node:fs";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import imageSize from "image-size";
|
|
5
|
-
import {
|
|
6
|
-
DEFAULT_EXCLUDE_PATTERNS,
|
|
7
|
-
DEFAULT_INCLUDE_PATTERNS,
|
|
8
|
-
INTELLIGENT_SUGGESTION_TOKEN_THRESHOLD,
|
|
9
|
-
} from "../../utils/constants/index.mjs";
|
|
10
|
-
import { loadDocumentStructure } from "../../utils/docs-finder-utils.mjs";
|
|
11
|
-
import {
|
|
12
|
-
buildSourcesContent,
|
|
13
|
-
calculateTokens,
|
|
14
|
-
getMimeType,
|
|
15
|
-
isRemoteFile,
|
|
16
|
-
loadFilesFromPaths,
|
|
17
|
-
readFileContents,
|
|
18
|
-
} from "../../utils/file-utils.mjs";
|
|
19
|
-
import { isOpenAPISpecFile } from "../../utils/openapi/index.mjs";
|
|
20
|
-
import {
|
|
21
|
-
getCurrentGitHead,
|
|
22
|
-
getModifiedFilesBetweenCommits,
|
|
23
|
-
toRelativePath,
|
|
24
|
-
} from "../../utils/utils.mjs";
|
|
25
|
-
|
|
26
|
-
const imageExts = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".heic", ".heif"];
|
|
27
|
-
const videoExts = [
|
|
28
|
-
".mp4",
|
|
29
|
-
".mpeg",
|
|
30
|
-
".mpg",
|
|
31
|
-
".mov",
|
|
32
|
-
".avi",
|
|
33
|
-
".flv",
|
|
34
|
-
".mkv",
|
|
35
|
-
".webm",
|
|
36
|
-
".wmv",
|
|
37
|
-
".m4v",
|
|
38
|
-
".3gpp",
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
export default async function loadSources(
|
|
42
|
-
{
|
|
43
|
-
sources = [],
|
|
44
|
-
sourcesPath = [],
|
|
45
|
-
includePatterns,
|
|
46
|
-
excludePatterns,
|
|
47
|
-
outputDir,
|
|
48
|
-
docsDir,
|
|
49
|
-
"doc-path": docPath,
|
|
50
|
-
boardId,
|
|
51
|
-
useDefaultPatterns = true,
|
|
52
|
-
lastGitHead,
|
|
53
|
-
reset = false,
|
|
54
|
-
media,
|
|
55
|
-
} = {},
|
|
56
|
-
options,
|
|
57
|
-
) {
|
|
58
|
-
let files = Array.isArray(sources) ? [...sources] : [];
|
|
59
|
-
const { minImageWidth } = media || { minImageWidth: 800 };
|
|
60
|
-
|
|
61
|
-
if (sourcesPath) {
|
|
62
|
-
const sourcesPathList = Array.isArray(sourcesPath) ? sourcesPath : [sourcesPath];
|
|
63
|
-
const pickSourcesPath = [];
|
|
64
|
-
const omitSourcesPath = [];
|
|
65
|
-
sourcesPathList.forEach((x) => {
|
|
66
|
-
if (typeof x !== "string" || !x) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (x.startsWith("!")) {
|
|
70
|
-
omitSourcesPath.push(x.substring(1));
|
|
71
|
-
} else {
|
|
72
|
-
pickSourcesPath.push(x);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const customExcludePatterns = omitSourcesPath
|
|
77
|
-
.map((x) => {
|
|
78
|
-
try {
|
|
79
|
-
const stats = statSync(x);
|
|
80
|
-
if (stats.isFile()) {
|
|
81
|
-
return x;
|
|
82
|
-
}
|
|
83
|
-
if (stats.isDirectory()) {
|
|
84
|
-
return `${x}/**`;
|
|
85
|
-
}
|
|
86
|
-
return null;
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.warn(`Failed to stat path ${x}: ${error.message}`);
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
.filter(Boolean);
|
|
93
|
-
const allFiles = await loadFilesFromPaths(pickSourcesPath, {
|
|
94
|
-
includePatterns,
|
|
95
|
-
excludePatterns: [
|
|
96
|
-
...new Set([
|
|
97
|
-
...(excludePatterns || []),
|
|
98
|
-
...customExcludePatterns,
|
|
99
|
-
...videoExts.map((x) => `**/*${x}`),
|
|
100
|
-
]),
|
|
101
|
-
],
|
|
102
|
-
useDefaultPatterns,
|
|
103
|
-
defaultIncludePatterns: DEFAULT_INCLUDE_PATTERNS,
|
|
104
|
-
defaultExcludePatterns: DEFAULT_EXCLUDE_PATTERNS,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
files = files.concat(allFiles);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
files = [...new Set(files)];
|
|
111
|
-
|
|
112
|
-
// Define media file extensions
|
|
113
|
-
const mediaExtensions = [
|
|
114
|
-
...imageExts,
|
|
115
|
-
// ignore video temporary
|
|
116
|
-
// ...videoExts
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
// Separate source files from media files
|
|
120
|
-
const sourceFilesPaths = [];
|
|
121
|
-
const mediaFiles = [];
|
|
122
|
-
|
|
123
|
-
// Helper function to determine file type from extension
|
|
124
|
-
const getFileType = (filePath) => {
|
|
125
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
126
|
-
|
|
127
|
-
if (imageExts.includes(ext)) return "image";
|
|
128
|
-
if (videoExts.includes(ext)) return "video";
|
|
129
|
-
return "media";
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
let filteredImageCount = 0;
|
|
133
|
-
|
|
134
|
-
await Promise.all(
|
|
135
|
-
files.map(async (file) => {
|
|
136
|
-
const ext = path.extname(file).toLowerCase();
|
|
137
|
-
|
|
138
|
-
if (mediaExtensions.includes(ext) && !isRemoteFile(file)) {
|
|
139
|
-
// This is a media file
|
|
140
|
-
const relativePath = path.relative(docsDir, file);
|
|
141
|
-
const fileName = path.basename(file);
|
|
142
|
-
const description = path.parse(fileName).name;
|
|
143
|
-
|
|
144
|
-
const mediaItem = {
|
|
145
|
-
name: fileName,
|
|
146
|
-
path: relativePath,
|
|
147
|
-
type: getFileType(relativePath),
|
|
148
|
-
description,
|
|
149
|
-
mimeType: getMimeType(file),
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
// For image files, get dimensions and filter by width
|
|
153
|
-
if (mediaItem.type === "image") {
|
|
154
|
-
try {
|
|
155
|
-
const buffer = await readFile(file);
|
|
156
|
-
const dimensions = imageSize(buffer);
|
|
157
|
-
mediaItem.width = dimensions.width;
|
|
158
|
-
mediaItem.height = dimensions.height;
|
|
159
|
-
|
|
160
|
-
// Filter out images with width less than minImageWidth, but not SVG images
|
|
161
|
-
if (dimensions.width < minImageWidth && mediaItem.mimeType !== "image/svg+xml") {
|
|
162
|
-
filteredImageCount++;
|
|
163
|
-
console.log(
|
|
164
|
-
`Ignored image: ${fileName} (${dimensions.width}x${dimensions.height}px < ${minImageWidth}px minimum)`,
|
|
165
|
-
);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
} catch (err) {
|
|
169
|
-
console.warn(`⚠️ Failed to get dimensions for ${fileName}: ${err.message}`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
mediaFiles.push(mediaItem);
|
|
174
|
-
} else {
|
|
175
|
-
// This is a source file
|
|
176
|
-
sourceFilesPaths.push(file);
|
|
177
|
-
}
|
|
178
|
-
}),
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
// Log summary of filtered images
|
|
182
|
-
if (filteredImageCount > 0) {
|
|
183
|
-
console.log(
|
|
184
|
-
`\nTotal ${filteredImageCount} low-resolution image(s) filtered for better documentation quality (minimum width: ${minImageWidth}px)\n`,
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Read all source files using the utility function
|
|
189
|
-
let sourceFiles = (await readFileContents(sourceFilesPaths, process.cwd())).map((i) => ({
|
|
190
|
-
...i,
|
|
191
|
-
tokens: calculateTokens(`\n${i.sourceId}\n${i.content}`),
|
|
192
|
-
}));
|
|
193
|
-
|
|
194
|
-
// filter OpenAPI doc should after check isLargeContext
|
|
195
|
-
sourceFiles = sourceFiles.filter((file) => {
|
|
196
|
-
if (options?.context?.userContext.openAPISpec) return true;
|
|
197
|
-
|
|
198
|
-
const isOpenAPI = isOpenAPISpecFile(file.content);
|
|
199
|
-
if (isOpenAPI && options?.context?.userContext) {
|
|
200
|
-
options.context.userContext.openAPISpec = file;
|
|
201
|
-
}
|
|
202
|
-
return !isOpenAPI;
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
const totalTokens = sourceFiles.reduce((sum, file) => sum + file.tokens, 0);
|
|
206
|
-
const totalLines = sourceFiles.reduce(
|
|
207
|
-
(sum, file) => sum + file.content.split("\n").filter(Boolean).length,
|
|
208
|
-
0,
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
const dataSources = splitSourcesToChunks(sourceFiles, INTELLIGENT_SUGGESTION_TOKEN_THRESHOLD).map(
|
|
212
|
-
(i) => ({ dataSourceChunk: buildSourcesContent(i) }),
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
const remoteFileList = [];
|
|
216
|
-
|
|
217
|
-
sourceFiles.forEach((file) => {
|
|
218
|
-
if (isRemoteFile(file.sourceId)) {
|
|
219
|
-
remoteFileList.push(file);
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
if (options?.context?.userContext) {
|
|
223
|
-
options.context.userContext.remoteFileList = remoteFileList;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// all files path
|
|
227
|
-
const allFilesPaths = sourceFiles.map((x) => `- ${toRelativePath(x.sourceId)}`).join("\n");
|
|
228
|
-
|
|
229
|
-
// Get the last documentation structure
|
|
230
|
-
const originalDocumentStructure = await loadDocumentStructure(outputDir);
|
|
231
|
-
|
|
232
|
-
// Get the last output result of the specified path
|
|
233
|
-
let content;
|
|
234
|
-
if (docPath && !reset && docsDir) {
|
|
235
|
-
// First try direct path matching (original format)
|
|
236
|
-
const flatName = docPath.replace(/^\//, "").replace(/\//g, "-");
|
|
237
|
-
const fileFullName = `${flatName}.md`;
|
|
238
|
-
let filePath = path.join(docsDir, fileFullName);
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
content = await readFile(filePath, "utf8");
|
|
242
|
-
} catch (err) {
|
|
243
|
-
if (err.code !== "ENOENT") {
|
|
244
|
-
console.warn(`Error reading document file ${filePath}: ${err.message}`);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// If not found and boardId is provided, try boardId-flattenedPath format
|
|
248
|
-
if (boardId && docPath.startsWith(`${boardId}-`)) {
|
|
249
|
-
// Extract the flattened path part after boardId-
|
|
250
|
-
const flattenedPath = docPath.substring(boardId.length + 1);
|
|
251
|
-
const boardIdFileFullName = `${flattenedPath}.md`;
|
|
252
|
-
filePath = path.join(docsDir, boardIdFileFullName);
|
|
253
|
-
|
|
254
|
-
try {
|
|
255
|
-
content = await readFile(filePath, "utf8");
|
|
256
|
-
} catch (boardIdErr) {
|
|
257
|
-
if (boardIdErr.code !== "ENOENT") {
|
|
258
|
-
console.warn(`Error reading document file ${filePath}: ${boardIdErr.message}`);
|
|
259
|
-
}
|
|
260
|
-
// The file does not exist, content remains undefined
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Get git change detection data
|
|
267
|
-
let modifiedFiles = [];
|
|
268
|
-
let currentGitHead = null;
|
|
269
|
-
|
|
270
|
-
if (lastGitHead) {
|
|
271
|
-
try {
|
|
272
|
-
currentGitHead = getCurrentGitHead();
|
|
273
|
-
if (currentGitHead && currentGitHead !== lastGitHead) {
|
|
274
|
-
modifiedFiles = getModifiedFilesBetweenCommits(lastGitHead, currentGitHead);
|
|
275
|
-
console.log(`Detected ${modifiedFiles.length} modified files since last generation`);
|
|
276
|
-
}
|
|
277
|
-
} catch (error) {
|
|
278
|
-
console.warn("Failed to detect git changes:", error.message);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return {
|
|
283
|
-
dataSources,
|
|
284
|
-
content,
|
|
285
|
-
originalDocumentStructure,
|
|
286
|
-
files,
|
|
287
|
-
modifiedFiles,
|
|
288
|
-
totalTokens,
|
|
289
|
-
totalLines,
|
|
290
|
-
mediaFiles,
|
|
291
|
-
allFilesPaths,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
loadSources.input_schema = {
|
|
296
|
-
type: "object",
|
|
297
|
-
properties: {
|
|
298
|
-
sources: {
|
|
299
|
-
type: "array",
|
|
300
|
-
items: { type: "string" },
|
|
301
|
-
description: "Array of paths to the sources files",
|
|
302
|
-
},
|
|
303
|
-
sourcesPath: {
|
|
304
|
-
anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
|
|
305
|
-
description: "Directory or directories to recursively read files from",
|
|
306
|
-
},
|
|
307
|
-
includePatterns: {
|
|
308
|
-
anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
|
|
309
|
-
description: "Glob patterns to filter files by path or filename. If not set, include all.",
|
|
310
|
-
},
|
|
311
|
-
excludePatterns: {
|
|
312
|
-
anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
|
|
313
|
-
description: "Glob patterns to exclude files by path or filename. If not set, exclude none.",
|
|
314
|
-
},
|
|
315
|
-
useDefaultPatterns: {
|
|
316
|
-
type: "boolean",
|
|
317
|
-
description: "Whether to use default include/exclude patterns. Defaults to true.",
|
|
318
|
-
},
|
|
319
|
-
"doc-path": {
|
|
320
|
-
type: "string",
|
|
321
|
-
description: "The document path to load content for",
|
|
322
|
-
},
|
|
323
|
-
boardId: {
|
|
324
|
-
type: "string",
|
|
325
|
-
description: "The board ID for boardId-flattenedPath format matching",
|
|
326
|
-
},
|
|
327
|
-
lastGitHead: {
|
|
328
|
-
type: "string",
|
|
329
|
-
description: "The git HEAD from last generation for change detection",
|
|
330
|
-
},
|
|
331
|
-
},
|
|
332
|
-
required: [],
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
loadSources.output_schema = {
|
|
336
|
-
type: "object",
|
|
337
|
-
properties: {
|
|
338
|
-
dataSources: {
|
|
339
|
-
type: "array",
|
|
340
|
-
items: {
|
|
341
|
-
type: "object",
|
|
342
|
-
properties: {
|
|
343
|
-
dataSourceChunk: { type: "string" },
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
files: {
|
|
348
|
-
type: "array",
|
|
349
|
-
items: { type: "string" },
|
|
350
|
-
description: "Array of file paths that were loaded",
|
|
351
|
-
},
|
|
352
|
-
modifiedFiles: {
|
|
353
|
-
type: "array",
|
|
354
|
-
items: { type: "string" },
|
|
355
|
-
description: "Array of modified files since last generation",
|
|
356
|
-
},
|
|
357
|
-
mediaFiles: {
|
|
358
|
-
type: "array",
|
|
359
|
-
items: {
|
|
360
|
-
type: "object",
|
|
361
|
-
properties: {
|
|
362
|
-
name: { type: "string" },
|
|
363
|
-
path: { type: "string" },
|
|
364
|
-
type: { type: "string" },
|
|
365
|
-
width: { type: "number" },
|
|
366
|
-
height: { type: "number" },
|
|
367
|
-
mimeType: { type: "string" },
|
|
368
|
-
},
|
|
369
|
-
},
|
|
370
|
-
description: "Array of media file objects (images/videos)",
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
loadSources.task_render_mode = "hide";
|
|
376
|
-
|
|
377
|
-
function splitSourcesToChunks(sources, maxTokens) {
|
|
378
|
-
const chunks = [];
|
|
379
|
-
|
|
380
|
-
let currentChunk = [];
|
|
381
|
-
let currentTokens = 0;
|
|
382
|
-
|
|
383
|
-
for (const source of sources) {
|
|
384
|
-
const sourceTokens = source.tokens;
|
|
385
|
-
|
|
386
|
-
if (currentTokens + sourceTokens > maxTokens) {
|
|
387
|
-
// Start a new chunk
|
|
388
|
-
if (currentChunk.length > 0) {
|
|
389
|
-
chunks.push(currentChunk);
|
|
390
|
-
}
|
|
391
|
-
currentChunk = [source];
|
|
392
|
-
currentTokens = sourceTokens;
|
|
393
|
-
} else {
|
|
394
|
-
// Add to current chunk
|
|
395
|
-
currentChunk.push(source);
|
|
396
|
-
currentTokens += sourceTokens;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (currentChunk.length > 0) {
|
|
401
|
-
chunks.push(currentChunk);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
return chunks;
|
|
405
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_REASONING_EFFORT_LEVEL,
|
|
3
|
-
DEFAULT_REASONING_EFFORT_VALUE,
|
|
4
|
-
REASONING_EFFORT_LEVELS,
|
|
5
|
-
} from "../../utils/constants/index.mjs";
|
|
6
|
-
|
|
7
|
-
export default function mapReasoningEffortLevel({ level }, options) {
|
|
8
|
-
const g =
|
|
9
|
-
REASONING_EFFORT_LEVELS[level] || REASONING_EFFORT_LEVELS[DEFAULT_REASONING_EFFORT_LEVEL];
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
reasoningEffort:
|
|
13
|
-
g[options.context.userContext.thinkingEffort] ?? DEFAULT_REASONING_EFFORT_VALUE,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { readdir, unlink } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { shutdownMermaidWorkerPool } from "../../utils/mermaid-worker-pool.mjs";
|
|
4
|
-
import { getCurrentGitHead, saveGitHeadToConfig } from "../../utils/utils.mjs";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {Object} params
|
|
8
|
-
* @param {Array<{path: string, content: string, title: string}>} params.documentStructure
|
|
9
|
-
* @param {string} params.docsDir
|
|
10
|
-
* @param {Array<string>} [params.translateLanguages] - Translation languages
|
|
11
|
-
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
12
|
-
*/
|
|
13
|
-
export default async function postGenerate({
|
|
14
|
-
documentStructure,
|
|
15
|
-
docsDir,
|
|
16
|
-
translateLanguages = [],
|
|
17
|
-
locale,
|
|
18
|
-
projectInfoMessage,
|
|
19
|
-
isChat,
|
|
20
|
-
feedback,
|
|
21
|
-
}) {
|
|
22
|
-
const _results = [];
|
|
23
|
-
// Save current git HEAD to config.yaml for change detection
|
|
24
|
-
try {
|
|
25
|
-
const gitHead = getCurrentGitHead();
|
|
26
|
-
await saveGitHeadToConfig(gitHead);
|
|
27
|
-
} catch (err) {
|
|
28
|
-
console.warn("Failed to save git HEAD:", err.message);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Clean up invalid .md files that are no longer in the documentation structure
|
|
32
|
-
try {
|
|
33
|
-
await cleanupInvalidFiles(documentStructure, docsDir, translateLanguages, locale);
|
|
34
|
-
} catch (err) {
|
|
35
|
-
console.error("Failed to cleanup invalid .md files:", err.message);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let message = `
|
|
39
|
-
✅ Documentation generated successfully! (\`${documentStructure.length}\` documents → \`${docsDir}\`)
|
|
40
|
-
${projectInfoMessage || ""} `;
|
|
41
|
-
|
|
42
|
-
if (!isChat) {
|
|
43
|
-
message += `
|
|
44
|
-
🚀 Next: Make your documentation live and generate a shareable link, run: \`aigne doc publish\`
|
|
45
|
-
💡 Optional: Update specific document (\`aigne doc update\`) or refine documentation structure (\`aigne doc create\`)
|
|
46
|
-
`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (isChat && feedback) {
|
|
50
|
-
message = `User feedback: ${feedback}
|
|
51
|
-
The documentation structure and relevant documents have been updated according to the user's feedback. All feedback has been fully processed.`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Shutdown mermaid worker pool to ensure clean exit
|
|
55
|
-
try {
|
|
56
|
-
await shutdownMermaidWorkerPool();
|
|
57
|
-
} catch (error) {
|
|
58
|
-
console.warn("Failed to shutdown mermaid worker pool:", error.message);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
message,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Generate filename based on flatName and language
|
|
68
|
-
* @param {string} flatName - Flattened path name
|
|
69
|
-
* @param {string} language - Language code
|
|
70
|
-
* @returns {string} - Generated filename
|
|
71
|
-
*/
|
|
72
|
-
function generateFileName(flatName, language) {
|
|
73
|
-
const isEnglish = language === "en";
|
|
74
|
-
return isEnglish ? `${flatName}.md` : `${flatName}.${language}.md`;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Clean up .md files that are no longer in the documentation structure
|
|
79
|
-
* @param {Array<{path: string, title: string}>} documentStructure
|
|
80
|
-
* @param {string} docsDir
|
|
81
|
-
* @param {Array<string>} translateLanguages
|
|
82
|
-
* @param {string} locale - Main language locale (e.g., 'en', 'zh', 'fr')
|
|
83
|
-
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
84
|
-
*/
|
|
85
|
-
async function cleanupInvalidFiles(documentStructure, docsDir, translateLanguages, locale) {
|
|
86
|
-
const results = [];
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
// Get all .md files in docsDir
|
|
90
|
-
const files = await readdir(docsDir);
|
|
91
|
-
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
92
|
-
|
|
93
|
-
// Generate expected file names from documentation structure
|
|
94
|
-
const expectedFiles = new Set();
|
|
95
|
-
|
|
96
|
-
// Add main document files
|
|
97
|
-
for (const { path } of documentStructure) {
|
|
98
|
-
const flatName = path.replace(/^\//, "").replace(/\//g, "-");
|
|
99
|
-
|
|
100
|
-
// Main language file
|
|
101
|
-
const mainFileName = generateFileName(flatName, locale);
|
|
102
|
-
expectedFiles.add(mainFileName);
|
|
103
|
-
|
|
104
|
-
// Add translation files for each language
|
|
105
|
-
for (const lang of translateLanguages) {
|
|
106
|
-
const translateFileName = generateFileName(flatName, lang);
|
|
107
|
-
expectedFiles.add(translateFileName);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Find files to delete (files that are not in expectedFiles and not _sidebar.md)
|
|
112
|
-
const filesToDelete = mdFiles.filter(
|
|
113
|
-
(file) => !expectedFiles.has(file) && file !== "_sidebar.md",
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// Delete invalid files
|
|
117
|
-
for (const file of filesToDelete) {
|
|
118
|
-
try {
|
|
119
|
-
const filePath = join(docsDir, file);
|
|
120
|
-
await unlink(filePath);
|
|
121
|
-
results.push({
|
|
122
|
-
path: filePath,
|
|
123
|
-
success: true,
|
|
124
|
-
message: `Deleted invalid file: ${file}`,
|
|
125
|
-
});
|
|
126
|
-
} catch (err) {
|
|
127
|
-
console.warn(`Failed to delete invalid file: ${file}, error: ${err.message}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (filesToDelete.length > 0) {
|
|
132
|
-
console.log(`Cleaned up ${filesToDelete.length} invalid .md files from ${docsDir}`);
|
|
133
|
-
}
|
|
134
|
-
} catch (err) {
|
|
135
|
-
// If docsDir doesn't exist or can't be read, that's okay
|
|
136
|
-
if (err.code !== "ENOENT") {
|
|
137
|
-
throw err;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return results;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Generate sidebar content, support nested structure, and the order is consistent with documentStructure
|