@aigne/doc-smith 0.8.15-beta.1 → 0.8.15-beta.11
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 +89 -0
- package/agents/clear/choose-contents.mjs +4 -4
- package/agents/clear/clear-auth-tokens.mjs +8 -8
- package/agents/clear/clear-deployment-config.mjs +2 -2
- package/agents/clear/clear-document-config.mjs +3 -3
- package/agents/clear/clear-document-structure.mjs +10 -10
- package/agents/clear/clear-generated-docs.mjs +103 -14
- package/agents/clear/clear-media-description.mjs +7 -7
- package/agents/evaluate/document-structure.yaml +3 -1
- package/agents/evaluate/document.yaml +3 -1
- package/agents/evaluate/index.yaml +1 -3
- package/agents/generate/check-diagram.mjs +1 -1
- package/agents/generate/check-need-generate-structure.mjs +2 -7
- package/agents/generate/draw-diagram.yaml +4 -0
- package/agents/generate/generate-structure.yaml +117 -65
- package/agents/generate/index.yaml +3 -3
- package/agents/generate/{merge-d2-diagram.yaml → merge-diagram.yaml} +7 -6
- package/agents/generate/update-document-structure.yaml +1 -1
- package/agents/generate/user-review-document-structure.mjs +3 -25
- package/agents/generate/utils/merge-document-structures.mjs +30 -0
- package/agents/init/check.mjs +4 -2
- package/agents/init/index.mjs +37 -7
- package/agents/media/load-media-description.mjs +12 -24
- package/agents/publish/publish-docs.mjs +3 -8
- package/agents/schema/document-execution-structure.yaml +1 -1
- package/agents/schema/document-structure-item.yaml +23 -0
- package/agents/schema/document-structure-refine-item.yaml +20 -0
- package/agents/schema/document-structure.yaml +1 -1
- package/agents/translate/index.yaml +1 -4
- package/agents/translate/record-translation-history.mjs +6 -2
- package/agents/translate/translate-multilingual.yaml +1 -1
- package/agents/update/batch-generate-document.yaml +1 -1
- package/agents/update/batch-update-document.yaml +1 -1
- package/agents/update/check-document.mjs +35 -13
- package/agents/update/check-generate-diagram.mjs +29 -0
- package/agents/update/generate-diagram.yaml +29 -0
- package/agents/update/generate-document.yaml +17 -30
- package/agents/update/handle-document-update.yaml +10 -1
- package/agents/update/save-and-translate-document.mjs +18 -47
- package/agents/update/update-document-detail.yaml +2 -1
- package/agents/update/update-single-document.yaml +1 -1
- package/agents/update/user-review-document.mjs +6 -5
- package/agents/utils/choose-docs.mjs +16 -5
- package/agents/utils/find-item-by-path.mjs +4 -2
- package/agents/utils/load-sources.mjs +63 -46
- package/agents/utils/{save-docs.mjs → post-generate.mjs} +2 -51
- package/agents/utils/save-doc-translation.mjs +27 -0
- package/agents/utils/{save-single-doc.mjs → save-doc.mjs} +17 -12
- package/agents/utils/save-sidebar.mjs +38 -0
- package/agents/utils/{transform-detail-datasources.mjs → transform-detail-data-sources.mjs} +7 -7
- package/aigne.yaml +16 -8
- package/package.json +3 -1
- package/prompts/common/document/content-rules-core.md +6 -6
- package/prompts/common/document/media-file-list-usage-rules.md +12 -0
- package/prompts/common/document/openapi-usage-rules.md +36 -0
- package/prompts/common/document/role-and-personality.md +1 -2
- package/prompts/common/document-structure/conflict-resolution-guidance.md +2 -2
- package/prompts/common/document-structure/document-structure-rules.md +8 -8
- package/prompts/common/document-structure/output-constraints.md +3 -3
- package/prompts/detail/custom/custom-components.md +38 -3
- package/prompts/detail/d2-diagram/rules.md +11 -14
- package/prompts/detail/d2-diagram/system-prompt.md +0 -14
- package/prompts/detail/d2-diagram/user-prompt.md +39 -0
- package/prompts/detail/generate/document-rules.md +3 -3
- package/prompts/detail/generate/system-prompt.md +2 -6
- package/prompts/detail/generate/user-prompt.md +20 -61
- package/prompts/detail/update/system-prompt.md +2 -6
- package/prompts/detail/update/user-prompt.md +7 -6
- package/prompts/evaluate/document.md +0 -4
- package/prompts/structure/check-document-structure.md +4 -4
- package/prompts/structure/generate/system-prompt.md +0 -31
- package/prompts/structure/generate/user-prompt.md +73 -29
- package/prompts/structure/review/structure-review-system.md +81 -0
- package/prompts/structure/update/system-prompt.md +1 -1
- package/prompts/structure/update/user-prompt.md +4 -4
- package/prompts/translate/code-block.md +13 -3
- package/prompts/translate/translate-document.md +3 -3
- package/types/document-structure-schema.mjs +3 -3
- package/utils/constants/index.mjs +6 -0
- package/utils/docs-finder-utils.mjs +85 -3
- package/utils/extract-api.mjs +32 -0
- package/utils/file-utils.mjs +153 -101
- package/utils/history-utils.mjs +20 -8
- package/utils/load-config.mjs +20 -1
- package/utils/markdown-checker.mjs +35 -1
- package/utils/utils.mjs +67 -65
- package/agents/generate/document-structure-tools/generate-sub-structure.mjs +0 -131
- package/agents/generate/generate-structure-without-tools.yaml +0 -65
- package/prompts/common/document/media-handling-rules.md +0 -9
|
@@ -2,7 +2,10 @@ import { access, readFile } from "node:fs/promises";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { TeamAgent } from "@aigne/core";
|
|
5
|
+
import fs from "fs-extra";
|
|
6
|
+
import pMap from "p-map";
|
|
5
7
|
|
|
8
|
+
import { getFileName } from "../../utils/utils.mjs";
|
|
6
9
|
import checkDetailResult from "../utils/check-detail-result.mjs";
|
|
7
10
|
|
|
8
11
|
// Get current script directory
|
|
@@ -18,13 +21,13 @@ export default async function checkDocument(
|
|
|
18
21
|
modifiedFiles,
|
|
19
22
|
forceRegenerate,
|
|
20
23
|
locale,
|
|
24
|
+
translates,
|
|
21
25
|
...rest
|
|
22
26
|
},
|
|
23
27
|
options,
|
|
24
28
|
) {
|
|
25
29
|
// Check if the detail file already exists
|
|
26
|
-
const
|
|
27
|
-
const fileFullName = locale === "en" ? `${flatName}.md` : `${flatName}.${locale}.md`;
|
|
30
|
+
const fileFullName = getFileName(path, locale);
|
|
28
31
|
const filePath = join(docsDir, fileFullName);
|
|
29
32
|
let detailGenerated = true;
|
|
30
33
|
let fileContent = null;
|
|
@@ -84,24 +87,42 @@ export default async function checkDocument(
|
|
|
84
87
|
contentValidationFailed = true;
|
|
85
88
|
}
|
|
86
89
|
}
|
|
90
|
+
const languages = translates.map((x) => x.language);
|
|
91
|
+
const lackLanguages = new Set(languages);
|
|
92
|
+
const skills = [];
|
|
87
93
|
|
|
88
94
|
// If file exists, sourceIds haven't changed, source files haven't changed, and content validation passes, no need to regenerate
|
|
89
95
|
if (detailGenerated && !sourceIdsChanged && !contentValidationFailed && !forceRegenerate) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
await pMap(
|
|
97
|
+
languages,
|
|
98
|
+
async (x) => {
|
|
99
|
+
const languageFileName = getFileName(path, x);
|
|
100
|
+
const languageFilePath = join(docsDir, languageFileName);
|
|
101
|
+
if (await fs.exists(languageFilePath)) {
|
|
102
|
+
lackLanguages.delete(x);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{ concurrency: 10 },
|
|
106
|
+
);
|
|
107
|
+
if (lackLanguages.size === 0) {
|
|
108
|
+
return {
|
|
109
|
+
path,
|
|
110
|
+
docsDir,
|
|
111
|
+
...rest,
|
|
112
|
+
detailGenerated: true,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// translations during generation don't need feedback, content is satisfactory
|
|
116
|
+
rest.content = fileContent;
|
|
117
|
+
} else {
|
|
118
|
+
skills.push(options.context.agents["handleDocumentUpdate"]);
|
|
96
119
|
}
|
|
97
120
|
|
|
121
|
+
skills.push(options.context.agents["translateMultilingual"]);
|
|
122
|
+
|
|
98
123
|
const teamAgent = TeamAgent.from({
|
|
99
124
|
name: "generateDocument",
|
|
100
|
-
skills
|
|
101
|
-
options.context.agents["handleDocumentUpdate"],
|
|
102
|
-
options.context.agents["translateMultilingual"],
|
|
103
|
-
options.context.agents["saveSingleDoc"],
|
|
104
|
-
],
|
|
125
|
+
skills,
|
|
105
126
|
});
|
|
106
127
|
let openAPISpec = null;
|
|
107
128
|
|
|
@@ -119,6 +140,7 @@ export default async function checkDocument(
|
|
|
119
140
|
|
|
120
141
|
const result = await options.context.invoke(teamAgent, {
|
|
121
142
|
...rest,
|
|
143
|
+
translates: translates.filter((x) => lackLanguages.has(x.language)),
|
|
122
144
|
locale,
|
|
123
145
|
docsDir,
|
|
124
146
|
path,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const placeholder = "DIAGRAM_PLACEHOLDER";
|
|
2
|
+
|
|
3
|
+
export default async function checkGenerateDiagram(
|
|
4
|
+
{ needDiagram, documentContent, locale },
|
|
5
|
+
options,
|
|
6
|
+
) {
|
|
7
|
+
if (!needDiagram) {
|
|
8
|
+
return {};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const generateAgent = options.context?.agents?.["generateDiagram"];
|
|
12
|
+
let content = documentContent;
|
|
13
|
+
|
|
14
|
+
if (content.includes(placeholder)) {
|
|
15
|
+
try {
|
|
16
|
+
const { diagramSourceCode } = await options.context.invoke(generateAgent, {
|
|
17
|
+
documentContent,
|
|
18
|
+
locale,
|
|
19
|
+
});
|
|
20
|
+
content = content.replace(placeholder, diagramSourceCode);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
// FIXME: @zhanghan should regenerate document without diagram
|
|
23
|
+
content = content.replace(placeholder, "");
|
|
24
|
+
console.log(`⚠️ Skip generate any diagram: ${error.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return { content };
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type: team
|
|
2
|
+
task_render_mode: collapse
|
|
3
|
+
name: generateDiagram
|
|
4
|
+
skills:
|
|
5
|
+
- ../generate/draw-diagram.yaml
|
|
6
|
+
- ../generate/wrap-diagram-code.mjs
|
|
7
|
+
reflection:
|
|
8
|
+
reviewer: ../generate/check-diagram.mjs
|
|
9
|
+
is_approved: isValid
|
|
10
|
+
max_iterations: 5
|
|
11
|
+
return_last_on_max_iterations: false
|
|
12
|
+
input_schema:
|
|
13
|
+
type: object
|
|
14
|
+
properties:
|
|
15
|
+
documentContent:
|
|
16
|
+
type: string
|
|
17
|
+
description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any diagram source code.)
|
|
18
|
+
locale:
|
|
19
|
+
type: string
|
|
20
|
+
description: Language for diagram labels and text
|
|
21
|
+
default: en
|
|
22
|
+
required:
|
|
23
|
+
- documentContent
|
|
24
|
+
output_schema:
|
|
25
|
+
type: object
|
|
26
|
+
properties:
|
|
27
|
+
diagramSourceCode:
|
|
28
|
+
type: string
|
|
29
|
+
description: The **diagram source code** generated from the input text.
|
|
@@ -16,7 +16,7 @@ input_schema:
|
|
|
16
16
|
locale:
|
|
17
17
|
type: string
|
|
18
18
|
description: User language, such as zh, en
|
|
19
|
-
|
|
19
|
+
detailDataSource:
|
|
20
20
|
type: string
|
|
21
21
|
description: Source data and context for document content generation
|
|
22
22
|
targetAudience:
|
|
@@ -44,9 +44,21 @@ input_schema:
|
|
|
44
44
|
description: Additional supplementary information
|
|
45
45
|
required:
|
|
46
46
|
- rules
|
|
47
|
-
-
|
|
47
|
+
- detailDataSource
|
|
48
48
|
- originalDocumentStructure
|
|
49
|
-
output_key: content
|
|
49
|
+
# output_key: content
|
|
50
|
+
output_schema:
|
|
51
|
+
type: object
|
|
52
|
+
properties:
|
|
53
|
+
content:
|
|
54
|
+
type: string
|
|
55
|
+
description: Document content
|
|
56
|
+
needDiagram:
|
|
57
|
+
type: boolean
|
|
58
|
+
description: Does this document need to generate diagram?
|
|
59
|
+
required:
|
|
60
|
+
- content
|
|
61
|
+
- detailDataSource
|
|
50
62
|
afs:
|
|
51
63
|
modules:
|
|
52
64
|
- module: system-fs
|
|
@@ -57,30 +69,5 @@ afs:
|
|
|
57
69
|
Codebase of the project to be documented used as context for document generation,
|
|
58
70
|
should search and read as needed while generating document content
|
|
59
71
|
keep_text_in_tool_uses: false
|
|
60
|
-
skills:
|
|
61
|
-
|
|
62
|
-
task_render_mode: collapse
|
|
63
|
-
name: generateDiagram
|
|
64
|
-
skills:
|
|
65
|
-
- ../generate/draw-diagram.yaml
|
|
66
|
-
- ../generate/wrap-diagram-code.mjs
|
|
67
|
-
reflection:
|
|
68
|
-
reviewer: ../generate/check-diagram.mjs
|
|
69
|
-
is_approved: isValid
|
|
70
|
-
max_iterations: 5
|
|
71
|
-
return_last_on_max_iterations: false
|
|
72
|
-
custom_error_message: "MUST NOT generate any diagram: validation failed after max iterations."
|
|
73
|
-
input_schema:
|
|
74
|
-
type: object
|
|
75
|
-
properties:
|
|
76
|
-
documentContent:
|
|
77
|
-
type: string
|
|
78
|
-
description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any diagram source code.)
|
|
79
|
-
required:
|
|
80
|
-
- documentContent
|
|
81
|
-
output_schema:
|
|
82
|
-
type: object
|
|
83
|
-
properties:
|
|
84
|
-
diagramSourceCode:
|
|
85
|
-
type: string
|
|
86
|
-
description: The **diagram source code** generated from the input text.
|
|
72
|
+
# skills:
|
|
73
|
+
# - ./generate-diagram.yaml
|
|
@@ -2,7 +2,7 @@ type: team
|
|
|
2
2
|
name: handleDocumentUpdate
|
|
3
3
|
description: Update a document in a batch
|
|
4
4
|
skills:
|
|
5
|
-
- ../utils/transform-detail-
|
|
5
|
+
- ../utils/transform-detail-data-sources.mjs
|
|
6
6
|
- type: team
|
|
7
7
|
task_render_mode: collapse
|
|
8
8
|
name: generateDocumentContent
|
|
@@ -23,6 +23,15 @@ skills:
|
|
|
23
23
|
max_iterations: 5
|
|
24
24
|
return_last_on_max_iterations: true
|
|
25
25
|
task_title: Generate document for '{{ title }}'
|
|
26
|
+
- type: transform
|
|
27
|
+
jsonata: |
|
|
28
|
+
$merge([
|
|
29
|
+
$,
|
|
30
|
+
{ "documentContent": content }
|
|
31
|
+
])
|
|
32
|
+
- ./check-generate-diagram.mjs
|
|
33
|
+
# - ../generate/merge-diagram.yaml
|
|
34
|
+
- ../utils/save-doc.mjs
|
|
26
35
|
input_schema:
|
|
27
36
|
type: object
|
|
28
37
|
properties:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import pMap from "p-map";
|
|
1
2
|
import { recordUpdate } from "../../utils/history-utils.mjs";
|
|
2
3
|
|
|
3
4
|
export default async function saveAndTranslateDocument(input, options) {
|
|
@@ -7,20 +8,15 @@ export default async function saveAndTranslateDocument(input, options) {
|
|
|
7
8
|
return {};
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
docsDir: docsDir,
|
|
18
|
-
locale: locale,
|
|
19
|
-
translates: translates || doc.translates,
|
|
20
|
-
labels: doc.labels,
|
|
21
|
-
isTranslate: isTranslate,
|
|
11
|
+
// Record history if feedback is provided
|
|
12
|
+
const doc = selectedDocs[0];
|
|
13
|
+
if (doc.feedback?.trim()) {
|
|
14
|
+
recordUpdate({
|
|
15
|
+
operation: "document_update",
|
|
16
|
+
feedback: doc.feedback.trim(),
|
|
17
|
+
docPaths: selectedDocs.map((v) => v.path),
|
|
22
18
|
});
|
|
23
|
-
}
|
|
19
|
+
}
|
|
24
20
|
|
|
25
21
|
// Only prompt user if translation is actually needed
|
|
26
22
|
let shouldTranslate = false;
|
|
@@ -46,28 +42,6 @@ export default async function saveAndTranslateDocument(input, options) {
|
|
|
46
42
|
|
|
47
43
|
// Save documents in batches
|
|
48
44
|
const batchSize = 3;
|
|
49
|
-
for (let i = 0; i < selectedDocs.length; i += batchSize) {
|
|
50
|
-
const batch = selectedDocs.slice(i, i + batchSize);
|
|
51
|
-
|
|
52
|
-
const savePromises = batch.map(async (doc) => {
|
|
53
|
-
try {
|
|
54
|
-
await saveDocument(doc);
|
|
55
|
-
|
|
56
|
-
// Record history for each document if feedback is provided
|
|
57
|
-
if (doc.feedback?.trim()) {
|
|
58
|
-
recordUpdate({
|
|
59
|
-
operation: "document_update",
|
|
60
|
-
feedback: doc.feedback.trim(),
|
|
61
|
-
documentPath: doc.path,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error(`❌ Failed to save document ${doc.path}:`, error.message);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await Promise.all(savePromises);
|
|
70
|
-
}
|
|
71
45
|
|
|
72
46
|
// Return results if user chose to skip translation
|
|
73
47
|
if (!shouldTranslate) {
|
|
@@ -77,30 +51,27 @@ export default async function saveAndTranslateDocument(input, options) {
|
|
|
77
51
|
// Translate documents in batches
|
|
78
52
|
const translateAgent = options.context.agents["translateMultilingual"];
|
|
79
53
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const translatePromises = batch.map(async (doc) => {
|
|
54
|
+
await pMap(
|
|
55
|
+
selectedDocs,
|
|
56
|
+
async (doc) => {
|
|
84
57
|
try {
|
|
85
58
|
// Clear feedback to ensure translation is not affected by update feedback
|
|
86
59
|
doc.feedback = "";
|
|
87
60
|
|
|
88
|
-
|
|
61
|
+
await options.context.invoke(translateAgent, {
|
|
89
62
|
...input, // context is required
|
|
90
63
|
content: doc.content,
|
|
91
64
|
translates: doc.translates,
|
|
92
65
|
title: doc.title,
|
|
66
|
+
path: doc.path,
|
|
67
|
+
docsDir,
|
|
93
68
|
});
|
|
94
|
-
|
|
95
|
-
// Save the translated content
|
|
96
|
-
await saveDocument(doc, result.translates, true);
|
|
97
69
|
} catch (error) {
|
|
98
70
|
console.error(`❌ Failed to translate document ${doc.path}:`, error.message);
|
|
99
71
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
72
|
+
},
|
|
73
|
+
{ concurrency: batchSize },
|
|
74
|
+
);
|
|
104
75
|
|
|
105
76
|
return {};
|
|
106
77
|
}
|
|
@@ -23,7 +23,7 @@ input_schema:
|
|
|
23
23
|
locale:
|
|
24
24
|
type: string
|
|
25
25
|
description: User language, e.g. zh, en
|
|
26
|
-
|
|
26
|
+
detailDataSource:
|
|
27
27
|
type: string
|
|
28
28
|
description: Context for document content
|
|
29
29
|
glossary:
|
|
@@ -57,4 +57,5 @@ afs:
|
|
|
57
57
|
keep_text_in_tool_uses: false
|
|
58
58
|
skills:
|
|
59
59
|
- ./document-tools/update-document-content.mjs
|
|
60
|
+
# - ./generate-diagram.yaml
|
|
60
61
|
task_render_mode: collapse
|
|
@@ -105,6 +105,7 @@ async function showDocumentDetail(content, title) {
|
|
|
105
105
|
renderer: new markedTerminal(),
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
+
// FIXME: @zhanghan fix error "Could not find the language 'd2', did you forget to load/include a language module?"
|
|
108
109
|
const renderedMarkdown = marked(content);
|
|
109
110
|
|
|
110
111
|
// Restore original console.error
|
|
@@ -121,16 +122,15 @@ async function showDocumentDetail(content, title) {
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
export default async function userReviewDocument(
|
|
125
|
-
{ content, title, description, ...rest },
|
|
126
|
-
options,
|
|
127
|
-
) {
|
|
125
|
+
export default async function userReviewDocument({ content, description, ...rest }, options) {
|
|
128
126
|
// Check if document content exists
|
|
129
127
|
if (!content || typeof content !== "string" || content.trim().length === 0) {
|
|
130
128
|
console.log("Please provide document content to review.");
|
|
131
129
|
return { content };
|
|
132
130
|
}
|
|
133
131
|
|
|
132
|
+
const title = rest.documentStructure?.find((x) => x.path === rest.path)?.title;
|
|
133
|
+
|
|
134
134
|
// Print current document headings structure
|
|
135
135
|
printDocumentHeadings(content, title || "Untitled Document");
|
|
136
136
|
|
|
@@ -190,7 +190,7 @@ export default async function userReviewDocument(
|
|
|
190
190
|
feedbacks.push(feedback.trim());
|
|
191
191
|
|
|
192
192
|
// Get the updateDocument agent
|
|
193
|
-
const updateAgent = options.context.agents["
|
|
193
|
+
const updateAgent = options.context.agents["handleDocumentUpdate"];
|
|
194
194
|
if (!updateAgent) {
|
|
195
195
|
console.log(
|
|
196
196
|
"We can't process your feedback right now. The document update feature is temporarily unavailable.",
|
|
@@ -213,6 +213,7 @@ export default async function userReviewDocument(
|
|
|
213
213
|
originalContent: options.context.userContext.currentContent,
|
|
214
214
|
feedback: feedback.trim(),
|
|
215
215
|
userPreferences,
|
|
216
|
+
title,
|
|
216
217
|
});
|
|
217
218
|
|
|
218
219
|
// Check if feedback should be saved as user preference
|
|
@@ -6,6 +6,14 @@ import {
|
|
|
6
6
|
getMainLanguageFiles,
|
|
7
7
|
processSelectedFiles,
|
|
8
8
|
} from "../../utils/docs-finder-utils.mjs";
|
|
9
|
+
import { DOC_ACTION } from "../../utils/constants/index.mjs";
|
|
10
|
+
|
|
11
|
+
function getFeedbackMessage(action) {
|
|
12
|
+
if (action === DOC_ACTION.translate) {
|
|
13
|
+
return "Any specific translation preferences or instructions? (Press Enter to skip):";
|
|
14
|
+
}
|
|
15
|
+
return "How would you like to improve this document? (Press Enter to skip)";
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
export default async function chooseDocs(
|
|
11
19
|
{
|
|
@@ -18,11 +26,13 @@ export default async function chooseDocs(
|
|
|
18
26
|
locale,
|
|
19
27
|
reset = false,
|
|
20
28
|
requiredFeedback = true,
|
|
29
|
+
action,
|
|
21
30
|
},
|
|
22
31
|
options,
|
|
23
32
|
) {
|
|
24
33
|
let foundItems = [];
|
|
25
34
|
let selectedFiles = [];
|
|
35
|
+
const docAction = action || (isTranslate ? DOC_ACTION.translate : DOC_ACTION.update);
|
|
26
36
|
|
|
27
37
|
// If docs is empty or not provided, let user select multiple documents
|
|
28
38
|
if (!docs || docs.length === 0) {
|
|
@@ -36,7 +46,9 @@ export default async function chooseDocs(
|
|
|
36
46
|
|
|
37
47
|
if (mainLanguageFiles.length === 0) {
|
|
38
48
|
throw new Error(
|
|
39
|
-
`No documents found in the docs directory.
|
|
49
|
+
`No documents found in the docs directory. You can generate them with ${chalk.yellow(
|
|
50
|
+
"`aigne doc generate`",
|
|
51
|
+
)}`,
|
|
40
52
|
);
|
|
41
53
|
}
|
|
42
54
|
|
|
@@ -65,7 +77,7 @@ export default async function chooseDocs(
|
|
|
65
77
|
|
|
66
78
|
// Let user select multiple files
|
|
67
79
|
selectedFiles = await options.prompts.checkbox({
|
|
68
|
-
message: getActionText(
|
|
80
|
+
message: getActionText("Select documents to {action}:", docAction),
|
|
69
81
|
source: (term) => {
|
|
70
82
|
if (!term) return choices;
|
|
71
83
|
|
|
@@ -87,7 +99,7 @@ export default async function chooseDocs(
|
|
|
87
99
|
foundItems = await processSelectedFiles(selectedFiles, documentExecutionStructure, docsDir);
|
|
88
100
|
} catch (error) {
|
|
89
101
|
console.log(
|
|
90
|
-
getActionText(
|
|
102
|
+
getActionText(`\nFailed to select documents to {action}: ${error.message}`, docAction),
|
|
91
103
|
);
|
|
92
104
|
process.exit(0);
|
|
93
105
|
}
|
|
@@ -122,8 +134,7 @@ export default async function chooseDocs(
|
|
|
122
134
|
// Prompt for feedback if not provided
|
|
123
135
|
let userFeedback = feedback;
|
|
124
136
|
if (!userFeedback && (requiredFeedback || foundItems?.length > 1)) {
|
|
125
|
-
const feedbackMessage =
|
|
126
|
-
"How should we improve this document? (Enter to skip, will auto-update from content sources):";
|
|
137
|
+
const feedbackMessage = getFeedbackMessage(docAction);
|
|
127
138
|
|
|
128
139
|
userFeedback = await options.prompts.input({
|
|
129
140
|
message: feedbackMessage,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DOC_ACTION } from "../../utils/constants/index.mjs";
|
|
1
2
|
import {
|
|
2
3
|
fileNameToFlatPath,
|
|
3
4
|
findItemByFlatName,
|
|
@@ -14,6 +15,7 @@ export default async function findItemByPath(
|
|
|
14
15
|
let foundItem = null;
|
|
15
16
|
let selectedFileContent = null;
|
|
16
17
|
let docPath = doc;
|
|
18
|
+
const docAction = isTranslate ? DOC_ACTION.translate : DOC_ACTION.update;
|
|
17
19
|
|
|
18
20
|
// If docPath is empty, let user select from available documents
|
|
19
21
|
if (!docPath) {
|
|
@@ -31,7 +33,7 @@ export default async function findItemByPath(
|
|
|
31
33
|
|
|
32
34
|
// Let user select a file
|
|
33
35
|
const selectedFile = await options.prompts.search({
|
|
34
|
-
message: getActionText(
|
|
36
|
+
message: getActionText("Select a document to {action}:", docAction),
|
|
35
37
|
source: async (input) => {
|
|
36
38
|
if (!input || input.trim() === "") {
|
|
37
39
|
return mainLanguageFiles.map((file) => ({
|
|
@@ -74,8 +76,8 @@ export default async function findItemByPath(
|
|
|
74
76
|
console.debug(error?.message);
|
|
75
77
|
throw new Error(
|
|
76
78
|
getActionText(
|
|
77
|
-
isTranslate,
|
|
78
79
|
"Please run 'aigne doc generate' first to generate documents, then select which document to {action}",
|
|
80
|
+
docAction,
|
|
79
81
|
),
|
|
80
82
|
);
|
|
81
83
|
}
|