@aigne/doc-smith 0.6.0 → 0.7.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/.aigne/doc-smith/config.yaml +70 -0
- package/.aigne/doc-smith/output/structure-plan.json +152 -0
- package/.aigne/doc-smith/preferences.yml +31 -0
- package/.aigne/doc-smith/upload-cache.yaml +288 -0
- package/.github/workflows/ci.yml +46 -0
- package/.github/workflows/reviewer.yml +2 -1
- package/CHANGELOG.md +17 -0
- package/README.md +33 -15
- package/agents/chat.yaml +30 -0
- package/agents/check-structure-plan.mjs +1 -1
- package/agents/docs-fs.yaml +25 -0
- package/agents/exit.mjs +6 -0
- package/agents/feedback-refiner.yaml +5 -1
- package/agents/find-items-by-paths.mjs +10 -4
- package/agents/fs.mjs +60 -0
- package/agents/input-generator.mjs +150 -91
- package/agents/load-config.mjs +0 -5
- package/agents/load-sources.mjs +61 -8
- package/agents/publish-docs.mjs +27 -12
- package/agents/retranslate.yaml +1 -1
- package/agents/team-publish-docs.yaml +2 -2
- package/aigne.yaml +1 -0
- package/docs/_sidebar.md +17 -0
- package/docs/advanced-how-it-works.md +104 -0
- package/docs/advanced-how-it-works.zh.md +104 -0
- package/docs/advanced-quality-assurance.md +64 -0
- package/docs/advanced-quality-assurance.zh.md +64 -0
- package/docs/advanced.md +28 -0
- package/docs/advanced.zh.md +28 -0
- package/docs/changelog.md +272 -0
- package/docs/changelog.zh.md +272 -0
- package/docs/cli-reference.md +185 -0
- package/docs/cli-reference.zh.md +185 -0
- package/docs/configuration-interactive-setup.md +82 -0
- package/docs/configuration-interactive-setup.zh.md +82 -0
- package/docs/configuration-language-support.md +64 -0
- package/docs/configuration-language-support.zh.md +64 -0
- package/docs/configuration-llm-setup.md +90 -0
- package/docs/configuration-llm-setup.zh.md +90 -0
- package/docs/configuration-preferences.md +122 -0
- package/docs/configuration-preferences.zh.md +123 -0
- package/docs/configuration.md +173 -0
- package/docs/configuration.zh.md +173 -0
- package/docs/features-generate-documentation.md +82 -0
- package/docs/features-generate-documentation.zh.md +82 -0
- package/docs/features-publish-your-docs.md +98 -0
- package/docs/features-publish-your-docs.zh.md +98 -0
- package/docs/features-translate-documentation.md +83 -0
- package/docs/features-translate-documentation.zh.md +83 -0
- package/docs/features-update-and-refine.md +86 -0
- package/docs/features-update-and-refine.zh.md +86 -0
- package/docs/features.md +56 -0
- package/docs/features.zh.md +56 -0
- package/docs/getting-started.md +74 -0
- package/docs/getting-started.zh.md +74 -0
- package/docs/overview.md +48 -0
- package/docs/overview.zh.md +48 -0
- package/media.md +19 -0
- package/package.json +13 -10
- package/prompts/content-detail-generator.md +7 -3
- package/prompts/document/custom-components.md +80 -0
- package/prompts/document/d2-chart/diy-examples.md +44 -0
- package/prompts/document/d2-chart/official-examples.md +708 -0
- package/prompts/document/d2-chart/rules.md +48 -0
- package/prompts/document/detail-generator.md +12 -15
- package/prompts/document/structure-planning.md +1 -3
- package/prompts/feedback-refiner.md +81 -60
- package/prompts/structure-planning.md +20 -3
- package/tests/check-detail-result.test.mjs +3 -4
- package/tests/conflict-resolution.test.mjs +237 -0
- package/tests/input-generator.test.mjs +940 -0
- package/tests/load-sources.test.mjs +627 -3
- package/tests/preferences-utils.test.mjs +94 -0
- package/tests/save-value-to-config.test.mjs +182 -5
- package/tests/utils.test.mjs +49 -0
- package/utils/conflict-detector.mjs +72 -1
- package/utils/constants.mjs +125 -124
- package/utils/kroki-utils.mjs +162 -0
- package/utils/markdown-checker.mjs +98 -70
- package/utils/utils.mjs +96 -28
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ Optimize specific documents with targeted feedback:
|
|
|
103
103
|
aigne doc update
|
|
104
104
|
|
|
105
105
|
# Update a specific document
|
|
106
|
-
aigne doc update --
|
|
106
|
+
aigne doc update --docs overview.md --feedback "Add more comprehensive FAQ entries"
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
**Interactive Mode:** When run without parameters, `aigne doc update` will present an interactive menu for you to select which document to regenerate and provide feedback.
|
|
@@ -122,6 +122,29 @@ aigne doc generate --feedback "Add more detailed installation guide and troubles
|
|
|
122
122
|
|
|
123
123
|
**Structure Optimization:** Use `aigne doc generate` with `--feedback` to refine the overall documentation structure, add new sections, or reorganize existing content.
|
|
124
124
|
|
|
125
|
+
#### Document Translation
|
|
126
|
+
|
|
127
|
+
Translate existing documentation to multiple languages:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Translate specific documents to multiple languages
|
|
131
|
+
aigne doc translate --langs zh --langs ja --docs examples.md --docs overview.md
|
|
132
|
+
|
|
133
|
+
# Interactive translation with document and language selection
|
|
134
|
+
aigne doc translate
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Command Parameters:**
|
|
138
|
+
- `--langs`: Specify target languages (can be used multiple times)
|
|
139
|
+
- `--docs`: Specify document paths to translate (can be used multiple times)
|
|
140
|
+
- `--feedback`: Provide feedback for translation improvement
|
|
141
|
+
- `--glossary`: Use a glossary file for consistent terminology (@path/to/glossary.md)
|
|
142
|
+
|
|
143
|
+
**Interactive Mode:** When run without parameters, `aigne doc translate` will present interactive menus to:
|
|
144
|
+
- Select documents to translate from your documentation
|
|
145
|
+
- Choose target languages from 12 supported languages
|
|
146
|
+
- Add new translation languages to your configuration
|
|
147
|
+
|
|
125
148
|
#### Publishing to Discuss Kit
|
|
126
149
|
|
|
127
150
|
Publish your documentation to Discuss Kit platforms:
|
|
@@ -185,6 +208,15 @@ aigne doc generate --feedback "Remove About section and add API Reference"
|
|
|
185
208
|
|
|
186
209
|
# Update specific document
|
|
187
210
|
aigne doc update --doc-path /faq --feedback "Add more comprehensive FAQ entries"
|
|
211
|
+
|
|
212
|
+
# Translate documents to multiple languages
|
|
213
|
+
aigne doc translate --langs zh --langs ja --docs examples.md --docs overview.md
|
|
214
|
+
|
|
215
|
+
# Interactive translation (select documents and languages)
|
|
216
|
+
aigne doc translate
|
|
217
|
+
|
|
218
|
+
# Translate with custom glossary and feedback
|
|
219
|
+
aigne doc translate --glossary @glossary.md --feedback "Use technical terminology consistently"
|
|
188
220
|
```
|
|
189
221
|
|
|
190
222
|
### Publishing and Integration
|
|
@@ -198,17 +230,3 @@ aigne doc publish --appUrl https://your-discuss-kit-instance.com
|
|
|
198
230
|
|
|
199
231
|
|
|
200
232
|
```
|
|
201
|
-
|
|
202
|
-
### Development Commands
|
|
203
|
-
|
|
204
|
-
```shell
|
|
205
|
-
# Development and debugging commands using npx to run local code
|
|
206
|
-
npx --no doc-smith run --entry-agent init
|
|
207
|
-
npx --no doc-smith run --entry-agent generate
|
|
208
|
-
npx --no doc-smith run --entry-agent update
|
|
209
|
-
npx --no doc-smith run --entry-agent translate
|
|
210
|
-
npx --no doc-smith run --entry-agent publish
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**Development Mode:** These commands use `npx` to run the local code version for development and debugging purposes, bypassing the globally installed CLI.
|
|
214
|
-
|
package/agents/chat.yaml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type: ai
|
|
2
|
+
name: chat
|
|
3
|
+
description: Start interactive document generation assistant
|
|
4
|
+
instructions: |
|
|
5
|
+
You are a professional document generation assistant that helps users create, modify, and manage documentation through interactive chat. Your primary role is to understand user requirements and intelligently call upon various specialized skills to complete documentation tasks efficiently.
|
|
6
|
+
|
|
7
|
+
Core Capabilities:
|
|
8
|
+
- Generate comprehensive documentation from user inputs and specifications
|
|
9
|
+
- Regenerate and refine document details based on feedback
|
|
10
|
+
- Translate and localize documentation content
|
|
11
|
+
- Publish and manage team documentation workflows
|
|
12
|
+
- Provide interactive guidance throughout the document creation process
|
|
13
|
+
|
|
14
|
+
Interaction Guidelines:
|
|
15
|
+
- Engage users in a professional yet friendly manner
|
|
16
|
+
- Ask clarifying questions to understand specific documentation needs
|
|
17
|
+
- Suggest appropriate skills and workflows based on user requests
|
|
18
|
+
- Provide clear explanations of available capabilities and processes
|
|
19
|
+
- Maintain context throughout multi-step documentation tasks
|
|
20
|
+
- Offer proactive suggestions for improving document quality and structure
|
|
21
|
+
input_key: message
|
|
22
|
+
memory: true
|
|
23
|
+
skills:
|
|
24
|
+
- ./input-generator.mjs
|
|
25
|
+
- ./docs-generator.yaml
|
|
26
|
+
- ./detail-regenerator.yaml
|
|
27
|
+
- ./team-publish-docs.yaml
|
|
28
|
+
- ./retranslate.yaml
|
|
29
|
+
- ./docs-fs.yaml
|
|
30
|
+
- ./exit.mjs
|
|
@@ -63,7 +63,7 @@ export default async function checkStructurePlan(
|
|
|
63
63
|
1. 对于新增的内容,可以根据需要新增节点,或补充到原有节点展示
|
|
64
64
|
2. 谨慎删除节点,除非节点关联 sourceIds 都被删除了
|
|
65
65
|
3. 不能修改原有节点的 path
|
|
66
|
-
4. 根据最新的 Data Sources
|
|
66
|
+
4. 根据最新的 Data Sources 可以按需要更新节点的 sourceIds。
|
|
67
67
|
`;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
type: team
|
|
2
|
+
name: docs_fs_actor
|
|
3
|
+
description: File system operations for documentation management
|
|
4
|
+
skills:
|
|
5
|
+
- ./load-config.mjs
|
|
6
|
+
- url: ./fs.mjs
|
|
7
|
+
default_input:
|
|
8
|
+
rootDir:
|
|
9
|
+
$get: docsDir
|
|
10
|
+
input_schema:
|
|
11
|
+
type: object
|
|
12
|
+
properties:
|
|
13
|
+
action:
|
|
14
|
+
type: "string"
|
|
15
|
+
enum: ["read_file", "write_file", "delete_file", "list_directory"]
|
|
16
|
+
description:
|
|
17
|
+
"The file system action to perform, available actions are: read_file, write_file, delete_file, list_directory"
|
|
18
|
+
path:
|
|
19
|
+
type: "string"
|
|
20
|
+
description: "The path to the file or directory to operate on"
|
|
21
|
+
content:
|
|
22
|
+
type: "string"
|
|
23
|
+
description: "The content to write to the file, required for write_file action"
|
|
24
|
+
required: ["action", "path"]
|
|
25
|
+
task_render_mode: hide
|
package/agents/exit.mjs
ADDED
|
@@ -41,8 +41,12 @@ output_schema:
|
|
|
41
41
|
limitToInputPaths:
|
|
42
42
|
type: boolean
|
|
43
43
|
description: Whether to limit to the "paths specified in current input" when used subsequently
|
|
44
|
+
reason:
|
|
45
|
+
type: string
|
|
46
|
+
description: Explanation of why the save decision was made and how the rule and scope were derived
|
|
44
47
|
required:
|
|
45
48
|
- rule
|
|
46
49
|
- scope
|
|
47
50
|
- save
|
|
48
|
-
- limitToInputPaths
|
|
51
|
+
- limitToInputPaths
|
|
52
|
+
- reason
|
|
@@ -26,10 +26,16 @@ export default async function selectedDocs(
|
|
|
26
26
|
// Let user select multiple files
|
|
27
27
|
selectedFiles = await options.prompts.checkbox({
|
|
28
28
|
message: getActionText(isTranslate, "Select documents to {action}:"),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
source: (term) => {
|
|
30
|
+
const choices = mainLanguageFiles.map((file) => ({
|
|
31
|
+
name: file,
|
|
32
|
+
value: file,
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
if (!term) return choices;
|
|
36
|
+
|
|
37
|
+
return choices.filter((choice) => choice.name.toLowerCase().includes(term.toLowerCase()));
|
|
38
|
+
},
|
|
33
39
|
validate: (answer) => {
|
|
34
40
|
if (answer.length === 0) {
|
|
35
41
|
return "Please select at least one document";
|
package/agents/fs.mjs
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export default async function fs({ rootDir, action, path, content }) {
|
|
5
|
+
if (!rootDir) throw new Error("Root directory is not specified");
|
|
6
|
+
|
|
7
|
+
path = join(rootDir, path);
|
|
8
|
+
|
|
9
|
+
switch (action) {
|
|
10
|
+
case "read_file":
|
|
11
|
+
return {
|
|
12
|
+
status: "ok",
|
|
13
|
+
path,
|
|
14
|
+
content: await readFile(path, "utf-8"),
|
|
15
|
+
};
|
|
16
|
+
case "write_file": {
|
|
17
|
+
await mkdir(dirname(path), { recursive: true });
|
|
18
|
+
await writeFile(path, content || "");
|
|
19
|
+
return {
|
|
20
|
+
status: "ok",
|
|
21
|
+
path,
|
|
22
|
+
content,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
case "delete_file":
|
|
26
|
+
await rm(path, { recursive: true, force: true });
|
|
27
|
+
return {
|
|
28
|
+
status: "ok",
|
|
29
|
+
path,
|
|
30
|
+
};
|
|
31
|
+
case "list_directory":
|
|
32
|
+
return {
|
|
33
|
+
status: "ok",
|
|
34
|
+
entries: await readdir(path, { withFileTypes: true }).then((list) =>
|
|
35
|
+
list.map((entry) => ({
|
|
36
|
+
path: join(entry.parentPath, entry.name),
|
|
37
|
+
isDirectory: entry.isDirectory(),
|
|
38
|
+
})),
|
|
39
|
+
),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fs.input_schema = {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
action: {
|
|
48
|
+
type: "string",
|
|
49
|
+
enum: ["read_file", "write_file", "delete_file", "list_directory"],
|
|
50
|
+
description:
|
|
51
|
+
"The file system action to perform, available actions are: read_file, write_file, delete_file, list_directory",
|
|
52
|
+
},
|
|
53
|
+
path: { type: "string", description: "The path to the file or directory to operate on" },
|
|
54
|
+
content: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "The content to write to the file, required for write_file action",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
required: ["action", "path"],
|
|
60
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
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 { stringify as yamlStringify } from "yaml";
|
|
4
5
|
import { getFilteredOptions, validateSelection } from "../utils/conflict-detector.mjs";
|
|
5
6
|
import {
|
|
6
7
|
DEPTH_RECOMMENDATION_LOGIC,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
detectSystemLanguage,
|
|
16
17
|
getAvailablePaths,
|
|
17
18
|
getProjectInfo,
|
|
19
|
+
isGlobPattern,
|
|
18
20
|
validatePath,
|
|
19
21
|
} from "../utils/utils.mjs";
|
|
20
22
|
|
|
@@ -34,7 +36,9 @@ export default async function init(
|
|
|
34
36
|
) {
|
|
35
37
|
if (skipIfExists) {
|
|
36
38
|
const filePath = join(outputPath, fileName);
|
|
37
|
-
|
|
39
|
+
const configContent = await readFile(filePath, "utf8").catch(() => null);
|
|
40
|
+
// Only skip if file exists AND has non-empty content
|
|
41
|
+
if (configContent && configContent.trim() !== "") {
|
|
38
42
|
return {};
|
|
39
43
|
}
|
|
40
44
|
}
|
|
@@ -228,19 +232,20 @@ export default async function init(
|
|
|
228
232
|
// 8. Source code paths
|
|
229
233
|
console.log("\n🔍 [8/8]: Source Code Paths");
|
|
230
234
|
console.log("Enter paths to analyze for documentation (e.g., ./src, ./lib)");
|
|
235
|
+
console.log("💡 You can also enter glob patterns (e.g., src/**/*.js, **/*.md)");
|
|
231
236
|
console.log("💡 If no paths are configured, './' will be used as default");
|
|
232
237
|
|
|
233
238
|
const sourcePaths = [];
|
|
234
239
|
while (true) {
|
|
235
240
|
const selectedPath = await options.prompts.search({
|
|
236
|
-
message: "Path:",
|
|
241
|
+
message: "Path or glob pattern:",
|
|
237
242
|
source: async (input) => {
|
|
238
243
|
if (!input || input.trim() === "") {
|
|
239
244
|
return [
|
|
240
245
|
{
|
|
241
|
-
name: "
|
|
246
|
+
name: "",
|
|
242
247
|
value: "",
|
|
243
|
-
description:
|
|
248
|
+
description: _PRESS_ENTER_TO_FINISH,
|
|
244
249
|
},
|
|
245
250
|
];
|
|
246
251
|
}
|
|
@@ -250,32 +255,58 @@ export default async function init(
|
|
|
250
255
|
// Search for matching files and folders in current directory
|
|
251
256
|
const availablePaths = getAvailablePaths(searchTerm);
|
|
252
257
|
|
|
253
|
-
|
|
258
|
+
// Also add option to use as glob pattern
|
|
259
|
+
const options = [...availablePaths];
|
|
260
|
+
|
|
261
|
+
// Check if input looks like a glob pattern
|
|
262
|
+
const isGlobPatternResult = isGlobPattern(searchTerm);
|
|
263
|
+
if (isGlobPatternResult) {
|
|
264
|
+
// If it looks like a glob pattern, allow direct input
|
|
265
|
+
options.push({
|
|
266
|
+
name: searchTerm,
|
|
267
|
+
value: searchTerm,
|
|
268
|
+
description: "This input will be used as a glob pattern for file matching",
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return options;
|
|
254
273
|
},
|
|
255
274
|
});
|
|
256
275
|
|
|
257
276
|
// Check if user chose to exit
|
|
258
|
-
if (!selectedPath || selectedPath.trim() === "" || selectedPath ===
|
|
277
|
+
if (!selectedPath || selectedPath.trim() === "" || selectedPath === _PRESS_ENTER_TO_FINISH) {
|
|
259
278
|
break;
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
const trimmedPath = selectedPath.trim();
|
|
263
282
|
|
|
264
|
-
//
|
|
265
|
-
const
|
|
283
|
+
// Check if it's a glob pattern
|
|
284
|
+
const isGlobPatternResult = isGlobPattern(trimmedPath);
|
|
266
285
|
|
|
267
|
-
if (
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
286
|
+
if (isGlobPatternResult) {
|
|
287
|
+
// For glob patterns, just add them without validation
|
|
288
|
+
if (sourcePaths.includes(trimmedPath)) {
|
|
289
|
+
console.log(`⚠️ Pattern already exists: ${trimmedPath}`);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
sourcePaths.push(trimmedPath);
|
|
293
|
+
} else {
|
|
294
|
+
// Use validatePath to check if path is valid for regular paths
|
|
295
|
+
const validation = validatePath(trimmedPath);
|
|
296
|
+
|
|
297
|
+
if (!validation.isValid) {
|
|
298
|
+
console.log(`⚠️ ${validation.error}`);
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
271
301
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
302
|
+
// Avoid duplicate paths
|
|
303
|
+
if (sourcePaths.includes(trimmedPath)) {
|
|
304
|
+
console.log(`⚠️ Path already exists: ${trimmedPath}`);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
277
307
|
|
|
278
|
-
|
|
308
|
+
sourcePaths.push(trimmedPath);
|
|
309
|
+
}
|
|
279
310
|
}
|
|
280
311
|
|
|
281
312
|
// If no paths entered, use default
|
|
@@ -324,114 +355,142 @@ export default async function init(
|
|
|
324
355
|
* @param {Object} input - Input object
|
|
325
356
|
* @returns {string} YAML string
|
|
326
357
|
*/
|
|
327
|
-
function generateYAML(input) {
|
|
328
|
-
|
|
358
|
+
export function generateYAML(input) {
|
|
359
|
+
// Create the main configuration object that will be safely serialized
|
|
360
|
+
const config = {
|
|
361
|
+
// Project information (safely handled by yaml library)
|
|
362
|
+
projectName: input.projectName || "",
|
|
363
|
+
projectDesc: input.projectDesc || "",
|
|
364
|
+
projectLogo: input.projectLogo || "",
|
|
365
|
+
|
|
366
|
+
// Documentation configuration
|
|
367
|
+
documentPurpose: input.documentPurpose || [],
|
|
368
|
+
targetAudienceTypes: input.targetAudienceTypes || [],
|
|
369
|
+
readerKnowledgeLevel: input.readerKnowledgeLevel || "",
|
|
370
|
+
documentationDepth: input.documentationDepth || "",
|
|
371
|
+
|
|
372
|
+
// Custom rules and target audience (empty for user to fill)
|
|
373
|
+
rules: "",
|
|
374
|
+
targetAudience: "",
|
|
375
|
+
|
|
376
|
+
// Language settings
|
|
377
|
+
locale: input.locale || "en",
|
|
378
|
+
translateLanguages: input.translateLanguages?.filter((lang) => lang.trim()) || [],
|
|
379
|
+
|
|
380
|
+
// Paths
|
|
381
|
+
docsDir: input.docsDir || "./aigne/doc-smith/docs",
|
|
382
|
+
sourcesPath: input.sourcesPath || [],
|
|
383
|
+
};
|
|
329
384
|
|
|
330
|
-
//
|
|
331
|
-
yaml
|
|
332
|
-
yaml += `projectName: ${input.projectName || ""}\n`;
|
|
333
|
-
yaml += `projectDesc: ${input.projectDesc || ""}\n`;
|
|
334
|
-
yaml += `projectLogo: ${input.projectLogo || ""}\n`;
|
|
335
|
-
yaml += `\n`;
|
|
385
|
+
// Generate comments and structure
|
|
386
|
+
let yaml = "# Project information for documentation publishing\n";
|
|
336
387
|
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
388
|
+
// Serialize the project info section safely
|
|
389
|
+
const projectSection = yamlStringify({
|
|
390
|
+
projectName: config.projectName,
|
|
391
|
+
projectDesc: config.projectDesc,
|
|
392
|
+
projectLogo: config.projectLogo,
|
|
393
|
+
}).trim();
|
|
394
|
+
|
|
395
|
+
yaml += `${projectSection}\n\n`;
|
|
396
|
+
|
|
397
|
+
// Add documentation configuration with comments
|
|
398
|
+
yaml += "# =============================================================================\n";
|
|
399
|
+
yaml += "# Documentation Configuration\n";
|
|
400
|
+
yaml += "# =============================================================================\n\n";
|
|
341
401
|
|
|
342
402
|
// Document Purpose with all available options
|
|
343
|
-
yaml +=
|
|
344
|
-
yaml +=
|
|
403
|
+
yaml += "# Purpose: What's the main outcome you want readers to achieve?\n";
|
|
404
|
+
yaml += "# Available options (uncomment and modify as needed):\n";
|
|
345
405
|
Object.entries(DOCUMENT_STYLES).forEach(([key, style]) => {
|
|
346
406
|
if (key !== "custom") {
|
|
347
407
|
yaml += `# ${key.padEnd(16)} - ${style.name}: ${style.description}\n`;
|
|
348
408
|
}
|
|
349
409
|
});
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
yaml += `\n`;
|
|
410
|
+
|
|
411
|
+
// Safely serialize documentPurpose
|
|
412
|
+
const documentPurposeSection = yamlStringify({ documentPurpose: config.documentPurpose }).trim();
|
|
413
|
+
yaml += `${documentPurposeSection.replace(/^documentPurpose:/, "documentPurpose:")}\n\n`;
|
|
357
414
|
|
|
358
415
|
// Target Audience Types with all available options
|
|
359
|
-
yaml +=
|
|
360
|
-
yaml +=
|
|
416
|
+
yaml += "# Target Audience: Who will be reading this most often?\n";
|
|
417
|
+
yaml += "# Available options (uncomment and modify as needed):\n";
|
|
361
418
|
Object.entries(TARGET_AUDIENCES).forEach(([key, audience]) => {
|
|
362
419
|
if (key !== "custom") {
|
|
363
420
|
yaml += `# ${key.padEnd(16)} - ${audience.name}: ${audience.description}\n`;
|
|
364
421
|
}
|
|
365
422
|
});
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
yaml += `\n`;
|
|
423
|
+
|
|
424
|
+
// Safely serialize targetAudienceTypes
|
|
425
|
+
const targetAudienceTypesSection = yamlStringify({
|
|
426
|
+
targetAudienceTypes: config.targetAudienceTypes,
|
|
427
|
+
}).trim();
|
|
428
|
+
yaml += `${targetAudienceTypesSection.replace(/^targetAudienceTypes:/, "targetAudienceTypes:")}\n\n`;
|
|
373
429
|
|
|
374
430
|
// Reader Knowledge Level with all available options
|
|
375
|
-
yaml +=
|
|
376
|
-
yaml +=
|
|
431
|
+
yaml += "# Reader Knowledge Level: What do readers typically know when they arrive?\n";
|
|
432
|
+
yaml += "# Available options (uncomment and modify as needed):\n";
|
|
377
433
|
Object.entries(READER_KNOWLEDGE_LEVELS).forEach(([key, level]) => {
|
|
378
434
|
yaml += `# ${key.padEnd(20)} - ${level.name}: ${level.description}\n`;
|
|
379
435
|
});
|
|
380
|
-
|
|
381
|
-
|
|
436
|
+
|
|
437
|
+
// Safely serialize readerKnowledgeLevel
|
|
438
|
+
const readerKnowledgeLevelSection = yamlStringify({
|
|
439
|
+
readerKnowledgeLevel: config.readerKnowledgeLevel,
|
|
440
|
+
}).trim();
|
|
441
|
+
yaml += `${readerKnowledgeLevelSection.replace(/^readerKnowledgeLevel:/, "readerKnowledgeLevel:")}\n\n`;
|
|
382
442
|
|
|
383
443
|
// Documentation Depth with all available options
|
|
384
|
-
yaml +=
|
|
385
|
-
yaml +=
|
|
444
|
+
yaml += "# Documentation Depth: How comprehensive should the documentation be?\n";
|
|
445
|
+
yaml += "# Available options (uncomment and modify as needed):\n";
|
|
386
446
|
Object.entries(DOCUMENTATION_DEPTH).forEach(([key, depth]) => {
|
|
387
447
|
yaml += `# ${key.padEnd(18)} - ${depth.name}: ${depth.description}\n`;
|
|
388
448
|
});
|
|
389
|
-
|
|
390
|
-
|
|
449
|
+
|
|
450
|
+
// Safely serialize documentationDepth
|
|
451
|
+
const documentationDepthSection = yamlStringify({
|
|
452
|
+
documentationDepth: config.documentationDepth,
|
|
453
|
+
}).trim();
|
|
454
|
+
yaml += `${documentationDepthSection.replace(/^documentationDepth:/, "documentationDepth:")}\n\n`;
|
|
391
455
|
|
|
392
456
|
// Custom Documentation Rules and Requirements
|
|
393
|
-
yaml +=
|
|
394
|
-
|
|
395
|
-
|
|
457
|
+
yaml += "# Custom Rules: Define specific documentation generation rules and requirements\n";
|
|
458
|
+
const rulesSection = yamlStringify({ rules: config.rules }).trim();
|
|
459
|
+
// Use literal style for multiline strings
|
|
460
|
+
yaml += `${rulesSection.replace(/rules: ''/, "rules: |\n ")}\n\n`;
|
|
396
461
|
|
|
397
462
|
// Target Audience Description
|
|
398
|
-
yaml +=
|
|
399
|
-
|
|
400
|
-
|
|
463
|
+
yaml += "# Target Audience: Describe your specific target audience and their characteristics\n";
|
|
464
|
+
const targetAudienceSection = yamlStringify({ targetAudience: config.targetAudience }).trim();
|
|
465
|
+
// Use literal style for multiline strings
|
|
466
|
+
yaml += `${targetAudienceSection.replace(/targetAudience: ''/, "targetAudience: |\n ")}\n\n`;
|
|
401
467
|
|
|
402
468
|
// Glossary Configuration
|
|
403
|
-
yaml +=
|
|
404
|
-
yaml +=
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
yaml +=
|
|
409
|
-
|
|
410
|
-
//
|
|
411
|
-
if (
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
yaml += `translateLanguages:\n`;
|
|
417
|
-
input.translateLanguages.forEach((lang) => {
|
|
418
|
-
if (lang.trim()) {
|
|
419
|
-
yaml += ` - ${lang}\n`;
|
|
420
|
-
}
|
|
421
|
-
});
|
|
469
|
+
yaml += "# Glossary: Define project-specific terms and definitions\n";
|
|
470
|
+
yaml += '# glossary: "@glossary.md" # Path to markdown file containing glossary definitions\n\n';
|
|
471
|
+
|
|
472
|
+
// Language settings - safely serialize
|
|
473
|
+
const localeSection = yamlStringify({ locale: config.locale }).trim();
|
|
474
|
+
yaml += `${localeSection.replace(/^locale:/, "locale:")}\n`;
|
|
475
|
+
|
|
476
|
+
// Translation languages
|
|
477
|
+
if (config.translateLanguages.length > 0) {
|
|
478
|
+
const translateLanguagesSection = yamlStringify({
|
|
479
|
+
translateLanguages: config.translateLanguages,
|
|
480
|
+
}).trim();
|
|
481
|
+
yaml += `${translateLanguagesSection.replace(/^translateLanguages:/, "translateLanguages:")}\n`;
|
|
422
482
|
} else {
|
|
423
|
-
yaml +=
|
|
424
|
-
yaml +=
|
|
425
|
-
yaml +=
|
|
483
|
+
yaml += "# translateLanguages: # List of languages to translate the documentation to\n";
|
|
484
|
+
yaml += "# - zh # Example: Chinese translation\n";
|
|
485
|
+
yaml += "# - en # Example: English translation\n";
|
|
426
486
|
}
|
|
427
487
|
|
|
428
|
-
//
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
});
|
|
488
|
+
// Directory and source path configurations - safely serialize
|
|
489
|
+
const docsDirSection = yamlStringify({ docsDir: config.docsDir }).trim();
|
|
490
|
+
yaml += `${docsDirSection.replace(/^docsDir:/, "docsDir:")} # Directory to save generated documentation\n`;
|
|
491
|
+
|
|
492
|
+
const sourcesPathSection = yamlStringify({ sourcesPath: config.sourcesPath }).trim();
|
|
493
|
+
yaml += `${sourcesPathSection.replace(/^sourcesPath:/, "sourcesPath: # Source code paths to analyze")}\n`;
|
|
435
494
|
|
|
436
495
|
return yaml;
|
|
437
496
|
}
|
package/agents/load-config.mjs
CHANGED
|
@@ -31,11 +31,6 @@ export default async function loadConfig({ config, appUrl }) {
|
|
|
31
31
|
const processedConfig = processConfigFields(parsedConfig);
|
|
32
32
|
|
|
33
33
|
return {
|
|
34
|
-
nodeName: "Section",
|
|
35
|
-
locale: "en",
|
|
36
|
-
sourcesPath: ["./"],
|
|
37
|
-
docsDir: "./.aigne/doc-smith/docs",
|
|
38
|
-
outputDir: "./.aigne/doc-smith/output",
|
|
39
34
|
lastGitHead: parsedConfig.lastGitHead || "",
|
|
40
35
|
...parsedConfig,
|
|
41
36
|
...processedConfig,
|