@aigne/doc-smith 0.0.1 → 0.0.2
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/.github/workflows/release.yml +49 -0
- package/CHANGELOG.md +36 -0
- package/README.md +23 -4
- package/agents/detail-regenerator.yaml +63 -64
- package/agents/docs-generator.yaml +65 -51
- package/agents/find-item-by-path.mjs +39 -0
- package/agents/input-generator.mjs +14 -22
- package/agents/load-config.mjs +43 -0
- package/agents/load-sources.mjs +3 -1
- package/agents/publish-docs.mjs +8 -6
- package/agents/save-docs.mjs +26 -5
- package/agents/save-single-doc.mjs +2 -0
- package/agents/team-publish-docs.yaml +13 -0
- package/aigne.yaml +4 -1
- package/docs-mcp/aigne.yaml +0 -0
- package/package.json +11 -11
- package/prompts/check-structure-planning-result.md +10 -0
- package/prompts/content-detail-generator.md +2 -0
- package/utils/utils.mjs +16 -5
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
release-please:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: googleapis/release-please-action@v4
|
|
17
|
+
id: release
|
|
18
|
+
with:
|
|
19
|
+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
|
20
|
+
release-type: node
|
|
21
|
+
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 2
|
|
27
|
+
|
|
28
|
+
- uses: pnpm/action-setup@v3
|
|
29
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
30
|
+
with:
|
|
31
|
+
version: 10
|
|
32
|
+
|
|
33
|
+
- name: Setup node
|
|
34
|
+
uses: actions/setup-node@v4
|
|
35
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
36
|
+
with:
|
|
37
|
+
node-version: 23
|
|
38
|
+
cache: pnpm
|
|
39
|
+
|
|
40
|
+
- name: Install dependencies
|
|
41
|
+
run: |
|
|
42
|
+
pnpm install
|
|
43
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
44
|
+
|
|
45
|
+
- name: Publish to NPM
|
|
46
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
47
|
+
run: |
|
|
48
|
+
npm config set '//registry.npmjs.org/:_authToken' "${{ secrets.NPM_TOKEN }}"
|
|
49
|
+
pnpm publish --access public --no-git-checks
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.0.2 (2025-07-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add auto create board ([3ff06ad](https://github.com/AIGNE-io/aigne-doc-smith/commit/3ff06ad0241e208b09bcf828c52c2c5051c67ef8))
|
|
9
|
+
* add docs-mcp ([a7508a1](https://github.com/AIGNE-io/aigne-doc-smith/commit/a7508a13abb2222968b1bc9c14948427af509f97))
|
|
10
|
+
* add input generator agent ([20c01bb](https://github.com/AIGNE-io/aigne-doc-smith/commit/20c01bbca6d6f9414695071fc907bd7cf43d7f62))
|
|
11
|
+
* add publish docs ([41bb126](https://github.com/AIGNE-io/aigne-doc-smith/commit/41bb126caeb1c3c242c7a2be27abb114aeab9953))
|
|
12
|
+
* add support docs labels ([4522c07](https://github.com/AIGNE-io/aigne-doc-smith/commit/4522c07b1ceb05664a1f5b5fb4df06feee536eba))
|
|
13
|
+
* detail add review ([8f1aa4f](https://github.com/AIGNE-io/aigne-doc-smith/commit/8f1aa4f22e2d2e590d7aa37288c2e1ee7ea48f07))
|
|
14
|
+
* init commit ([dafc40e](https://github.com/AIGNE-io/aigne-doc-smith/commit/dafc40e94f3c407e50b2c46ecb46237f23a15cf7))
|
|
15
|
+
* structure plan add review ([b56e83e](https://github.com/AIGNE-io/aigne-doc-smith/commit/b56e83e558f509302b422205f30e9b2adb42d452))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* polish agent name ([25875a0](https://github.com/AIGNE-io/aigne-doc-smith/commit/25875a0688ebbca71f6c25bf4bd5246361f3dd2d))
|
|
21
|
+
* polish agent param and description ([290eb24](https://github.com/AIGNE-io/aigne-doc-smith/commit/290eb240ce986b0f1f406bf42824ce1235df11e5))
|
|
22
|
+
* polish code ([34f9a24](https://github.com/AIGNE-io/aigne-doc-smith/commit/34f9a24fc3748b4177cad2b5330fe6b3ccd99175))
|
|
23
|
+
* polish code ([0343486](https://github.com/AIGNE-io/aigne-doc-smith/commit/0343486aa086bbe2ced8de849de6a4a42567719c))
|
|
24
|
+
* polish code ([7b7dfb9](https://github.com/AIGNE-io/aigne-doc-smith/commit/7b7dfb925b3aa55956ef7a99ededc749fb6a42d7))
|
|
25
|
+
* polish code ([4fa4694](https://github.com/AIGNE-io/aigne-doc-smith/commit/4fa4694dbbd5880d501883a7cf3c0d3494509fb4))
|
|
26
|
+
* polish code ([74fee51](https://github.com/AIGNE-io/aigne-doc-smith/commit/74fee51ad6337af8811a35f2a4334b67ec109439))
|
|
27
|
+
* polish code ([7fa1675](https://github.com/AIGNE-io/aigne-doc-smith/commit/7fa1675b2cab6144d1fb9d4388130209c6cfa0bc))
|
|
28
|
+
* polish docs review ([70374ab](https://github.com/AIGNE-io/aigne-doc-smith/commit/70374abed74946eafa7b0f87331c2e496fa61592))
|
|
29
|
+
* polish input generator agent ([ae908bb](https://github.com/AIGNE-io/aigne-doc-smith/commit/ae908bbc0cb98b9b196e8b08f23149e5693e0abe))
|
|
30
|
+
* polish structure plan ([3a0a196](https://github.com/AIGNE-io/aigne-doc-smith/commit/3a0a196a97196ba445c4709d3466ff355917ac53))
|
|
31
|
+
* save docs remove useless docs ([bec5ba3](https://github.com/AIGNE-io/aigne-doc-smith/commit/bec5ba3afd462c990a0aa813bbe38ce9a61363ee))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Miscellaneous Chores
|
|
35
|
+
|
|
36
|
+
* release 0.0.2 ([73bf26a](https://github.com/AIGNE-io/aigne-doc-smith/commit/73bf26a5c55fa4726d866cff64bd48d1ca37a3b3))
|
package/README.md
CHANGED
|
@@ -61,17 +61,36 @@ Contributions are welcome! Please feel free to submit a pull request or open an
|
|
|
61
61
|
npx --no doc-smith run --entry-agent init
|
|
62
62
|
|
|
63
63
|
# 生成命令
|
|
64
|
-
npx --no doc-smith run --
|
|
64
|
+
npx --no doc-smith run --entry-agent generator --model gemini:gemini-2.5-flash
|
|
65
65
|
|
|
66
66
|
# 重新生成单篇
|
|
67
|
-
npx --no doc-smith run --
|
|
67
|
+
npx --no doc-smith run --entry-agent regenerator --input-path bitnet-m4XQ-core-concepts-quantization
|
|
68
68
|
|
|
69
69
|
# 结构规划优化
|
|
70
|
-
npx --no doc-smith run --input @./doc-smith/
|
|
70
|
+
npx --no doc-smith run --input @./doc-smith/config.yaml --format yaml --entry-agent generator --input-structurePlanFeedback "补充节点的 sourceIds,确保所有节点 sourceIds 都有值" --model gemini:gemini-2.5-pro
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
# 发布文档
|
|
74
|
-
npx --no doc-smith run --input @./doc-smith/
|
|
74
|
+
npx --no doc-smith run --input @./doc-smith/config.yaml --format yaml --entry-agent publish
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
使用 `aigne doc` 运行
|
|
80
|
+
|
|
81
|
+
```shell
|
|
82
|
+
# 初始化
|
|
83
|
+
aigne doc init
|
|
84
|
+
|
|
85
|
+
# 生成文档
|
|
86
|
+
aigne doc generator
|
|
87
|
+
|
|
88
|
+
# 优化单篇文档
|
|
89
|
+
aigne doc regenerator --path bitnet-m4XQ-core-concepts-quantization # 可使用 structure-plan.json 中的 path ,或 Discuss Kit 中访问的 path
|
|
90
|
+
|
|
91
|
+
# 发布文档
|
|
92
|
+
aigne doc publish
|
|
93
|
+
|
|
75
94
|
|
|
76
95
|
```
|
|
77
96
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
type: team
|
|
2
2
|
name: regenerator
|
|
3
|
-
description:
|
|
3
|
+
description: Optimize and regenerate individual document content and translations
|
|
4
4
|
skills:
|
|
5
|
+
- ./load-config.mjs
|
|
5
6
|
- ./load-sources.mjs
|
|
6
7
|
- type: transform
|
|
7
8
|
jsonata: |
|
|
@@ -19,80 +20,78 @@ skills:
|
|
|
19
20
|
})
|
|
20
21
|
}
|
|
21
22
|
])
|
|
22
|
-
-
|
|
23
|
-
jsonata: |
|
|
24
|
-
(
|
|
25
|
-
$array := structurePlanResult;
|
|
26
|
-
$path := currentPath;
|
|
27
|
-
$foundItem := $array[path=$path][0];
|
|
28
|
-
$merge([
|
|
29
|
-
$foundItem,
|
|
30
|
-
{ "originalStructurePlan": originalStructurePlan }
|
|
31
|
-
|
|
32
|
-
])
|
|
33
|
-
)
|
|
23
|
+
- ./find-item-by-path.mjs
|
|
34
24
|
- ./format-structure-plan.mjs
|
|
35
25
|
- ./detail-generator-and-translate.yaml
|
|
36
26
|
input_schema:
|
|
37
27
|
type: object
|
|
38
28
|
properties:
|
|
39
|
-
|
|
40
|
-
type: string
|
|
41
|
-
description: 节点名称
|
|
42
|
-
default: 部分
|
|
43
|
-
locale:
|
|
44
|
-
type: string
|
|
45
|
-
description: 语言
|
|
46
|
-
targetAudience:
|
|
29
|
+
config:
|
|
47
30
|
type: string
|
|
48
|
-
description:
|
|
31
|
+
description: Path to the config file
|
|
32
|
+
default: ./doc-smith/config.yaml
|
|
33
|
+
# nodeName:
|
|
34
|
+
# type: string
|
|
35
|
+
# description: Name of the section to generate documentation for
|
|
36
|
+
# default: Section
|
|
37
|
+
# locale:
|
|
38
|
+
# type: string
|
|
39
|
+
# description: Primary language for documentation (e.g., zh, en)
|
|
40
|
+
# targetAudience:
|
|
41
|
+
# type: string
|
|
42
|
+
# description: Target audience for the documentation
|
|
49
43
|
glossary:
|
|
50
44
|
type: string
|
|
51
|
-
description:
|
|
52
|
-
|
|
45
|
+
description: Glossary of terms for consistent terminology
|
|
46
|
+
path:
|
|
53
47
|
type: string
|
|
54
|
-
description:
|
|
48
|
+
description: Document path to regenerate
|
|
55
49
|
feedback:
|
|
56
50
|
type: string
|
|
57
|
-
description:
|
|
58
|
-
sources:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
sourcesPath:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
includePatterns:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
excludePatterns:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
outputDir:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
docsDir:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
additionalInformation:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
51
|
+
description: Feedback for content improvement
|
|
52
|
+
# sources:
|
|
53
|
+
# type: array
|
|
54
|
+
# items:
|
|
55
|
+
# type: string
|
|
56
|
+
# description: Source code files for documentation generation
|
|
57
|
+
# sourcesPath:
|
|
58
|
+
# type: array
|
|
59
|
+
# description: Source code paths
|
|
60
|
+
# items:
|
|
61
|
+
# type: string
|
|
62
|
+
# default:
|
|
63
|
+
# - ./
|
|
64
|
+
# includePatterns:
|
|
65
|
+
# type: array
|
|
66
|
+
# description: File patterns to include
|
|
67
|
+
# items:
|
|
68
|
+
# type: string
|
|
69
|
+
# excludePatterns:
|
|
70
|
+
# type: array
|
|
71
|
+
# description: File patterns to exclude
|
|
72
|
+
# items:
|
|
73
|
+
# type: string
|
|
74
|
+
# outputDir:
|
|
75
|
+
# type: string
|
|
76
|
+
# description: Output directory for intermediate files
|
|
77
|
+
# default: ./doc-smith/output
|
|
78
|
+
# docsDir:
|
|
79
|
+
# type: string
|
|
80
|
+
# description: Directory to save generated documentation
|
|
81
|
+
# default: ./doc-smith/docs
|
|
82
|
+
# additionalInformation:
|
|
83
|
+
# type: string
|
|
84
|
+
# description: Additional context or information for documentation
|
|
85
|
+
# translateLanguages:
|
|
86
|
+
# type: array
|
|
87
|
+
# items:
|
|
88
|
+
# type: string
|
|
89
|
+
# description: Target languages for translation (e.g., zh, en)
|
|
90
|
+
# labels:
|
|
91
|
+
# type: array
|
|
92
|
+
# items:
|
|
93
|
+
# type: string
|
|
94
|
+
# description: Tags or labels for categorization
|
|
96
95
|
output_schema:
|
|
97
96
|
type: object
|
|
98
97
|
properties:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
type: team
|
|
2
2
|
name: generator
|
|
3
|
-
description:
|
|
3
|
+
description: Automatically generates comprehensive project documentation
|
|
4
4
|
skills:
|
|
5
|
+
- ./load-config.mjs
|
|
5
6
|
- ./load-sources.mjs
|
|
6
7
|
- ./check-structure-planning.mjs
|
|
7
8
|
- type: transform
|
|
@@ -34,60 +35,73 @@ skills:
|
|
|
34
35
|
input_schema:
|
|
35
36
|
type: object
|
|
36
37
|
properties:
|
|
37
|
-
|
|
38
|
+
config:
|
|
38
39
|
type: string
|
|
39
|
-
description:
|
|
40
|
-
default:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
40
|
+
description: Path to the config file
|
|
41
|
+
default: ./doc-smith/config.yaml
|
|
42
|
+
# nodeName:
|
|
43
|
+
# type: string
|
|
44
|
+
# description: Name of the section to generate documentation for
|
|
45
|
+
# default: Section
|
|
46
|
+
# rules:
|
|
47
|
+
# type: string
|
|
48
|
+
# description: Documentation generation requirements and rules
|
|
49
|
+
# locale:
|
|
50
|
+
# type: string
|
|
51
|
+
# description: Primary language for documentation (e.g., zh, en)
|
|
52
|
+
# sources:
|
|
53
|
+
# type: array
|
|
54
|
+
# items:
|
|
55
|
+
# type: string
|
|
56
|
+
# description: Source code files for documentation generation
|
|
57
|
+
# sourcesPath:
|
|
58
|
+
# type: array
|
|
59
|
+
# description: Source code paths
|
|
60
|
+
# items:
|
|
61
|
+
# type: string
|
|
62
|
+
# default:
|
|
63
|
+
# - ./
|
|
64
|
+
# includePatterns:
|
|
65
|
+
# type: array
|
|
66
|
+
# description: File patterns to include
|
|
67
|
+
# items:
|
|
68
|
+
# type: string
|
|
69
|
+
# excludePatterns:
|
|
70
|
+
# type: array
|
|
71
|
+
# description: File patterns to exclude
|
|
72
|
+
# items:
|
|
73
|
+
# type: string
|
|
74
|
+
# docsDir:
|
|
75
|
+
# type: string
|
|
76
|
+
# description: Directory to save generated documentation
|
|
77
|
+
# default: ./doc-smith/docs
|
|
78
|
+
# outputDir:
|
|
79
|
+
# type: string
|
|
80
|
+
# description: Output directory for intermediate files
|
|
81
|
+
# default: ./doc-smith/output
|
|
82
|
+
# translateLanguages:
|
|
83
|
+
# type: array
|
|
84
|
+
# items:
|
|
85
|
+
# type: string
|
|
86
|
+
# description: Target languages for translation (e.g., zh, en)
|
|
72
87
|
glossary:
|
|
73
88
|
type: string
|
|
74
|
-
description:
|
|
75
|
-
additionalInformation:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
docsType:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
description: Glossary of terms for consistent terminology
|
|
90
|
+
# additionalInformation:
|
|
91
|
+
# type: string
|
|
92
|
+
# description: Additional context or information for documentation
|
|
93
|
+
# docsType:
|
|
94
|
+
# type: string
|
|
95
|
+
# description: Type of documentation (general, getting-started, reference, faq)
|
|
96
|
+
# default: general
|
|
82
97
|
structurePlanFeedback:
|
|
83
98
|
type: string
|
|
84
|
-
description:
|
|
85
|
-
labels:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
description: Feedback for structure planning adjustments
|
|
100
|
+
# labels:
|
|
101
|
+
# type: array
|
|
102
|
+
# items:
|
|
103
|
+
# type: string
|
|
104
|
+
# description: Tags or labels for categorization
|
|
90
105
|
required:
|
|
91
|
-
-
|
|
92
|
-
- docsDir
|
|
106
|
+
- config
|
|
93
107
|
mode: sequential
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export default async function findItemByPath({
|
|
2
|
+
path,
|
|
3
|
+
structurePlanResult,
|
|
4
|
+
boardId,
|
|
5
|
+
}) {
|
|
6
|
+
let foundItem = null;
|
|
7
|
+
|
|
8
|
+
// First try direct path matching
|
|
9
|
+
foundItem = structurePlanResult.find((item) => item.path === path);
|
|
10
|
+
|
|
11
|
+
// If not found and boardId is provided, try boardId-flattenedPath format matching
|
|
12
|
+
if (!foundItem && boardId) {
|
|
13
|
+
// Check if path starts with boardId followed by a dash
|
|
14
|
+
if (path.startsWith(`${boardId}-`)) {
|
|
15
|
+
// Extract the flattened path part after boardId-
|
|
16
|
+
const flattenedPath = path.substring(boardId.length + 1);
|
|
17
|
+
|
|
18
|
+
// Find item by comparing flattened paths
|
|
19
|
+
foundItem = structurePlanResult.find((item) => {
|
|
20
|
+
// Convert item.path to flattened format (replace / with -)
|
|
21
|
+
const itemFlattenedPath = item.path
|
|
22
|
+
.replace(/^\//, "")
|
|
23
|
+
.replace(/\//g, "-");
|
|
24
|
+
return itemFlattenedPath === flattenedPath;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!foundItem) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Item with path "${path}" not found in structurePlanResult`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Merge the found item with originalStructurePlan
|
|
36
|
+
return {
|
|
37
|
+
...foundItem,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -9,7 +9,7 @@ import { join, dirname } from "node:path";
|
|
|
9
9
|
* @returns {Promise<Object>}
|
|
10
10
|
*/
|
|
11
11
|
export default async function init(
|
|
12
|
-
{ outputPath = "./doc-smith", fileName = "
|
|
12
|
+
{ outputPath = "./doc-smith", fileName = "config.yaml" },
|
|
13
13
|
options
|
|
14
14
|
) {
|
|
15
15
|
console.log("Welcome to AIGNE Doc Smith!");
|
|
@@ -31,16 +31,16 @@ export default async function init(
|
|
|
31
31
|
console.log("\n=== Target Audience ===");
|
|
32
32
|
const targetAudienceInput = await options.prompts.input({
|
|
33
33
|
message:
|
|
34
|
-
"What is the target audience? (e.g., developers, users, press Enter
|
|
34
|
+
"What is the target audience? (e.g., developers, users, press Enter for default 'developers'):",
|
|
35
35
|
});
|
|
36
|
-
input.targetAudience = targetAudienceInput.trim() || "";
|
|
36
|
+
input.targetAudience = targetAudienceInput.trim() || "developers";
|
|
37
37
|
|
|
38
38
|
// 3. Language settings
|
|
39
39
|
console.log("\n=== Language Settings ===");
|
|
40
40
|
const localeInput = await options.prompts.input({
|
|
41
|
-
message: "Primary language (e.g., en, zh, press Enter
|
|
41
|
+
message: "Primary language (e.g., en, zh, press Enter for default 'en'):",
|
|
42
42
|
});
|
|
43
|
-
input.locale = localeInput.trim() || "";
|
|
43
|
+
input.locale = localeInput.trim() || "en";
|
|
44
44
|
|
|
45
45
|
// 4. Translation languages
|
|
46
46
|
console.log("\n=== Translation Settings ===");
|
|
@@ -89,25 +89,19 @@ export default async function init(
|
|
|
89
89
|
function generateYAML(input, outputPath) {
|
|
90
90
|
let yaml = "";
|
|
91
91
|
|
|
92
|
-
// Add rules
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
// Add rules (required field)
|
|
93
|
+
yaml += `rules: |\n`;
|
|
94
|
+
if (input.rules && input.rules.trim()) {
|
|
95
95
|
yaml += ` ${input.rules.split("\n").join("\n ")}\n\n`;
|
|
96
|
+
} else {
|
|
97
|
+
yaml += ` \n\n`;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
// Add target audience
|
|
99
|
-
|
|
100
|
-
yaml += `targetAudience: ${input.targetAudience}\n`;
|
|
101
|
-
} else {
|
|
102
|
-
yaml += `# targetAudience: developers # Target audience for the documentation (e.g., developers, users)\n`;
|
|
103
|
-
}
|
|
101
|
+
yaml += `targetAudience: ${input.targetAudience}\n`;
|
|
104
102
|
|
|
105
103
|
// Add language settings
|
|
106
|
-
|
|
107
|
-
yaml += `locale: ${input.locale}\n`;
|
|
108
|
-
} else {
|
|
109
|
-
yaml += `# locale: en # Primary language for the documentation (e.g., en, zh)\n`;
|
|
110
|
-
}
|
|
104
|
+
yaml += `locale: ${input.locale}\n`;
|
|
111
105
|
|
|
112
106
|
// Add translation languages
|
|
113
107
|
if (
|
|
@@ -136,7 +130,5 @@ function generateYAML(input, outputPath) {
|
|
|
136
130
|
return yaml;
|
|
137
131
|
}
|
|
138
132
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
inputGenerator({}).catch(console.error);
|
|
142
|
-
}
|
|
133
|
+
init.description =
|
|
134
|
+
"Generate a configuration file for the documentation generation process";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { parse } from "yaml";
|
|
4
|
+
|
|
5
|
+
export default async function loadConfig({ config }) {
|
|
6
|
+
const configPath = path.join(process.cwd(), config);
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
// Check if config file exists
|
|
10
|
+
await fs.access(configPath);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.log(`Config file not found: ${configPath}`);
|
|
13
|
+
console.log("Please run 'aigne doc init' to create the config file.");
|
|
14
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Read and parse YAML file
|
|
19
|
+
const configContent = await fs.readFile(configPath, "utf-8");
|
|
20
|
+
const parsedConfig = parse(configContent);
|
|
21
|
+
return {
|
|
22
|
+
nodeName: "Section",
|
|
23
|
+
locale: "en",
|
|
24
|
+
sourcesPath: ["./"],
|
|
25
|
+
docDir: "./doc-smith/docs",
|
|
26
|
+
outputDir: "./doc-smith/output",
|
|
27
|
+
...parsedConfig,
|
|
28
|
+
};
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error(`Error parsing config file: ${error.message}`);
|
|
31
|
+
throw new Error(`Failed to parse config file: ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
loadConfig.input_schema = {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
config: {
|
|
39
|
+
type: "string",
|
|
40
|
+
default: "./doc-smith/config.yaml",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
package/agents/load-sources.mjs
CHANGED
|
@@ -44,8 +44,9 @@ const DEFAULT_EXCLUDE_PATTERNS = [
|
|
|
44
44
|
"**/*test/**",
|
|
45
45
|
"**/*tests/**",
|
|
46
46
|
"**/*examples/**",
|
|
47
|
+
"**/playgrounds/**",
|
|
47
48
|
"v1/**",
|
|
48
|
-
"
|
|
49
|
+
"**/dist/**",
|
|
49
50
|
"**/*build/**",
|
|
50
51
|
"**/*experimental/**",
|
|
51
52
|
"**/*deprecated/**",
|
|
@@ -59,6 +60,7 @@ const DEFAULT_EXCLUDE_PATTERNS = [
|
|
|
59
60
|
"**/*bin/**",
|
|
60
61
|
"**/*node_modules/**",
|
|
61
62
|
"*.log",
|
|
63
|
+
"**/*test.*",
|
|
62
64
|
];
|
|
63
65
|
|
|
64
66
|
/**
|
package/agents/publish-docs.mjs
CHANGED
|
@@ -117,7 +117,7 @@ async function getAccessToken(appUrl) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* Save boardId to
|
|
120
|
+
* Save boardId to config.yaml file if it was auto-created
|
|
121
121
|
* @param {string} boardId - The original boardId (may be empty)
|
|
122
122
|
* @param {string} newBoardId - The boardId returned from publishDocsFn
|
|
123
123
|
*/
|
|
@@ -130,7 +130,7 @@ async function saveBoardIdToInput(boardId, newBoardId) {
|
|
|
130
130
|
mkdirSync(docSmithDir, { recursive: true });
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
const inputFilePath = join(docSmithDir, "
|
|
133
|
+
const inputFilePath = join(docSmithDir, "config.yaml");
|
|
134
134
|
let fileContent = "";
|
|
135
135
|
|
|
136
136
|
// Read existing file content if it exists
|
|
@@ -156,12 +156,12 @@ async function saveBoardIdToInput(boardId, newBoardId) {
|
|
|
156
156
|
await writeFile(inputFilePath, fileContent);
|
|
157
157
|
console.log(`Board ID saved to: ${inputFilePath}`);
|
|
158
158
|
} catch (error) {
|
|
159
|
-
console.warn("Failed to save board ID to
|
|
159
|
+
console.warn("Failed to save board ID to config.yaml:", error.message);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
export default async function
|
|
164
|
+
export default async function publishDocs({ docsDir, appUrl, boardId }) {
|
|
165
165
|
const accessToken = await getAccessToken(appUrl);
|
|
166
166
|
|
|
167
167
|
process.env.DOC_ROOT_DIR = docsDir;
|
|
@@ -180,7 +180,7 @@ export default async function publish({ docsDir, appUrl, boardId }) {
|
|
|
180
180
|
autoCreateBoard: !boardId,
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
// Save boardId to
|
|
183
|
+
// Save boardId to config.yaml if it was auto-created
|
|
184
184
|
await saveBoardIdToInput(boardId, newBoardId);
|
|
185
185
|
|
|
186
186
|
return {
|
|
@@ -190,7 +190,7 @@ export default async function publish({ docsDir, appUrl, boardId }) {
|
|
|
190
190
|
};
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
publishDocs.input_schema = {
|
|
194
194
|
type: "object",
|
|
195
195
|
properties: {
|
|
196
196
|
docsDir: {
|
|
@@ -210,3 +210,5 @@ publish.input_schema = {
|
|
|
210
210
|
},
|
|
211
211
|
},
|
|
212
212
|
};
|
|
213
|
+
|
|
214
|
+
publishDocs.description = "Publish the documentation to Discuss Kit";
|
package/agents/save-docs.mjs
CHANGED
|
@@ -12,6 +12,7 @@ export default async function saveDocs({
|
|
|
12
12
|
structurePlanResult: structurePlan,
|
|
13
13
|
docsDir,
|
|
14
14
|
translateLanguages = [],
|
|
15
|
+
locale,
|
|
15
16
|
}) {
|
|
16
17
|
const results = [];
|
|
17
18
|
|
|
@@ -30,7 +31,8 @@ export default async function saveDocs({
|
|
|
30
31
|
const cleanupResults = await cleanupInvalidFiles(
|
|
31
32
|
structurePlan,
|
|
32
33
|
docsDir,
|
|
33
|
-
translateLanguages
|
|
34
|
+
translateLanguages,
|
|
35
|
+
locale
|
|
34
36
|
);
|
|
35
37
|
results.push(...cleanupResults);
|
|
36
38
|
} catch (err) {
|
|
@@ -40,14 +42,31 @@ export default async function saveDocs({
|
|
|
40
42
|
return { saveDocsResult: results };
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Generate filename based on flatName and language
|
|
47
|
+
* @param {string} flatName - Flattened path name
|
|
48
|
+
* @param {string} language - Language code
|
|
49
|
+
* @returns {string} - Generated filename
|
|
50
|
+
*/
|
|
51
|
+
function generateFileName(flatName, language) {
|
|
52
|
+
const isEnglish = language === "en";
|
|
53
|
+
return isEnglish ? `${flatName}.md` : `${flatName}.${language}.md`;
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
/**
|
|
44
57
|
* Clean up .md files that are no longer in the structure plan
|
|
45
58
|
* @param {Array<{path: string, title: string}>} structurePlan
|
|
46
59
|
* @param {string} docsDir
|
|
47
60
|
* @param {Array<string>} translateLanguages
|
|
61
|
+
* @param {string} locale - Main language locale (e.g., 'en', 'zh', 'fr')
|
|
48
62
|
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
49
63
|
*/
|
|
50
|
-
async function cleanupInvalidFiles(
|
|
64
|
+
async function cleanupInvalidFiles(
|
|
65
|
+
structurePlan,
|
|
66
|
+
docsDir,
|
|
67
|
+
translateLanguages,
|
|
68
|
+
locale
|
|
69
|
+
) {
|
|
51
70
|
const results = [];
|
|
52
71
|
|
|
53
72
|
try {
|
|
@@ -61,12 +80,14 @@ async function cleanupInvalidFiles(structurePlan, docsDir, translateLanguages) {
|
|
|
61
80
|
// Add main document files
|
|
62
81
|
for (const { path } of structurePlan) {
|
|
63
82
|
const flatName = path.replace(/^\//, "").replace(/\//g, "-");
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
|
|
84
|
+
// Main language file
|
|
85
|
+
const mainFileName = generateFileName(flatName, locale);
|
|
86
|
+
expectedFiles.add(mainFileName);
|
|
66
87
|
|
|
67
88
|
// Add translation files for each language
|
|
68
89
|
for (const lang of translateLanguages) {
|
|
69
|
-
const translateFileName =
|
|
90
|
+
const translateFileName = generateFileName(flatName, lang);
|
|
70
91
|
expectedFiles.add(translateFileName);
|
|
71
92
|
}
|
|
72
93
|
}
|
|
@@ -6,6 +6,7 @@ export default async function saveSingleDoc({
|
|
|
6
6
|
docsDir,
|
|
7
7
|
translates,
|
|
8
8
|
labels,
|
|
9
|
+
locale,
|
|
9
10
|
}) {
|
|
10
11
|
const results = await saveDocWithTranslations({
|
|
11
12
|
path,
|
|
@@ -13,6 +14,7 @@ export default async function saveSingleDoc({
|
|
|
13
14
|
docsDir,
|
|
14
15
|
translates,
|
|
15
16
|
labels,
|
|
17
|
+
locale,
|
|
16
18
|
});
|
|
17
19
|
return { saveSingleDocResult: results };
|
|
18
20
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type: team
|
|
2
|
+
name: publish
|
|
3
|
+
description: Publish the documentation to Discuss Kit
|
|
4
|
+
skills:
|
|
5
|
+
- load-config.mjs
|
|
6
|
+
- publish-docs.mjs
|
|
7
|
+
input_schema:
|
|
8
|
+
type: object
|
|
9
|
+
properties:
|
|
10
|
+
config:
|
|
11
|
+
type: string
|
|
12
|
+
description: Path to the config file
|
|
13
|
+
default: ./doc-smith/config.yaml
|
package/aigne.yaml
CHANGED
|
@@ -6,7 +6,6 @@ chat_model:
|
|
|
6
6
|
# name: gemini-2.5-flash-preview-05-20
|
|
7
7
|
temperature: 0.8
|
|
8
8
|
agents:
|
|
9
|
-
- ./agents/docs-generator.yaml
|
|
10
9
|
- ./agents/structure-planning.yaml
|
|
11
10
|
- ./agents/batch-docs-detail-generator.yaml
|
|
12
11
|
- ./agents/load-sources.mjs
|
|
@@ -23,6 +22,10 @@ agents:
|
|
|
23
22
|
- ./agents/reflective-structure-planner.yaml
|
|
24
23
|
- ./agents/check-structure-planning-result.yaml
|
|
25
24
|
- ./agents/input-generator.mjs
|
|
25
|
+
- ./agents/docs-generator.yaml
|
|
26
26
|
- ./agents/detail-regenerator.yaml
|
|
27
27
|
- ./agents/publish-docs.mjs
|
|
28
28
|
- ./agents/format-structure-plan.mjs
|
|
29
|
+
- ./agents/load-config.mjs
|
|
30
|
+
- ./agents/team-publish-docs.yaml
|
|
31
|
+
- ./agents/find-item-by-path.mjs
|
package/docs-mcp/aigne.yaml
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"main": "index.js",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
|
-
"lint": "biome check && pnpm -r run lint",
|
|
12
|
-
"update:deps": "npx -y taze major -r -w -f -n '/@abtnode|@aigne|@arcblock|@blocklet|@did-connect|@did-pay|@did-space|@nft-store|@nft-studio|@ocap/' && pnpm install && pnpm run deduplicate",
|
|
13
|
-
"deduplicate": "pnpm dedupe",
|
|
14
|
-
"lint:fix": "biome check --write && pnpm -r run lint"
|
|
15
|
-
},
|
|
16
9
|
"type": "module",
|
|
17
10
|
"bin": "aigne.yaml",
|
|
18
11
|
"keywords": [],
|
|
@@ -20,14 +13,21 @@
|
|
|
20
13
|
"license": "MIT",
|
|
21
14
|
"dependencies": {
|
|
22
15
|
"@aigne/anthropic": "^0.10.2",
|
|
23
|
-
"@aigne/cli": "^1.
|
|
16
|
+
"@aigne/cli": "^1.27.0",
|
|
24
17
|
"@aigne/core": "^1.39.0",
|
|
25
18
|
"@aigne/gemini": "^0.8.6",
|
|
26
19
|
"@aigne/openai": "^0.10.6",
|
|
27
|
-
"@aigne/publish-docs": "^0.
|
|
20
|
+
"@aigne/publish-docs": "^0.5.0",
|
|
28
21
|
"glob": "^11.0.3",
|
|
29
22
|
"open": "^10.2.0",
|
|
30
23
|
"ufo": "^1.6.1",
|
|
31
24
|
"yaml": "^2.8.0"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
28
|
+
"lint": "biome check && pnpm -r run lint",
|
|
29
|
+
"update:deps": "npx -y taze major -r -w -f -n '/@abtnode|@aigne|@arcblock|@blocklet|@did-connect|@did-pay|@did-space|@nft-store|@nft-studio|@ocap/' && pnpm install && pnpm run deduplicate",
|
|
30
|
+
"deduplicate": "pnpm dedupe",
|
|
31
|
+
"lint:fix": "biome check --write && pnpm -r run lint"
|
|
32
32
|
}
|
|
33
|
-
}
|
|
33
|
+
}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
你的主要目标是验证两条关键规则:
|
|
24
24
|
1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
|
|
25
25
|
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点**绝不能**被修改,特别是它们的 `path` 属性。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
26
|
+
3. **数据有效性**: 所有 {{ nodeName }} 都有关联数据源,sourceIds 中都有值。
|
|
26
27
|
</goal>
|
|
27
28
|
|
|
28
29
|
<rules>
|
|
@@ -71,6 +72,15 @@
|
|
|
71
72
|
"reason": "The new structure plan modified unrelated nodes, which is not allowed. [Please provide specific details, e.g.: 'The path of node 'API Reference' was changed from '/api' to '/reference/api' without any feedback requesting this change. This is a critical error.']"
|
|
72
73
|
}
|
|
73
74
|
```
|
|
75
|
+
|
|
76
|
+
* ** 如果数据无效 **:
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"isValid": false,
|
|
80
|
+
"reason": "The structure plan contains nodes without associated data sources. Each node must have at least one source file linked through sourcesIds."
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
74
84
|
* **如果是首次运行**:
|
|
75
85
|
|
|
76
86
|
```json
|
|
@@ -64,8 +64,10 @@ parentId: {{parentId}}
|
|
|
64
64
|
- 结合当前{{nodeName}}的标题、描述,合理规划{{nodeName}}内容结构,内容要丰富、有条理、有吸引力。
|
|
65
65
|
- 内容风格需要匹配目标受众
|
|
66
66
|
- 明确区分与 structurePlan 其他{{nodeName}}的内容,避免重复,突出本{{nodeName}}的独特价值。
|
|
67
|
+
{% if enforceInfoCompleteness %}
|
|
67
68
|
- 如果 DataSources 相关信息不足,直接返回错误信息,提示用户补充内容,要确保页面内容足够丰富,你可以放心的向用户提出补充信息的要求。
|
|
68
69
|
- 只展示有价值、能吸引用户的信息,如信息不足,提示用户补充信息
|
|
70
|
+
{% endif %}
|
|
69
71
|
- 输出为完整的信息,包含{{nodeName}}计划展示的全部信息。
|
|
70
72
|
- 确保每个{{nodeName}}的详情中,都包含一个 markdown 的一级标题,展示当前{{nodeName}}的标题:{{title}}
|
|
71
73
|
- markdown 输出内容正常换行、添加空行,让内容容易阅读
|
package/utils/utils.mjs
CHANGED
|
@@ -34,6 +34,7 @@ export function processContent({ content }) {
|
|
|
34
34
|
* @param {string} params.path - Relative path (without extension)
|
|
35
35
|
* @param {string} params.content - Main document content
|
|
36
36
|
* @param {string} params.docsDir - Root directory
|
|
37
|
+
* @param {string} params.locale - Main content language (e.g., 'en', 'zh', 'fr')
|
|
37
38
|
* @param {Array<{language: string, translation: string}>} [params.translates] - Translation content
|
|
38
39
|
* @param {Array<string>} [params.labels] - Document labels for front matter
|
|
39
40
|
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
@@ -42,6 +43,7 @@ export async function saveDocWithTranslations({
|
|
|
42
43
|
path: docPath,
|
|
43
44
|
content,
|
|
44
45
|
docsDir,
|
|
46
|
+
locale,
|
|
45
47
|
translates = [],
|
|
46
48
|
labels,
|
|
47
49
|
}) {
|
|
@@ -49,10 +51,18 @@ export async function saveDocWithTranslations({
|
|
|
49
51
|
try {
|
|
50
52
|
// Flatten path: remove leading /, replace all / with -
|
|
51
53
|
const flatName = docPath.replace(/^\//, "").replace(/\//g, "-");
|
|
52
|
-
const fileFullName = `${flatName}.md`;
|
|
53
|
-
const filePath = path.join(docsDir, fileFullName);
|
|
54
54
|
await fs.mkdir(docsDir, { recursive: true });
|
|
55
55
|
|
|
56
|
+
// Helper function to generate filename based on language
|
|
57
|
+
const getFileName = (language) => {
|
|
58
|
+
const isEnglish = language === "en";
|
|
59
|
+
return isEnglish ? `${flatName}.md` : `${flatName}.${language}.md`;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Save main content with appropriate filename based on locale
|
|
63
|
+
const mainFileName = getFileName(locale);
|
|
64
|
+
const mainFilePath = path.join(docsDir, mainFileName);
|
|
65
|
+
|
|
56
66
|
// Add labels front matter if labels are provided
|
|
57
67
|
let finalContent = processContent({ content });
|
|
58
68
|
if (labels && labels.length > 0) {
|
|
@@ -60,11 +70,12 @@ export async function saveDocWithTranslations({
|
|
|
60
70
|
finalContent = frontMatter + finalContent;
|
|
61
71
|
}
|
|
62
72
|
|
|
63
|
-
await fs.writeFile(
|
|
64
|
-
results.push({ path:
|
|
73
|
+
await fs.writeFile(mainFilePath, finalContent, "utf8");
|
|
74
|
+
results.push({ path: mainFilePath, success: true });
|
|
65
75
|
|
|
76
|
+
// Process all translations
|
|
66
77
|
for (const translate of translates) {
|
|
67
|
-
const translateFileName =
|
|
78
|
+
const translateFileName = getFileName(translate.language);
|
|
68
79
|
const translatePath = path.join(docsDir, translateFileName);
|
|
69
80
|
|
|
70
81
|
// Add labels front matter to translation content if labels are provided
|