@aigne/doc-smith 0.2.11 → 0.3.1
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 +19 -0
- package/agents/batch-docs-detail-generator.yaml +1 -1
- package/agents/batch-translate.yaml +3 -1
- package/agents/check-structure-plan.mjs +1 -1
- package/agents/detail-generator-and-translate.yaml +3 -0
- package/agents/detail-regenerator.yaml +3 -6
- package/agents/docs-generator.yaml +2 -5
- package/agents/find-item-by-path.mjs +1 -1
- package/agents/format-structure-plan.mjs +2 -0
- package/agents/input-generator.mjs +220 -52
- package/agents/load-config.mjs +8 -1
- package/agents/load-sources.mjs +2 -0
- package/agents/publish-docs.mjs +11 -4
- package/agents/reflective-structure-planner.yaml +2 -1
- package/agents/save-output.mjs +2 -0
- package/agents/save-single-doc.mjs +2 -0
- package/agents/structure-planning.yaml +1 -1
- package/agents/transform-detail-datasources.mjs +2 -0
- package/package.json +7 -7
- package/prompts/content-detail-generator.md +3 -1
- package/tests/test-all-validation-cases.mjs +22 -0
- package/utils/auth-utils.mjs +34 -10
- package/utils/blocklet.mjs +46 -12
- package/utils/conflict-detector.mjs +131 -0
- package/utils/constants.mjs +388 -27
- package/utils/markdown-checker.mjs +14 -0
- package/utils/utils.mjs +150 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.1](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.3.0...v0.3.1) (2025-08-19)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* polish load sources pattern ([#48](https://github.com/AIGNE-io/aigne-doc-smith/issues/48)) ([5f83b91](https://github.com/AIGNE-io/aigne-doc-smith/commit/5f83b917ea6779ba79418e3ff2490eb692c3e48a))
|
|
9
|
+
|
|
10
|
+
## [0.3.0](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.2.11...v0.3.0) (2025-08-19)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **core:** polish generation context collecting workflow ([#46](https://github.com/AIGNE-io/aigne-doc-smith/issues/46)) ([687d06a](https://github.com/AIGNE-io/aigne-doc-smith/commit/687d06afd648e0e697d25e85dcc841b17c3c311c))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* optimizing help copy for running a self-hosted discuss kit ([#45](https://github.com/AIGNE-io/aigne-doc-smith/issues/45)) ([6841de8](https://github.com/AIGNE-io/aigne-doc-smith/commit/6841de817408d85ac8d993860ab431f7b8816aef))
|
|
21
|
+
|
|
3
22
|
## [0.2.11](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.2.10...v0.2.11) (2025-08-15)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -3,6 +3,8 @@ name: batchTranslate
|
|
|
3
3
|
description: 批量翻译文档到多个语言
|
|
4
4
|
skills:
|
|
5
5
|
- type: team
|
|
6
|
+
task_render_mode: collapse
|
|
7
|
+
name: translate
|
|
6
8
|
skills:
|
|
7
9
|
- ./translate.yaml
|
|
8
10
|
- type: transform
|
|
@@ -14,7 +16,7 @@ skills:
|
|
|
14
16
|
reflection:
|
|
15
17
|
reviewer: ./check-detail-result.mjs
|
|
16
18
|
is_approved: isApproved
|
|
17
|
-
max_iterations:
|
|
19
|
+
max_iterations: 5
|
|
18
20
|
return_last_on_max_iterations: true
|
|
19
21
|
task_title: Translate '{{ title }}' to '{{ language }}'
|
|
20
22
|
input_schema:
|
|
@@ -71,7 +71,7 @@ export default async function checkStructurePlan(
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const panningAgent = options.context.agents["
|
|
74
|
+
const panningAgent = options.context.agents["structurePlanning"];
|
|
75
75
|
|
|
76
76
|
const result = await options.context.invoke(panningAgent, {
|
|
77
77
|
feedback: finalFeedback || "",
|
|
@@ -4,6 +4,8 @@ description: 生成文档详情并翻译
|
|
|
4
4
|
skills:
|
|
5
5
|
- ./transform-detail-datasources.mjs
|
|
6
6
|
- type: team
|
|
7
|
+
task_render_mode: collapse
|
|
8
|
+
name: detailGenerate
|
|
7
9
|
skills:
|
|
8
10
|
- ./content-detail-generator.yaml
|
|
9
11
|
- type: transform
|
|
@@ -19,6 +21,7 @@ skills:
|
|
|
19
21
|
return_last_on_max_iterations: true
|
|
20
22
|
task_title: Generate detail for '{{ title }}'
|
|
21
23
|
- type: transform
|
|
24
|
+
task_render_mode: hide
|
|
22
25
|
jsonata: |
|
|
23
26
|
$merge([
|
|
24
27
|
$,
|
|
@@ -10,6 +10,7 @@ skills:
|
|
|
10
10
|
- ./load-config.mjs
|
|
11
11
|
- ./load-sources.mjs
|
|
12
12
|
- type: transform
|
|
13
|
+
task_render_mode: hide
|
|
13
14
|
jsonata: |
|
|
14
15
|
$merge([
|
|
15
16
|
$,
|
|
@@ -33,14 +34,10 @@ skills:
|
|
|
33
34
|
input_schema:
|
|
34
35
|
type: object
|
|
35
36
|
properties:
|
|
36
|
-
# config:
|
|
37
|
-
# type: string
|
|
38
|
-
# description: Path to the config file
|
|
39
|
-
# default: ./.aigne/doc-smith/config.yaml
|
|
40
37
|
glossary:
|
|
41
38
|
type: string
|
|
42
|
-
description: Glossary of terms for consistent terminology
|
|
43
|
-
|
|
39
|
+
description: Glossary of terms for consistent terminology, use @<file> to read from a file
|
|
40
|
+
docPath:
|
|
44
41
|
type: string
|
|
45
42
|
description: Document path to regenerate
|
|
46
43
|
feedback:
|
|
@@ -19,6 +19,7 @@ skills:
|
|
|
19
19
|
fileName: structure-plan.json
|
|
20
20
|
- type: transform
|
|
21
21
|
name: transformData
|
|
22
|
+
task_render_mode: hide
|
|
22
23
|
jsonata: |
|
|
23
24
|
$merge([
|
|
24
25
|
$,
|
|
@@ -41,13 +42,9 @@ skills:
|
|
|
41
42
|
input_schema:
|
|
42
43
|
type: object
|
|
43
44
|
properties:
|
|
44
|
-
# config:
|
|
45
|
-
# type: string
|
|
46
|
-
# description: Path to the config file
|
|
47
|
-
# default: ./.aigne/doc-smith/config.yaml
|
|
48
45
|
glossary:
|
|
49
46
|
type: string
|
|
50
|
-
description: Glossary of terms for consistent terminology
|
|
47
|
+
description: Glossary of terms for consistent terminology, use @<file> to read from a file
|
|
51
48
|
feedback:
|
|
52
49
|
type: string
|
|
53
50
|
description: Feedback for structure planning adjustments
|
|
@@ -8,7 +8,7 @@ function getActionText(isTranslate, baseText) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export default async function findItemByPath(
|
|
11
|
-
{
|
|
11
|
+
{ docPath, structurePlanResult, boardId, docsDir, isTranslate, feedback },
|
|
12
12
|
options,
|
|
13
13
|
) {
|
|
14
14
|
let foundItem = null;
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
DOCUMENT_STYLES,
|
|
6
|
+
SUPPORTED_LANGUAGES,
|
|
7
|
+
TARGET_AUDIENCES,
|
|
8
|
+
READER_KNOWLEDGE_LEVELS,
|
|
9
|
+
DOCUMENTATION_DEPTH,
|
|
10
|
+
PURPOSE_TO_KNOWLEDGE_MAPPING,
|
|
11
|
+
DEPTH_RECOMMENDATION_LOGIC,
|
|
12
|
+
} from "../utils/constants.mjs";
|
|
13
|
+
import {
|
|
14
|
+
getAvailablePaths,
|
|
15
|
+
getProjectInfo,
|
|
16
|
+
validatePath,
|
|
17
|
+
detectSystemLanguage,
|
|
18
|
+
} from "../utils/utils.mjs";
|
|
19
|
+
import { validateSelection, getFilteredOptions } from "../utils/conflict-detector.mjs";
|
|
6
20
|
|
|
7
21
|
// UI constants
|
|
8
22
|
const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
|
|
@@ -31,72 +45,172 @@ export default async function init(
|
|
|
31
45
|
// Collect user information
|
|
32
46
|
const input = {};
|
|
33
47
|
|
|
34
|
-
// 1.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
choices: Object.entries(DOCUMENT_STYLES)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
// 1. Primary purpose - what's the main outcome you want readers to achieve?
|
|
49
|
+
const purposeChoices = await options.prompts.checkbox({
|
|
50
|
+
message:
|
|
51
|
+
"📝 Step 1/8: What's the main outcome you want readers to achieve? (Select all that apply)",
|
|
52
|
+
choices: Object.entries(DOCUMENT_STYLES)
|
|
53
|
+
.filter(([key]) => key !== "custom") // Remove custom option for multiselect
|
|
54
|
+
.map(([key, style]) => ({
|
|
55
|
+
name: `${style.name}`,
|
|
56
|
+
description: style.description,
|
|
57
|
+
value: key,
|
|
58
|
+
})),
|
|
59
|
+
validate: (input) => {
|
|
60
|
+
if (input.length === 0) {
|
|
61
|
+
return "Please select at least one purpose.";
|
|
62
|
+
}
|
|
63
|
+
return validateSelection("documentPurpose", input);
|
|
64
|
+
},
|
|
42
65
|
});
|
|
43
66
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
message: "
|
|
67
|
+
// Follow-up logic: If ONLY mixedPurpose selected, ask for priority ranking
|
|
68
|
+
let prioritizedPurposes = purposeChoices;
|
|
69
|
+
if (purposeChoices.length === 1 && purposeChoices.includes("mixedPurpose")) {
|
|
70
|
+
const topPriorities = await options.prompts.checkbox({
|
|
71
|
+
message: "🎯 Which is most important? (Select top 2 priorities)",
|
|
72
|
+
choices: Object.entries(DOCUMENT_STYLES)
|
|
73
|
+
.filter(([key]) => key !== "custom" && key !== "mixedPurpose") // Filter out custom and mixedPurpose
|
|
74
|
+
.map(([key, style]) => ({
|
|
75
|
+
name: `${style.name}`,
|
|
76
|
+
description: style.description,
|
|
77
|
+
value: key,
|
|
78
|
+
})),
|
|
79
|
+
validate: (input) => {
|
|
80
|
+
if (input.length === 0) {
|
|
81
|
+
return "Please select at least one priority.";
|
|
82
|
+
}
|
|
83
|
+
if (input.length > 2) {
|
|
84
|
+
return "Please select maximum 2 priorities.";
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
},
|
|
49
88
|
});
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
|
|
89
|
+
|
|
90
|
+
// Replace mixedPurpose with selected priorities
|
|
91
|
+
prioritizedPurposes = topPriorities;
|
|
53
92
|
}
|
|
54
93
|
|
|
55
|
-
|
|
94
|
+
// Save document purpose choices as keys
|
|
95
|
+
input.documentPurpose = prioritizedPurposes;
|
|
96
|
+
|
|
97
|
+
// 2. Target audience - who will be reading this most often?
|
|
98
|
+
const audienceChoices = await options.prompts.checkbox({
|
|
99
|
+
message: "👥 Step 2/8: Who will be reading this most often? (Select all that apply)",
|
|
100
|
+
choices: Object.entries(TARGET_AUDIENCES)
|
|
101
|
+
.filter(([key]) => key !== "custom") // Remove custom option for multiselect
|
|
102
|
+
.map(([key, audience]) => ({
|
|
103
|
+
name: `${audience.name}`,
|
|
104
|
+
description: audience.description,
|
|
105
|
+
value: key,
|
|
106
|
+
})),
|
|
107
|
+
validate: (input) => {
|
|
108
|
+
if (input.length === 0) {
|
|
109
|
+
return "Please select at least one audience.";
|
|
110
|
+
}
|
|
111
|
+
return validateSelection("targetAudienceTypes", input);
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Save target audience choices as keys
|
|
116
|
+
input.targetAudienceTypes = audienceChoices;
|
|
56
117
|
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
118
|
+
// 3. Reader knowledge level - what do readers typically know when they arrive?
|
|
119
|
+
// Determine default based on selected purposes using mapping
|
|
120
|
+
const mappedPurpose = prioritizedPurposes.find(
|
|
121
|
+
(purpose) => PURPOSE_TO_KNOWLEDGE_MAPPING[purpose],
|
|
122
|
+
);
|
|
123
|
+
const defaultKnowledge = mappedPurpose ? PURPOSE_TO_KNOWLEDGE_MAPPING[mappedPurpose] : null;
|
|
124
|
+
|
|
125
|
+
// Filter knowledge level options based on previous selections
|
|
126
|
+
const { filteredOptions: filteredKnowledgeOptions } = getFilteredOptions(
|
|
127
|
+
"readerKnowledgeLevel",
|
|
128
|
+
{ documentPurpose: prioritizedPurposes, targetAudienceTypes: audienceChoices },
|
|
129
|
+
READER_KNOWLEDGE_LEVELS,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const knowledgeChoice = await options.prompts.select({
|
|
133
|
+
message: "🧠 Step 3/8: What do readers typically know when they arrive?",
|
|
134
|
+
choices: Object.entries(filteredKnowledgeOptions).map(([key, level]) => ({
|
|
135
|
+
name: `${level.name}`,
|
|
136
|
+
description: level.description,
|
|
63
137
|
value: key,
|
|
64
138
|
})),
|
|
139
|
+
default: defaultKnowledge,
|
|
65
140
|
});
|
|
66
141
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
142
|
+
// Save reader knowledge level choice as key
|
|
143
|
+
input.readerKnowledgeLevel = knowledgeChoice;
|
|
144
|
+
|
|
145
|
+
// 4. Documentation depth - how comprehensive should the documentation be?
|
|
146
|
+
// Determine default based on priority: Purpose > Audience > Knowledge Level
|
|
147
|
+
const getDepthDefault = () => {
|
|
148
|
+
// Check priority order: purposes -> audiences -> knowledgeLevels
|
|
149
|
+
const checks = [
|
|
150
|
+
() => {
|
|
151
|
+
const purpose = prioritizedPurposes.find((p) => DEPTH_RECOMMENDATION_LOGIC.purposes[p]);
|
|
152
|
+
return purpose ? DEPTH_RECOMMENDATION_LOGIC.purposes[purpose] : null;
|
|
153
|
+
},
|
|
154
|
+
() => {
|
|
155
|
+
const audience = audienceChoices.find((a) => DEPTH_RECOMMENDATION_LOGIC.audiences[a]);
|
|
156
|
+
return audience ? DEPTH_RECOMMENDATION_LOGIC.audiences[audience] : null;
|
|
157
|
+
},
|
|
158
|
+
() => DEPTH_RECOMMENDATION_LOGIC.knowledgeLevels[knowledgeChoice] || null,
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
return checks.find((check) => check())?.() || null;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const defaultDepth = getDepthDefault();
|
|
165
|
+
|
|
166
|
+
// Filter documentation depth options based on all previous selections
|
|
167
|
+
const { filteredOptions: filteredDepthOptions } = getFilteredOptions(
|
|
168
|
+
"documentationDepth",
|
|
169
|
+
{
|
|
170
|
+
documentPurpose: prioritizedPurposes,
|
|
171
|
+
targetAudienceTypes: audienceChoices,
|
|
172
|
+
readerKnowledgeLevel: knowledgeChoice,
|
|
173
|
+
},
|
|
174
|
+
DOCUMENTATION_DEPTH,
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const depthChoice = await options.prompts.select({
|
|
178
|
+
message: "📊 Step 4/8: How comprehensive should the documentation be?",
|
|
179
|
+
choices: Object.entries(filteredDepthOptions).map(([key, depth]) => ({
|
|
180
|
+
name: `${depth.name}`,
|
|
181
|
+
description: depth.description,
|
|
182
|
+
value: key,
|
|
183
|
+
})),
|
|
184
|
+
default: defaultDepth,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Save documentation depth choice as key
|
|
188
|
+
input.documentationDepth = depthChoice;
|
|
77
189
|
|
|
78
|
-
|
|
190
|
+
// 5. Language settings
|
|
191
|
+
// Detect system language and use as default
|
|
192
|
+
const systemLanguage = detectSystemLanguage();
|
|
79
193
|
|
|
80
|
-
// 3. Language settings
|
|
81
194
|
// Let user select primary language from supported list
|
|
82
195
|
const primaryLanguageChoice = await options.prompts.select({
|
|
83
|
-
message: "🌐 Step
|
|
196
|
+
message: "🌐 Step 5/8: Choose primary documentation language:",
|
|
84
197
|
choices: SUPPORTED_LANGUAGES.map((lang) => ({
|
|
85
198
|
name: `${lang.label} - ${lang.sample}`,
|
|
86
199
|
value: lang.code,
|
|
87
200
|
})),
|
|
201
|
+
default: systemLanguage,
|
|
88
202
|
});
|
|
89
203
|
|
|
90
204
|
input.locale = primaryLanguageChoice;
|
|
91
205
|
|
|
92
|
-
//
|
|
206
|
+
// 6. Translation languages
|
|
93
207
|
// Filter out the primary language from available choices
|
|
94
208
|
const availableTranslationLanguages = SUPPORTED_LANGUAGES.filter(
|
|
95
209
|
(lang) => lang.code !== primaryLanguageChoice,
|
|
96
210
|
);
|
|
97
211
|
|
|
98
212
|
const translateLanguageChoices = await options.prompts.checkbox({
|
|
99
|
-
message: "🔄 Step
|
|
213
|
+
message: "🔄 Step 6/8: Select translation languages:",
|
|
100
214
|
choices: availableTranslationLanguages.map((lang) => ({
|
|
101
215
|
name: `${lang.label} - ${lang.sample}`,
|
|
102
216
|
value: lang.code,
|
|
@@ -105,15 +219,15 @@ export default async function init(
|
|
|
105
219
|
|
|
106
220
|
input.translateLanguages = translateLanguageChoices;
|
|
107
221
|
|
|
108
|
-
//
|
|
222
|
+
// 7. Documentation directory
|
|
109
223
|
const docsDirInput = await options.prompts.input({
|
|
110
|
-
message: `📁 Step
|
|
224
|
+
message: `📁 Step 7/8: Where to save generated docs:`,
|
|
111
225
|
default: `${outputPath}/docs`,
|
|
112
226
|
});
|
|
113
227
|
input.docsDir = docsDirInput.trim() || `${outputPath}/docs`;
|
|
114
228
|
|
|
115
|
-
//
|
|
116
|
-
console.log("\n🔍 Step
|
|
229
|
+
// 8. Source code paths
|
|
230
|
+
console.log("\n🔍 Step 8/8: Source Code Paths");
|
|
117
231
|
console.log("Enter paths to analyze for documentation (e.g., ./src, ./lib)");
|
|
118
232
|
console.log("💡 If no paths are configured, './' will be used as default");
|
|
119
233
|
|
|
@@ -221,16 +335,70 @@ function generateYAML(input) {
|
|
|
221
335
|
yaml += `projectLogo: ${input.projectLogo || ""}\n`;
|
|
222
336
|
yaml += `\n`;
|
|
223
337
|
|
|
224
|
-
// Add
|
|
225
|
-
yaml +=
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
338
|
+
// Add documentation configuration choices with all available options
|
|
339
|
+
yaml += `# =============================================================================\n`;
|
|
340
|
+
yaml += `# Documentation Configuration\n`;
|
|
341
|
+
yaml += `# =============================================================================\n\n`;
|
|
342
|
+
|
|
343
|
+
// Document Purpose with all available options
|
|
344
|
+
yaml += `# Purpose: What's the main outcome you want readers to achieve?\n`;
|
|
345
|
+
yaml += `# Available options (uncomment and modify as needed):\n`;
|
|
346
|
+
Object.entries(DOCUMENT_STYLES).forEach(([key, style]) => {
|
|
347
|
+
if (key !== "custom") {
|
|
348
|
+
yaml += `# ${key.padEnd(16)} - ${style.name}: ${style.description}\n`;
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
yaml += `documentPurpose:\n`;
|
|
352
|
+
if (input.documentPurpose && input.documentPurpose.length > 0) {
|
|
353
|
+
input.documentPurpose.forEach((purpose) => {
|
|
354
|
+
yaml += ` - ${purpose}\n`;
|
|
355
|
+
});
|
|
230
356
|
}
|
|
357
|
+
yaml += `\n`;
|
|
358
|
+
|
|
359
|
+
// Target Audience Types with all available options
|
|
360
|
+
yaml += `# Target Audience: Who will be reading this most often?\n`;
|
|
361
|
+
yaml += `# Available options (uncomment and modify as needed):\n`;
|
|
362
|
+
Object.entries(TARGET_AUDIENCES).forEach(([key, audience]) => {
|
|
363
|
+
if (key !== "custom") {
|
|
364
|
+
yaml += `# ${key.padEnd(16)} - ${audience.name}: ${audience.description}\n`;
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
yaml += `targetAudienceTypes:\n`;
|
|
368
|
+
if (input.targetAudienceTypes && input.targetAudienceTypes.length > 0) {
|
|
369
|
+
input.targetAudienceTypes.forEach((audience) => {
|
|
370
|
+
yaml += ` - ${audience}\n`;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
yaml += `\n`;
|
|
374
|
+
|
|
375
|
+
// Reader Knowledge Level with all available options
|
|
376
|
+
yaml += `# Reader Knowledge Level: What do readers typically know when they arrive?\n`;
|
|
377
|
+
yaml += `# Available options (uncomment and modify as needed):\n`;
|
|
378
|
+
Object.entries(READER_KNOWLEDGE_LEVELS).forEach(([key, level]) => {
|
|
379
|
+
yaml += `# ${key.padEnd(20)} - ${level.name}: ${level.description}\n`;
|
|
380
|
+
});
|
|
381
|
+
yaml += `readerKnowledgeLevel: ${input.readerKnowledgeLevel || ""}\n`;
|
|
382
|
+
yaml += `\n`;
|
|
383
|
+
|
|
384
|
+
// Documentation Depth with all available options
|
|
385
|
+
yaml += `# Documentation Depth: How comprehensive should the documentation be?\n`;
|
|
386
|
+
yaml += `# Available options (uncomment and modify as needed):\n`;
|
|
387
|
+
Object.entries(DOCUMENTATION_DEPTH).forEach(([key, depth]) => {
|
|
388
|
+
yaml += `# ${key.padEnd(18)} - ${depth.name}: ${depth.description}\n`;
|
|
389
|
+
});
|
|
390
|
+
yaml += `documentationDepth: ${input.documentationDepth || ""}\n`;
|
|
391
|
+
yaml += `\n`;
|
|
392
|
+
|
|
393
|
+
// Custom Documentation Rules and Requirements
|
|
394
|
+
yaml += `# Custom Rules: Define specific documentation generation rules and requirements\n`;
|
|
395
|
+
yaml += `rules: |\n`;
|
|
396
|
+
yaml += ` \n\n`;
|
|
231
397
|
|
|
232
|
-
//
|
|
233
|
-
yaml +=
|
|
398
|
+
// Target Audience Description
|
|
399
|
+
yaml += `# Target Audience: Describe your specific target audience and their characteristics\n`;
|
|
400
|
+
yaml += `targetAudience: |\n`;
|
|
401
|
+
yaml += ` \n\n`;
|
|
234
402
|
|
|
235
403
|
// Add language settings
|
|
236
404
|
yaml += `locale: ${input.locale}\n`;
|
package/agents/load-config.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parse } from "yaml";
|
|
4
|
+
import { processConfigFields } from "../utils/utils.mjs";
|
|
4
5
|
|
|
5
6
|
export default async function loadConfig({ config, appUrl }) {
|
|
6
7
|
const configPath = path.join(process.cwd(), config);
|
|
@@ -20,9 +21,12 @@ export default async function loadConfig({ config, appUrl }) {
|
|
|
20
21
|
const parsedConfig = parse(configContent);
|
|
21
22
|
|
|
22
23
|
if (appUrl) {
|
|
23
|
-
parsedConfig.appUrl = appUrl
|
|
24
|
+
parsedConfig.appUrl = appUrl.includes("://") ? appUrl : `https://${appUrl}`;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
// Parse new configuration fields and convert keys to actual content
|
|
28
|
+
const processedConfig = processConfigFields(parsedConfig);
|
|
29
|
+
|
|
26
30
|
return {
|
|
27
31
|
nodeName: "Section",
|
|
28
32
|
locale: "en",
|
|
@@ -31,6 +35,7 @@ export default async function loadConfig({ config, appUrl }) {
|
|
|
31
35
|
outputDir: "./.aigne/doc-smith/output",
|
|
32
36
|
lastGitHead: parsedConfig.lastGitHead || "",
|
|
33
37
|
...parsedConfig,
|
|
38
|
+
...processedConfig,
|
|
34
39
|
};
|
|
35
40
|
} catch (error) {
|
|
36
41
|
console.error(`Error parsing config file: ${error.message}`);
|
|
@@ -51,3 +56,5 @@ loadConfig.input_schema = {
|
|
|
51
56
|
},
|
|
52
57
|
},
|
|
53
58
|
};
|
|
59
|
+
|
|
60
|
+
loadConfig.task_render_mode = "hide";
|
package/agents/load-sources.mjs
CHANGED
package/agents/publish-docs.mjs
CHANGED
|
@@ -2,6 +2,8 @@ import { basename, join } from "node:path";
|
|
|
2
2
|
import { publishDocs as publishDocsFn } from "@aigne/publish-docs";
|
|
3
3
|
import { getAccessToken } from "../utils/auth-utils.mjs";
|
|
4
4
|
import { loadConfigFromFile, saveValueToConfig } from "../utils/utils.mjs";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { DISCUSS_KIT_STORE_URL } from "../utils/constants.mjs";
|
|
5
7
|
|
|
6
8
|
const DEFAULT_APP_URL = "https://docsmith.aigne.io";
|
|
7
9
|
|
|
@@ -39,6 +41,10 @@ export default async function publishDocs(
|
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
if (choice === "custom") {
|
|
44
|
+
console.log(
|
|
45
|
+
`${chalk.bold("\n💡 Tips")}\n\n` +
|
|
46
|
+
`Start here to run your own website:\n${chalk.cyan(DISCUSS_KIT_STORE_URL)}\n`,
|
|
47
|
+
);
|
|
42
48
|
const userInput = await options.prompts.input({
|
|
43
49
|
message: "Please enter your Discuss Kit platform URL:",
|
|
44
50
|
validate: (input) => {
|
|
@@ -98,12 +104,13 @@ export default async function publishDocs(
|
|
|
98
104
|
"⚠️ Warning: boardId is auto-generated by system, please do not edit manually",
|
|
99
105
|
);
|
|
100
106
|
}
|
|
107
|
+
const message = `✅ Documentation Published Successfully!`;
|
|
108
|
+
return {
|
|
109
|
+
message,
|
|
110
|
+
};
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
message,
|
|
106
|
-
};
|
|
113
|
+
return {};
|
|
107
114
|
} catch (error) {
|
|
108
115
|
return {
|
|
109
116
|
message: `❌ Failed to publish docs: ${error.message}`,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
type: team
|
|
2
|
-
name:
|
|
2
|
+
name: structurePlanning
|
|
3
3
|
description: A team of agents that plan the structure of the documentation.
|
|
4
4
|
skills:
|
|
5
5
|
- structure-planning.yaml
|
|
6
6
|
task_title: Plan the structure of the documentation
|
|
7
|
+
task_render_mode: collapse
|
|
7
8
|
reflection:
|
|
8
9
|
reviewer: check-structure-planning-result.yaml
|
|
9
10
|
is_approved: isValid
|
package/agents/save-output.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@aigne/aigne-hub": "^0.4
|
|
16
|
-
"@aigne/anthropic": "^0.11.
|
|
17
|
-
"@aigne/cli": "^1.
|
|
18
|
-
"@aigne/core": "^1.
|
|
19
|
-
"@aigne/gemini": "^0.9.
|
|
20
|
-
"@aigne/openai": "^0.11.
|
|
15
|
+
"@aigne/aigne-hub": "^0.6.4",
|
|
16
|
+
"@aigne/anthropic": "^0.11.4",
|
|
17
|
+
"@aigne/cli": "^1.37.0",
|
|
18
|
+
"@aigne/core": "^1.51.0",
|
|
19
|
+
"@aigne/gemini": "^0.9.4",
|
|
20
|
+
"@aigne/openai": "^0.11.4",
|
|
21
21
|
"@aigne/publish-docs": "^0.5.4",
|
|
22
22
|
"chalk": "^5.5.0",
|
|
23
23
|
"dompurify": "^3.2.6",
|
|
@@ -52,6 +52,8 @@ parentId: {{parentId}}
|
|
|
52
52
|
|
|
53
53
|
<user_rules>
|
|
54
54
|
{{ rules }}
|
|
55
|
+
|
|
56
|
+
** 使用 {{ locale }} 语言输出内容 **
|
|
55
57
|
</user_rules>
|
|
56
58
|
|
|
57
59
|
<rules>
|
|
@@ -96,5 +98,5 @@ parentId: {{parentId}}
|
|
|
96
98
|
|
|
97
99
|
1. 输内容为{{nodeName}}的详细文本。
|
|
98
100
|
2. 直接输出{{nodeName}}内容,不要包含其他信息.
|
|
99
|
-
3.
|
|
101
|
+
3. 仅参考示例中的风格,**以语言 {{locale}} 输出内容 **
|
|
100
102
|
</output_schema>
|