@aigne/doc-smith 0.0.1 → 0.1.0
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 +49 -0
- package/README.md +27 -4
- package/agents/check-structure-planning-result.yaml +1 -1
- package/agents/check-structure-planning.mjs +4 -4
- package/agents/detail-generator-and-translate.yaml +1 -1
- package/agents/detail-regenerator.yaml +64 -65
- package/agents/docs-generator.yaml +67 -53
- 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 +33 -9
- package/agents/publish-docs.mjs +8 -6
- package/agents/save-docs.mjs +26 -5
- package/agents/save-single-doc.mjs +2 -0
- package/agents/structure-planning.yaml +1 -1
- package/agents/team-publish-docs.yaml +13 -0
- package/aigne.yaml +16 -1
- package/docs-mcp/aigne.yaml +0 -0
- package/docs-mcp/get-docs-detail.mjs +2 -3
- package/docs-mcp/get-docs-structure.mjs +8 -3
- package/package.json +11 -11
- package/prompts/check-structure-planning-result.md +17 -5
- package/prompts/content-detail-generator.md +2 -0
- package/prompts/structure-planning.md +3 -1
- 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,49 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.0.2...v0.1.0) (2025-07-31)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add entry agents for mcp server and cli ([fa85d65](https://github.com/AIGNE-io/aigne-doc-smith/commit/fa85d651e8dc723e2b97150fc2258b115c6c5bb0))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* polish command param ([#3](https://github.com/AIGNE-io/aigne-doc-smith/issues/3)) ([003f6b8](https://github.com/AIGNE-io/aigne-doc-smith/commit/003f6b8ae2c9e1af55ba1841458fa8567a0eb2f0))
|
|
14
|
+
* polish docs mcp agent ([8654cd4](https://github.com/AIGNE-io/aigne-doc-smith/commit/8654cd4ea38034f3af0244f56b27acf66ba704e1))
|
|
15
|
+
|
|
16
|
+
## 0.0.2 (2025-07-30)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* add auto create board ([3ff06ad](https://github.com/AIGNE-io/aigne-doc-smith/commit/3ff06ad0241e208b09bcf828c52c2c5051c67ef8))
|
|
22
|
+
* add docs-mcp ([a7508a1](https://github.com/AIGNE-io/aigne-doc-smith/commit/a7508a13abb2222968b1bc9c14948427af509f97))
|
|
23
|
+
* add input generator agent ([20c01bb](https://github.com/AIGNE-io/aigne-doc-smith/commit/20c01bbca6d6f9414695071fc907bd7cf43d7f62))
|
|
24
|
+
* add publish docs ([41bb126](https://github.com/AIGNE-io/aigne-doc-smith/commit/41bb126caeb1c3c242c7a2be27abb114aeab9953))
|
|
25
|
+
* add support docs labels ([4522c07](https://github.com/AIGNE-io/aigne-doc-smith/commit/4522c07b1ceb05664a1f5b5fb4df06feee536eba))
|
|
26
|
+
* detail add review ([8f1aa4f](https://github.com/AIGNE-io/aigne-doc-smith/commit/8f1aa4f22e2d2e590d7aa37288c2e1ee7ea48f07))
|
|
27
|
+
* init commit ([dafc40e](https://github.com/AIGNE-io/aigne-doc-smith/commit/dafc40e94f3c407e50b2c46ecb46237f23a15cf7))
|
|
28
|
+
* structure plan add review ([b56e83e](https://github.com/AIGNE-io/aigne-doc-smith/commit/b56e83e558f509302b422205f30e9b2adb42d452))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* polish agent name ([25875a0](https://github.com/AIGNE-io/aigne-doc-smith/commit/25875a0688ebbca71f6c25bf4bd5246361f3dd2d))
|
|
34
|
+
* polish agent param and description ([290eb24](https://github.com/AIGNE-io/aigne-doc-smith/commit/290eb240ce986b0f1f406bf42824ce1235df11e5))
|
|
35
|
+
* polish code ([34f9a24](https://github.com/AIGNE-io/aigne-doc-smith/commit/34f9a24fc3748b4177cad2b5330fe6b3ccd99175))
|
|
36
|
+
* polish code ([0343486](https://github.com/AIGNE-io/aigne-doc-smith/commit/0343486aa086bbe2ced8de849de6a4a42567719c))
|
|
37
|
+
* polish code ([7b7dfb9](https://github.com/AIGNE-io/aigne-doc-smith/commit/7b7dfb925b3aa55956ef7a99ededc749fb6a42d7))
|
|
38
|
+
* polish code ([4fa4694](https://github.com/AIGNE-io/aigne-doc-smith/commit/4fa4694dbbd5880d501883a7cf3c0d3494509fb4))
|
|
39
|
+
* polish code ([74fee51](https://github.com/AIGNE-io/aigne-doc-smith/commit/74fee51ad6337af8811a35f2a4334b67ec109439))
|
|
40
|
+
* polish code ([7fa1675](https://github.com/AIGNE-io/aigne-doc-smith/commit/7fa1675b2cab6144d1fb9d4388130209c6cfa0bc))
|
|
41
|
+
* polish docs review ([70374ab](https://github.com/AIGNE-io/aigne-doc-smith/commit/70374abed74946eafa7b0f87331c2e496fa61592))
|
|
42
|
+
* polish input generator agent ([ae908bb](https://github.com/AIGNE-io/aigne-doc-smith/commit/ae908bbc0cb98b9b196e8b08f23149e5693e0abe))
|
|
43
|
+
* polish structure plan ([3a0a196](https://github.com/AIGNE-io/aigne-doc-smith/commit/3a0a196a97196ba445c4709d3466ff355917ac53))
|
|
44
|
+
* save docs remove useless docs ([bec5ba3](https://github.com/AIGNE-io/aigne-doc-smith/commit/bec5ba3afd462c990a0aa813bbe38ce9a61363ee))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Miscellaneous Chores
|
|
48
|
+
|
|
49
|
+
* release 0.0.2 ([73bf26a](https://github.com/AIGNE-io/aigne-doc-smith/commit/73bf26a5c55fa4726d866cff64bd48d1ca37a3b3))
|
package/README.md
CHANGED
|
@@ -61,17 +61,40 @@ 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-getting-started
|
|
68
68
|
|
|
69
69
|
# 结构规划优化
|
|
70
|
-
npx --no doc-smith run --
|
|
70
|
+
npx --no doc-smith run --entry-agent generator --input-feedback "补充节点的 sourceIds,确保所有节点 sourceIds 都有值" --model gemini:gemini-2.5-pro
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
# 发布文档
|
|
74
|
-
npx --no doc-smith run --
|
|
74
|
+
npx --no doc-smith run --entry-agent publish
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
使用 `aigne doc` 运行
|
|
80
|
+
|
|
81
|
+
```shell
|
|
82
|
+
# 初始化
|
|
83
|
+
aigne doc init
|
|
84
|
+
|
|
85
|
+
# 生成文档
|
|
86
|
+
aigne doc generate
|
|
87
|
+
|
|
88
|
+
# 优化结构规划
|
|
89
|
+
aigne doc generate --feedback "删除 About 文档"
|
|
90
|
+
|
|
91
|
+
# 优化单篇文档
|
|
92
|
+
# 可使用 structure-plan.json 中的 path ,或 Discuss Kit 中访问的 path
|
|
93
|
+
aigne doc update --doc-path /faq --feedback "添加更多的 FAQ"
|
|
94
|
+
|
|
95
|
+
# 发布文档
|
|
96
|
+
aigne doc publish
|
|
97
|
+
|
|
75
98
|
|
|
76
99
|
```
|
|
77
100
|
|
|
@@ -9,11 +9,11 @@ import { OpenAIChatModel } from "@aigne/openai";
|
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
|
|
11
11
|
export default async function checkStructurePlanning(
|
|
12
|
-
{ originalStructurePlan,
|
|
12
|
+
{ originalStructurePlan, feedback, ...rest },
|
|
13
13
|
options
|
|
14
14
|
) {
|
|
15
15
|
// If originalStructurePlan exists, return directly
|
|
16
|
-
if (originalStructurePlan && !
|
|
16
|
+
if (originalStructurePlan && !feedback) {
|
|
17
17
|
return {
|
|
18
18
|
structurePlan: originalStructurePlan,
|
|
19
19
|
};
|
|
@@ -39,14 +39,14 @@ export default async function checkStructurePlanning(
|
|
|
39
39
|
const panningAgent = aigne.agents["reflective-structure-planner"];
|
|
40
40
|
|
|
41
41
|
const result = await options.context.invoke(panningAgent, {
|
|
42
|
-
|
|
42
|
+
feedback: feedback || "",
|
|
43
43
|
originalStructurePlan,
|
|
44
44
|
...rest,
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
return {
|
|
48
48
|
...result,
|
|
49
|
-
|
|
49
|
+
feedback: "", // clear feedback
|
|
50
50
|
originalStructurePlan: originalStructurePlan
|
|
51
51
|
? originalStructurePlan
|
|
52
52
|
: JSON.parse(JSON.stringify(result.structurePlan || [])),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
type: team
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
2
|
+
name: update
|
|
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
|
+
doc-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
|
-
name:
|
|
3
|
-
description:
|
|
2
|
+
name: generate
|
|
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
|
-
|
|
82
|
-
|
|
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
|
|
97
|
+
feedback:
|
|
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
|
+
"doc-path": docPath,
|
|
3
|
+
structurePlanResult,
|
|
4
|
+
boardId,
|
|
5
|
+
}) {
|
|
6
|
+
let foundItem = null;
|
|
7
|
+
|
|
8
|
+
// First try direct path matching
|
|
9
|
+
foundItem = structurePlanResult.find((item) => item.path === docPath);
|
|
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 (docPath.startsWith(`${boardId}-`)) {
|
|
15
|
+
// Extract the flattened path part after boardId-
|
|
16
|
+
const flattenedPath = docPath.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 "${docPath}" 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
|
/**
|
|
@@ -153,7 +155,8 @@ export default async function loadSources({
|
|
|
153
155
|
excludePatterns,
|
|
154
156
|
outputDir,
|
|
155
157
|
docsDir,
|
|
156
|
-
|
|
158
|
+
"doc-path": docPath,
|
|
159
|
+
boardId,
|
|
157
160
|
useDefaultPatterns = true,
|
|
158
161
|
} = {}) {
|
|
159
162
|
let files = Array.isArray(sources) ? [...sources] : [];
|
|
@@ -248,15 +251,32 @@ export default async function loadSources({
|
|
|
248
251
|
|
|
249
252
|
// Get the last output result of the specified path
|
|
250
253
|
let content;
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
if (docPath) {
|
|
255
|
+
let fileFullName;
|
|
256
|
+
|
|
257
|
+
// First try direct path matching (original format)
|
|
258
|
+
const flatName = docPath.replace(/^\//, "").replace(/\//g, "-");
|
|
259
|
+
fileFullName = `${flatName}.md`;
|
|
260
|
+
let filePath = path.join(docsDir, fileFullName);
|
|
261
|
+
|
|
255
262
|
try {
|
|
256
263
|
await access(filePath);
|
|
257
264
|
content = await readFile(filePath, "utf8");
|
|
258
265
|
} catch {
|
|
259
|
-
//
|
|
266
|
+
// If not found and boardId is provided, try boardId-flattenedPath format
|
|
267
|
+
if (boardId && docPath.startsWith(`${boardId}-`)) {
|
|
268
|
+
// Extract the flattened path part after boardId-
|
|
269
|
+
const flattenedPath = docPath.substring(boardId.length + 1);
|
|
270
|
+
fileFullName = `${flattenedPath}.md`;
|
|
271
|
+
filePath = path.join(docsDir, fileFullName);
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
await access(filePath);
|
|
275
|
+
content = await readFile(filePath, "utf8");
|
|
276
|
+
} catch {
|
|
277
|
+
// The file does not exist, content remains undefined
|
|
278
|
+
}
|
|
279
|
+
}
|
|
260
280
|
}
|
|
261
281
|
}
|
|
262
282
|
|
|
@@ -296,9 +316,13 @@ loadSources.input_schema = {
|
|
|
296
316
|
description:
|
|
297
317
|
"Whether to use default include/exclude patterns. Defaults to true.",
|
|
298
318
|
},
|
|
299
|
-
|
|
319
|
+
"doc-path": {
|
|
320
|
+
type: "string",
|
|
321
|
+
description: "The document path to load content for",
|
|
322
|
+
},
|
|
323
|
+
boardId: {
|
|
300
324
|
type: "string",
|
|
301
|
-
description: "The
|
|
325
|
+
description: "The board ID for boardId-flattenedPath format matching",
|
|
302
326
|
},
|
|
303
327
|
},
|
|
304
328
|
required: [],
|
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,22 @@ 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
|
|
32
|
+
mcp_server:
|
|
33
|
+
agents:
|
|
34
|
+
- ./agents/input-generator.mjs
|
|
35
|
+
- ./agents/docs-generator.yaml
|
|
36
|
+
- ./agents/detail-regenerator.yaml
|
|
37
|
+
- ./agents/publish-docs.mjs
|
|
38
|
+
cli:
|
|
39
|
+
agents:
|
|
40
|
+
- ./agents/input-generator.mjs
|
|
41
|
+
- ./agents/docs-generator.yaml
|
|
42
|
+
- ./agents/detail-regenerator.yaml
|
|
43
|
+
- ./agents/publish-docs.mjs
|
package/docs-mcp/aigne.yaml
CHANGED
|
File without changes
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
-
const docsDir =
|
|
5
|
-
"/Users/lban/arcblock/code/arcblock-sdk-docs/packages/aigne-framework/docs/";
|
|
4
|
+
const docsDir = path.join(process.cwd(), "doc-smith", "docs");
|
|
6
5
|
|
|
7
6
|
export default async function getDocDetail({ path: docPath }) {
|
|
8
7
|
try {
|
|
@@ -39,4 +38,4 @@ getDocDetail.input_schema = {
|
|
|
39
38
|
},
|
|
40
39
|
};
|
|
41
40
|
|
|
42
|
-
getDocDetail.description = "Get
|
|
41
|
+
getDocDetail.description = "Get single docs detail";
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
|
|
3
|
-
const structureDir =
|
|
4
|
-
|
|
4
|
+
const structureDir = path.join(
|
|
5
|
+
process.cwd(),
|
|
6
|
+
"doc-smith",
|
|
7
|
+
"output",
|
|
8
|
+
"structure-plan.json"
|
|
9
|
+
);
|
|
5
10
|
|
|
6
11
|
export default async function getDocsStructure() {
|
|
7
12
|
const structure = await fs.readFile(structureDir, "utf-8");
|
|
8
13
|
return { structure };
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
getDocsStructure.description = "Get
|
|
16
|
+
getDocsStructure.description = "Get docs structure";
|
package/package.json
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
}
|
|
@@ -13,16 +13,19 @@
|
|
|
13
13
|
{{ structurePlan }}
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
-
|
|
16
|
+
- **用户反馈**:
|
|
17
17
|
```
|
|
18
|
-
{{
|
|
18
|
+
{{ feedback }}
|
|
19
|
+
|
|
20
|
+
根据最新的 Data Sources 按需要更新节点的 sourceIds ,更新至状态。
|
|
19
21
|
```
|
|
20
22
|
</context>
|
|
21
23
|
|
|
22
24
|
<goal>
|
|
23
25
|
你的主要目标是验证两条关键规则:
|
|
24
26
|
1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
|
|
25
|
-
2.
|
|
27
|
+
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path 属性不能被修改 **。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
28
|
+
3. **数据有效性**: 所有 {{ nodeName }} 都有关联数据源,sourceIds 中都有值。
|
|
26
29
|
</goal>
|
|
27
30
|
|
|
28
31
|
<rules>
|
|
@@ -34,12 +37,12 @@
|
|
|
34
37
|
这是主要场景。你必须执行详细的比较。
|
|
35
38
|
|
|
36
39
|
**分步分析**:
|
|
37
|
-
1. **分析反馈**:仔细阅读并理解 `<context>` 中
|
|
40
|
+
1. **分析反馈**:仔细阅读并理解 `<context>` 中 用户反馈 提出的每一项变更要求。明确哪些节点是需要被修改、添加或删除的目标。
|
|
38
41
|
2. **验证反馈的实现**:对比 `<context>` 中的 `structurePlan` 和 `originalStructurePlan`,确认所要求的变更是否已执行。例如,如果反馈是“移除‘示例’部分”,你必须检查该部分在 `structurePlan` 中是否已不存在。
|
|
39
42
|
3. **验证无关节点的稳定性**:这是最关键的检查。遍历 `structurePlan` 中的所有节点。对于每一个在 `originalStructurePlan` 中也存在、但并未在反馈中被提及的节点:
|
|
40
43
|
* **至关重要**:其 `path` 属性**必须**与 `originalStructurePlan` 中的完全相同。
|
|
41
44
|
* 理想情况下,其他属性(如 `title`)也应保持稳定,除非这些变更是由某个被要求的变更直接导致的。
|
|
42
|
-
|
|
45
|
+
4. **`sourcesIds` 是允许变更的**,每次结构规划可以根据最新的 DataSources 变更依赖的数据源,sourceIds 不能为空。
|
|
43
46
|
</rules>
|
|
44
47
|
|
|
45
48
|
<output>
|
|
@@ -71,6 +74,15 @@
|
|
|
71
74
|
"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
75
|
}
|
|
73
76
|
```
|
|
77
|
+
|
|
78
|
+
* ** 如果数据无效 **:
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"isValid": false,
|
|
82
|
+
"reason": "The structure plan contains nodes without associated data sources. Each node must have at least one source file linked through sourcesIds."
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
74
86
|
* **如果是首次运行**:
|
|
75
87
|
|
|
76
88
|
```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
|