@aigne/doc-smith 0.9.10 → 0.9.11-beta
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/CHANGELOG.md +12 -0
- package/README.md +189 -219
- package/README.zh.md +270 -0
- package/agents/bash-executor/index.mjs +347 -0
- package/agents/clear/ai/intent.md +142 -0
- package/agents/clear/choose-contents.mjs +13 -65
- package/agents/clear/clear-auth-tokens.mjs +17 -21
- package/agents/clear/clear-deployment-config.mjs +33 -24
- package/agents/clear/index.yaml +1 -9
- package/agents/content-checker/ai/intent.md +209 -0
- package/agents/content-checker/clean-invalid-docs.mjs +254 -0
- package/agents/content-checker/index.mjs +191 -0
- package/agents/content-checker/validate-content.mjs +983 -0
- package/agents/generate-images/generate-image.yaml +75 -0
- package/agents/generate-images/generate-summary.mjs +213 -0
- package/agents/generate-images/index.yaml +39 -0
- package/agents/generate-images/prepare-generation.mjs +286 -0
- package/agents/generate-images/prepare-image-generation.mjs +130 -0
- package/{prompts/detail/diagram/generate-image-system.md → agents/generate-images/prompts/system.md} +22 -56
- package/agents/generate-images/prompts/user.md +85 -0
- package/agents/generate-images/save-image-result.mjs +247 -0
- package/agents/generate-images/scan-image-slots.mjs +247 -0
- package/agents/localize/index.yaml +19 -42
- package/{prompts/translate → agents/localize/prompts}/translate-document.md +0 -139
- package/agents/localize/translate-documents/generate-summary.mjs +163 -0
- package/agents/localize/translate-documents/load-glossary.mjs +52 -0
- package/agents/localize/translate-documents/prepare-translation.mjs +249 -0
- package/agents/localize/translate-documents/save-translation.mjs +171 -0
- package/agents/localize/translate-documents/translate-document-to-language.mjs +209 -0
- package/agents/localize/translate-documents/translate-document.yaml +23 -0
- package/agents/localize/translate-documents/translate-to-languages.yaml +10 -0
- package/agents/localize/translate-images/check-image-translation.mjs +225 -0
- package/agents/localize/translate-images/detect-text/detect-and-update-shared.mjs +148 -0
- package/agents/localize/translate-images/detect-text/detect-image-text.yaml +44 -0
- package/agents/localize/translate-images/detect-text/detect-images-text.yaml +21 -0
- package/agents/localize/translate-images/detect-text/prompts/detect-image-text-system.md +43 -0
- package/agents/localize/translate-images/detect-text/prompts/detect-image-text-user.md +14 -0
- package/agents/localize/translate-images/detect-text/save-text-detection.mjs +105 -0
- package/agents/localize/translate-images/prepare-image-input.mjs +124 -0
- package/agents/localize/translate-images/save-image-translation.mjs +172 -0
- package/agents/localize/translate-images/scan-doc-images.mjs +165 -0
- package/agents/localize/translate-images/translate-doc-images.yaml +24 -0
- package/agents/localize/{translate-diagram.yaml → translate-images/translate-image.yaml} +25 -14
- package/agents/publish/ai/intent.md +182 -0
- package/agents/publish/check.mjs +107 -0
- package/agents/publish/index.yaml +9 -14
- package/agents/publish/publish-docs.mjs +81 -61
- package/agents/publish/translate-meta.mjs +79 -58
- package/agents/save-document/index.mjs +260 -0
- package/agents/structure-checker/index.mjs +307 -0
- package/agents/structure-checker/validate-structure.mjs +477 -0
- package/agents/update-image/analyze-feedback.yaml +37 -0
- package/agents/update-image/index.yaml +78 -0
- package/agents/update-image/load-existing-image.mjs +211 -0
- package/agents/update-image/prompts/analyze-feedback-system.md +43 -0
- package/agents/update-image/prompts/analyze-feedback-user.md +15 -0
- package/aigne.yaml +26 -139
- package/package.json +16 -48
- package/scripts/README.md +90 -0
- package/scripts/install.sh +86 -0
- package/scripts/uninstall.sh +52 -0
- package/skills/doc-smith/SKILL.md +285 -0
- package/skills/doc-smith/ai/intent/sources-improve.md +290 -0
- package/skills/doc-smith/references/changeset-guide.md +171 -0
- package/skills/doc-smith/references/document-content-guide.md +214 -0
- package/skills/doc-smith/references/document-structure-schema.md +138 -0
- package/skills/doc-smith/references/patch-guide.md +96 -0
- package/skills/doc-smith/references/structure-confirmation-guide.md +133 -0
- package/skills/doc-smith/references/structure-planning-guide.md +149 -0
- package/skills/doc-smith/references/update-workflow.md +108 -0
- package/skills/doc-smith/references/user-intent-guide.md +175 -0
- package/skills/doc-smith/references/workspace-initialization.md +376 -0
- package/skills/doc-smith-docs-detail/SKILL.md +356 -0
- package/skills/doc-smith-docs-detail/ai/intent.md +271 -0
- package/skills-entry/doc-smith/ai/intent.md +260 -0
- package/skills-entry/doc-smith/index.mjs +66 -0
- package/skills-entry/doc-smith/prompt.md +57 -0
- package/skills-entry/doc-smith/utils.mjs +27 -0
- package/skills-entry/doc-smith-docs-detail/batch.yaml +56 -0
- package/skills-entry/doc-smith-docs-detail/index.mjs +95 -0
- package/skills-entry/doc-smith-docs-detail/prompt.md +64 -0
- package/utils/afs-factory.mjs +183 -0
- package/utils/agent-constants.mjs +97 -0
- package/utils/{auth-utils.mjs → auth.mjs} +6 -9
- package/{agents/utils/update-branding.mjs → utils/branding.mjs} +3 -4
- package/utils/config.mjs +261 -0
- package/utils/constants.mjs +32 -0
- package/utils/deploy.mjs +3 -3
- package/utils/docs-converter.mjs +454 -0
- package/utils/docs.mjs +212 -0
- package/utils/document-paths.mjs +172 -0
- package/utils/files.mjs +74 -0
- package/utils/git.mjs +65 -0
- package/utils/{blocklet.mjs → http.mjs} +18 -0
- package/utils/image-slots.mjs +57 -0
- package/utils/image-utils.mjs +114 -0
- package/utils/project.mjs +95 -0
- package/utils/sources-path-resolver.mjs +76 -0
- package/utils/{upload-files.mjs → upload.mjs} +3 -3
- package/utils/workspace.mjs +371 -0
- 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/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/create/aggregate-document-structure.mjs +0 -21
- package/agents/create/analyze-diagram-type-llm.yaml +0 -159
- package/agents/create/analyze-diagram-type.mjs +0 -455
- package/agents/create/check-document-structure.yaml +0 -30
- package/agents/create/check-need-generate-structure.mjs +0 -138
- 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 -91
- package/agents/create/generate-structure.yaml +0 -106
- package/agents/create/index.yaml +0 -45
- package/agents/create/refine-document-structure.yaml +0 -12
- package/agents/create/replace-d2-with-image.mjs +0 -610
- 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 -139
- package/agents/create/utils/init-current-content.mjs +0 -34
- package/agents/create/utils/merge-document-structures.mjs +0 -36
- 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 -643
- package/agents/init/validate.mjs +0 -16
- package/agents/localize/choose-language.mjs +0 -107
- package/agents/localize/record-translation-history.mjs +0 -23
- package/agents/localize/save-doc-translation-or-skip.mjs +0 -18
- package/agents/localize/set-review-content.mjs +0 -58
- package/agents/localize/translate-document-wrapper.mjs +0 -34
- package/agents/localize/translate-document.yaml +0 -24
- package/agents/localize/translate-multilingual.yaml +0 -57
- package/agents/localize/translate-or-skip-diagram.mjs +0 -52
- 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 -454
- package/agents/prefs/index.mjs +0 -203
- 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-update-is-single.mjs +0 -53
- package/agents/update/document-tools/update-document-content.mjs +0 -303
- package/agents/update/generate-diagram.yaml +0 -80
- package/agents/update/generate-document.yaml +0 -70
- package/agents/update/handle-document-update.yaml +0 -103
- package/agents/update/index.yaml +0 -69
- package/agents/update/pre-check-generate-diagram.yaml +0 -44
- package/agents/update/save-and-translate-document.mjs +0 -80
- package/agents/update/update-document-detail.yaml +0 -71
- package/agents/update/update-single/update-single-document-detail.mjs +0 -322
- 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 -253
- package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
- package/agents/utils/check-detail-result.mjs +0 -51
- package/agents/utils/check-feedback-refiner.mjs +0 -81
- package/agents/utils/choose-docs.mjs +0 -251
- 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 -96
- 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 -133
- package/agents/utils/read-current-document-content.mjs +0 -46
- package/agents/utils/save-doc-translation.mjs +0 -30
- package/agents/utils/save-doc.mjs +0 -54
- package/agents/utils/save-output.mjs +0 -26
- package/agents/utils/save-sidebar.mjs +0 -38
- 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/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-user.md +0 -81
- 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/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/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 -205
- package/utils/debug.mjs +0 -3
- package/utils/delete-diagram-images.mjs +0 -99
- package/utils/diagram-version-utils.mjs +0 -14
- package/utils/docs-finder-utils.mjs +0 -548
- 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 -154
- package/utils/kroki-utils.mjs +0 -173
- package/utils/linter/index.mjs +0 -50
- package/utils/load-config.mjs +0 -78
- 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/sync-diagram-to-translations.mjs +0 -272
- package/utils/translate-diagram-images.mjs +0 -807
- package/utils/utils.mjs +0 -1354
- /package/{prompts/translate → agents/localize/prompts}/glossary.md +0 -0
|
@@ -5,21 +5,19 @@ import fs from "fs-extra";
|
|
|
5
5
|
import { parse as yamlParse, stringify as yamlStringify } from "yaml";
|
|
6
6
|
import z from "zod";
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { loadDocumentStructure } from "../../utils/docs
|
|
10
|
-
import { saveValueToConfig } from "../../utils/
|
|
11
|
-
|
|
12
|
-
export default async function translateMeta(
|
|
13
|
-
{ projectName, projectDesc, locale, translateLanguages = [] }
|
|
14
|
-
options,
|
|
15
|
-
) {
|
|
8
|
+
import { PATHS } from "../../utils/agent-constants.mjs";
|
|
9
|
+
import { loadDocumentStructure } from "../../utils/docs.mjs";
|
|
10
|
+
import { saveValueToConfig } from "../../utils/config.mjs";
|
|
11
|
+
|
|
12
|
+
export default async function translateMeta({ config }, options) {
|
|
13
|
+
const { projectName, projectDesc, locale, translateLanguages = [] } = config;
|
|
16
14
|
const languages = [...new Set([...(locale ? [locale] : []), ...(translateLanguages || [])])];
|
|
17
15
|
|
|
18
16
|
// If projectDesc is empty, first try to load overview.md, then fallback to structure-plan.json
|
|
19
17
|
let finalProjectDesc = projectDesc;
|
|
20
18
|
if (!finalProjectDesc || finalProjectDesc.trim() === "") {
|
|
21
19
|
// First, try to read overview.md
|
|
22
|
-
const overviewFilePath = join(
|
|
20
|
+
const overviewFilePath = join("docs", "overview", "en.md");
|
|
23
21
|
const overviewExists = await fs.pathExists(overviewFilePath);
|
|
24
22
|
|
|
25
23
|
if (overviewExists) {
|
|
@@ -32,7 +30,7 @@ export default async function translateMeta(
|
|
|
32
30
|
}
|
|
33
31
|
} else {
|
|
34
32
|
try {
|
|
35
|
-
const outputDir =
|
|
33
|
+
const outputDir = "./planning";
|
|
36
34
|
const documentStructure = await loadDocumentStructure(outputDir);
|
|
37
35
|
if (documentStructure && Array.isArray(documentStructure)) {
|
|
38
36
|
const overviewItem =
|
|
@@ -50,7 +48,10 @@ export default async function translateMeta(
|
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
|
|
53
|
-
|
|
51
|
+
// Ensure cache directory exists
|
|
52
|
+
await fs.ensureDir(PATHS.CACHE);
|
|
53
|
+
|
|
54
|
+
const translationCacheFilePath = join(PATHS.CACHE, "translation-cache.yaml");
|
|
54
55
|
await fs.ensureFile(translationCacheFilePath);
|
|
55
56
|
const translationCache = await fs.readFile(translationCacheFilePath, "utf-8");
|
|
56
57
|
const parsedTranslationCache = yamlParse(translationCache || "{}");
|
|
@@ -58,36 +59,47 @@ export default async function translateMeta(
|
|
|
58
59
|
const titleTranslation = parsedTranslationCache[projectName] || {};
|
|
59
60
|
const descTranslation = parsedTranslationCache[projectDesc] || {};
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
62
|
+
// If only one language, skip translation and cache original content directly
|
|
63
|
+
if (languages.length <= 1) {
|
|
64
|
+
const singleLang = languages[0] || locale || "en";
|
|
65
|
+
if (projectName && !titleTranslation[singleLang]) {
|
|
66
|
+
titleTranslation[singleLang] = projectName;
|
|
67
|
+
}
|
|
68
|
+
if (finalProjectDesc && !descTranslation[singleLang]) {
|
|
69
|
+
descTranslation[singleLang] = finalProjectDesc;
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
// Multiple languages: need translation
|
|
73
|
+
const titleLanguages = languages.filter((lang) => !titleTranslation[lang]);
|
|
74
|
+
const descLanguages = languages.filter((lang) => !descTranslation[lang]);
|
|
75
|
+
const titleTranslationSchema = z.object(
|
|
76
|
+
titleLanguages.reduce((shape, lang) => {
|
|
77
|
+
shape[lang] = z.string();
|
|
78
|
+
return shape;
|
|
79
|
+
}, {}),
|
|
80
|
+
);
|
|
81
|
+
const descTranslationSchema = z.object(
|
|
82
|
+
descLanguages.reduce((shape, lang) => {
|
|
83
|
+
shape[lang] = z.string();
|
|
84
|
+
return shape;
|
|
85
|
+
}, {}),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const agent = AIAgent.from({
|
|
89
|
+
name: "translateMeta",
|
|
90
|
+
instructions:
|
|
91
|
+
"You are an **Elite Polyglot Localization and Translation Specialist** with extensive professional experience across multiple domains. Your core mission is to produce translations that are not only **100% accurate** to the source meaning but are also **natively fluent, highly readable, and culturally appropriate** in the target language.",
|
|
92
|
+
inputKey: "message",
|
|
93
|
+
outputSchema: z.object({
|
|
94
|
+
title: titleTranslationSchema.describe("Translated titles with language codes as keys"),
|
|
95
|
+
desc: descTranslationSchema.describe(
|
|
96
|
+
"Translated descriptions with language codes as keys. Each description MUST be within 100 characters.",
|
|
97
|
+
),
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
if (titleLanguages.length > 0 || descLanguages.length > 0) {
|
|
101
|
+
const translatedMetadata = await options.context.invoke(agent, {
|
|
102
|
+
message: `Translate the following title and description into all target languages except the source language. Provide the translations in a JSON object with the language codes as keys. If the project title or description is empty, return an empty string for that field.
|
|
91
103
|
|
|
92
104
|
**IMPORTANT**: The description translations MUST be concise and within 100 characters. If the source description is long, extract and translate only the key points or create a brief summary that captures the essence.
|
|
93
105
|
|
|
@@ -116,23 +128,19 @@ Respond with a JSON object in the following format:
|
|
|
116
128
|
- Be concise and capture the core essence of the project
|
|
117
129
|
- Use natural, fluent language appropriate for the target culture
|
|
118
130
|
- If the source is very long, create a brief summary instead of a full translation
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (translatedMetadata.desc[lang]) {
|
|
133
|
-
descTranslation[lang] = translatedMetadata.desc[lang];
|
|
134
|
-
}
|
|
135
|
-
});
|
|
131
|
+
`,
|
|
132
|
+
});
|
|
133
|
+
Object.keys(translatedMetadata.title || {}).forEach((lang) => {
|
|
134
|
+
if (translatedMetadata.title[lang]) {
|
|
135
|
+
titleTranslation[lang] = translatedMetadata.title[lang];
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
Object.keys(translatedMetadata.desc || {}).forEach((lang) => {
|
|
139
|
+
if (translatedMetadata.desc[lang]) {
|
|
140
|
+
descTranslation[lang] = translatedMetadata.desc[lang];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
136
144
|
}
|
|
137
145
|
|
|
138
146
|
if (!projectDesc && finalProjectDesc) {
|
|
@@ -153,3 +161,16 @@ If no translation is needed, respond with:
|
|
|
153
161
|
},
|
|
154
162
|
};
|
|
155
163
|
}
|
|
164
|
+
|
|
165
|
+
translateMeta.description =
|
|
166
|
+
"Translate project metadata (title and description) to multiple languages";
|
|
167
|
+
|
|
168
|
+
translateMeta.input_schema = {
|
|
169
|
+
type: "object",
|
|
170
|
+
properties: {
|
|
171
|
+
config: {
|
|
172
|
+
type: "object",
|
|
173
|
+
description: "Configuration object from check step.",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { stringify as yamlStringify } from "yaml";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import {
|
|
6
|
+
normalizePath,
|
|
7
|
+
loadDocumentPaths,
|
|
8
|
+
isValidDocumentPath,
|
|
9
|
+
} from "../../utils/document-paths.mjs";
|
|
10
|
+
import { PATHS, ERROR_CODES, FILE_TYPES, DOC_META_DEFAULTS } from "../../utils/agent-constants.mjs";
|
|
11
|
+
import { loadLocale } from "../../utils/config.mjs";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create document folder and files
|
|
15
|
+
* @param {string} filePath - File path (without slash)
|
|
16
|
+
* @param {string} language - Language code
|
|
17
|
+
* @param {string} content - Document content
|
|
18
|
+
* @returns {Promise<Object>} - Created file paths
|
|
19
|
+
*/
|
|
20
|
+
async function createDocumentFiles(filePath, language, content) {
|
|
21
|
+
const docFolder = path.join(PATHS.DOCS_DIR, filePath);
|
|
22
|
+
|
|
23
|
+
// 1. Create folder (recursive creation, ignore if already exists)
|
|
24
|
+
await mkdir(docFolder, { recursive: true });
|
|
25
|
+
|
|
26
|
+
// 2. Generate .meta.yaml
|
|
27
|
+
const metaContent = yamlStringify({
|
|
28
|
+
kind: DOC_META_DEFAULTS.KIND,
|
|
29
|
+
source: language,
|
|
30
|
+
default: language,
|
|
31
|
+
});
|
|
32
|
+
const metaPath = path.join(docFolder, FILE_TYPES.META);
|
|
33
|
+
await writeFile(metaPath, metaContent, "utf8");
|
|
34
|
+
|
|
35
|
+
// 3. Save language file
|
|
36
|
+
const langFile = `${language}${FILE_TYPES.MARKDOWN}`;
|
|
37
|
+
const langPath = path.join(docFolder, langFile);
|
|
38
|
+
await writeFile(langPath, content, "utf8");
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
folder: docFolder,
|
|
42
|
+
metaFile: metaPath,
|
|
43
|
+
contentFile: langPath,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Save document to docs directory
|
|
49
|
+
* @param {Object} params - Parameters
|
|
50
|
+
* @param {string} params.path - Document path (with or without slash)
|
|
51
|
+
* @param {string} params.content - Document content (Markdown format)
|
|
52
|
+
* @param {Object} params.options - Options
|
|
53
|
+
* @param {string} params.options.language - Language code (e.g., zh, en, ja)
|
|
54
|
+
* @returns {Promise<Object>} - Operation result
|
|
55
|
+
*/
|
|
56
|
+
export default async function saveDocument({ path: rawPath, content, options = {} }) {
|
|
57
|
+
try {
|
|
58
|
+
// 1. Parameter validation: content
|
|
59
|
+
if (!content || typeof content !== "string" || content.trim().length === 0) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: ERROR_CODES.EMPTY_CONTENT,
|
|
63
|
+
message: "Document content cannot be empty",
|
|
64
|
+
suggestion: "Please provide valid document content",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 2. Parameter validation: language
|
|
69
|
+
const language = options.language;
|
|
70
|
+
if (!language || typeof language !== "string") {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
error: ERROR_CODES.INVALID_LANGUAGE,
|
|
74
|
+
message: `Invalid language code: ${language}`,
|
|
75
|
+
suggestion: "Please provide a valid language code (e.g., zh, en, ja)",
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Validate language code format (e.g., zh, en, zh-CN, en-US)
|
|
80
|
+
const languagePattern = /^[a-z]{2}(-[A-Z]{2})?$/;
|
|
81
|
+
if (!languagePattern.test(language)) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: ERROR_CODES.INVALID_LANGUAGE,
|
|
85
|
+
message: `Invalid language code format: ${language}`,
|
|
86
|
+
suggestion: "Language code should follow format: zh, en, ja or zh-CN, en-US, etc.",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 3. Parameter validation: path
|
|
91
|
+
if (!rawPath || typeof rawPath !== "string") {
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
error: ERROR_CODES.INVALID_PATH,
|
|
95
|
+
message: "Invalid document path",
|
|
96
|
+
suggestion: "Please provide a valid document path",
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 4. Normalize path
|
|
101
|
+
const { filePath, displayPath } = normalizePath(rawPath);
|
|
102
|
+
|
|
103
|
+
// 5. Load and validate document structure
|
|
104
|
+
let validPaths;
|
|
105
|
+
try {
|
|
106
|
+
validPaths = await loadDocumentPaths({ includeBothFormats: true });
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (error.message === ERROR_CODES.MISSING_STRUCTURE_FILE) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
error: ERROR_CODES.MISSING_STRUCTURE_FILE,
|
|
112
|
+
message: `Document structure file not found: ${PATHS.DOCUMENT_STRUCTURE}`,
|
|
113
|
+
suggestion: "Please generate the document structure file first",
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 6. Validate path exists in document structure
|
|
120
|
+
if (!isValidDocumentPath(rawPath, validPaths)) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
error: ERROR_CODES.PATH_NOT_IN_STRUCTURE,
|
|
124
|
+
message: `Document path ${displayPath} does not exist in document structure`,
|
|
125
|
+
suggestion: `Please add this path to ${PATHS.DOCUMENT_STRUCTURE} first, or check if the path is correct`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 7. Check that language must equal project locale when creating new document
|
|
130
|
+
const docFolder = path.join(PATHS.DOCS_DIR, filePath);
|
|
131
|
+
const metaPath = path.join(docFolder, FILE_TYPES.META);
|
|
132
|
+
const isNewDocument = !existsSync(metaPath);
|
|
133
|
+
|
|
134
|
+
if (isNewDocument) {
|
|
135
|
+
let projectLocale;
|
|
136
|
+
try {
|
|
137
|
+
projectLocale = await loadLocale();
|
|
138
|
+
} catch (_error) {
|
|
139
|
+
return {
|
|
140
|
+
success: false,
|
|
141
|
+
error: ERROR_CODES.MISSING_CONFIG_FILE,
|
|
142
|
+
message: "Cannot read project configuration file",
|
|
143
|
+
suggestion: "Please ensure config.yaml exists and contains the locale field",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (language !== projectLocale) {
|
|
148
|
+
return {
|
|
149
|
+
success: false,
|
|
150
|
+
error: ERROR_CODES.INVALID_LANGUAGE,
|
|
151
|
+
message: `New documents must use project main language: ${projectLocale}, provided: ${language}`,
|
|
152
|
+
suggestion: `Please change language parameter to "${projectLocale}" (project locale), generate main language version first`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 8. Create folder and files
|
|
158
|
+
const files = await createDocumentFiles(filePath, language, content);
|
|
159
|
+
|
|
160
|
+
// 9. Return success response
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
path: displayPath,
|
|
164
|
+
folder: files.folder,
|
|
165
|
+
files: {
|
|
166
|
+
meta: files.metaFile,
|
|
167
|
+
content: files.contentFile,
|
|
168
|
+
},
|
|
169
|
+
message: `Document saved successfully: ${displayPath} (${language})`,
|
|
170
|
+
};
|
|
171
|
+
} catch (error) {
|
|
172
|
+
// Catch unexpected errors
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
error: ERROR_CODES.FILE_OPERATION_ERROR,
|
|
176
|
+
message: `File operation failed: ${error.message}`,
|
|
177
|
+
suggestion: "Check file system permissions or if path is correct",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Add description
|
|
183
|
+
saveDocument.description =
|
|
184
|
+
`Save document to ${PATHS.DOCS_DIR} directory, automatically create folder structure, meta info file and language version file. ` +
|
|
185
|
+
"[Important restriction] This tool is only for creating new documents. When editing existing documents, use the Edit tool to modify the corresponding language file directly. " +
|
|
186
|
+
`Must ensure ${PATHS.DOCUMENT_STRUCTURE} exists and contains the target document path before use. ` +
|
|
187
|
+
"[Mandatory requirement] When creating new documents, language must equal project locale (locale field in config.yaml), the system will auto-validate.";
|
|
188
|
+
|
|
189
|
+
// Define input schema
|
|
190
|
+
saveDocument.input_schema = {
|
|
191
|
+
type: "object",
|
|
192
|
+
required: ["path", "content", "options"],
|
|
193
|
+
properties: {
|
|
194
|
+
path: {
|
|
195
|
+
type: "string",
|
|
196
|
+
description: "Document path, must exist in planning/document-structure.yaml",
|
|
197
|
+
},
|
|
198
|
+
content: {
|
|
199
|
+
type: "string",
|
|
200
|
+
description: "Document content (Markdown format), cannot be empty",
|
|
201
|
+
},
|
|
202
|
+
options: {
|
|
203
|
+
type: "object",
|
|
204
|
+
required: ["language"],
|
|
205
|
+
properties: {
|
|
206
|
+
language: {
|
|
207
|
+
type: "string",
|
|
208
|
+
description:
|
|
209
|
+
"Language code (e.g., zh, en, ja), must be read from locale field in config.yaml",
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// Define output schema
|
|
217
|
+
saveDocument.output_schema = {
|
|
218
|
+
type: "object",
|
|
219
|
+
required: ["success"],
|
|
220
|
+
properties: {
|
|
221
|
+
success: {
|
|
222
|
+
type: "boolean",
|
|
223
|
+
description: "Whether operation succeeded",
|
|
224
|
+
},
|
|
225
|
+
path: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Normalized document path (present on success)",
|
|
228
|
+
},
|
|
229
|
+
folder: {
|
|
230
|
+
type: "string",
|
|
231
|
+
description: "Created folder path (present on success)",
|
|
232
|
+
},
|
|
233
|
+
files: {
|
|
234
|
+
type: "object",
|
|
235
|
+
description: "Created file paths (present on success)",
|
|
236
|
+
properties: {
|
|
237
|
+
meta: {
|
|
238
|
+
type: "string",
|
|
239
|
+
description: "Meta info file path",
|
|
240
|
+
},
|
|
241
|
+
content: {
|
|
242
|
+
type: "string",
|
|
243
|
+
description: "Language file path",
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
message: {
|
|
248
|
+
type: "string",
|
|
249
|
+
description: "Operation result description",
|
|
250
|
+
},
|
|
251
|
+
error: {
|
|
252
|
+
type: "string",
|
|
253
|
+
description: "Error code (present on failure)",
|
|
254
|
+
},
|
|
255
|
+
suggestion: {
|
|
256
|
+
type: "string",
|
|
257
|
+
description: "Suggested action (present on failure)",
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
};
|