@aigne/doc-smith 0.0.2 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
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
+
3
16
  ## 0.0.2 (2025-07-30)
4
17
 
5
18
 
package/README.md CHANGED
@@ -64,14 +64,14 @@ npx --no doc-smith run --entry-agent init
64
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 --entry-agent regenerator --input-path bitnet-m4XQ-core-concepts-quantization
67
+ npx --no doc-smith run --entry-agent regenerator --input-path bitnet-getting-started
68
68
 
69
69
  # 结构规划优化
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
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 --input @./doc-smith/config.yaml --format yaml --entry-agent publish
74
+ npx --no doc-smith run --entry-agent publish
75
75
 
76
76
 
77
77
  ```
@@ -83,10 +83,14 @@ npx --no doc-smith run --input @./doc-smith/config.yaml --format yaml --entry-ag
83
83
  aigne doc init
84
84
 
85
85
  # 生成文档
86
- aigne doc generator
86
+ aigne doc generate
87
+
88
+ # 优化结构规划
89
+ aigne doc generate --feedback "删除 About 文档"
87
90
 
88
91
  # 优化单篇文档
89
- aigne doc regenerator --path bitnet-m4XQ-core-concepts-quantization # 可使用 structure-plan.json 中的 path ,或 Discuss Kit 中访问的 path
92
+ # 可使用 structure-plan.json 中的 path ,或 Discuss Kit 中访问的 path
93
+ aigne doc update --doc-path /faq --feedback "添加更多的 FAQ"
90
94
 
91
95
  # 发布文档
92
96
  aigne doc publish
@@ -11,7 +11,7 @@ input_schema:
11
11
  originalStructurePlan:
12
12
  $ref: ./schema/structure-plan.yaml
13
13
  description: 上一轮生成的结构规划,用于对比。如果不存在,则检查默认通过。
14
- structurePlanFeedback:
14
+ feedback:
15
15
  type: string
16
16
  description: 用户针对上一轮结果提供的反馈。
17
17
  required:
@@ -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, structurePlanFeedback, ...rest },
12
+ { originalStructurePlan, feedback, ...rest },
13
13
  options
14
14
  ) {
15
15
  // If originalStructurePlan exists, return directly
16
- if (originalStructurePlan && !structurePlanFeedback) {
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
- structurePlanFeedback,
42
+ feedback: feedback || "",
43
43
  originalStructurePlan,
44
44
  ...rest,
45
45
  });
46
46
 
47
47
  return {
48
48
  ...result,
49
- structurePlanFeedback,
49
+ feedback: "", // clear feedback
50
50
  originalStructurePlan: originalStructurePlan
51
51
  ? originalStructurePlan
52
52
  : JSON.parse(JSON.stringify(result.structurePlan || [])),
@@ -35,7 +35,7 @@ input_schema:
35
35
  glossary:
36
36
  type: string
37
37
  description: 术语表
38
- currentPath:
38
+ doc-path:
39
39
  type: string
40
40
  description: 当前路径
41
41
  feedback:
@@ -1,5 +1,5 @@
1
1
  type: team
2
- name: regenerator
2
+ name: update
3
3
  description: Optimize and regenerate individual document content and translations
4
4
  skills:
5
5
  - ./load-config.mjs
@@ -43,7 +43,7 @@ input_schema:
43
43
  glossary:
44
44
  type: string
45
45
  description: Glossary of terms for consistent terminology
46
- path:
46
+ doc-path:
47
47
  type: string
48
48
  description: Document path to regenerate
49
49
  feedback:
@@ -1,5 +1,5 @@
1
1
  type: team
2
- name: generator
2
+ name: generate
3
3
  description: Automatically generates comprehensive project documentation
4
4
  skills:
5
5
  - ./load-config.mjs
@@ -94,7 +94,7 @@ input_schema:
94
94
  # type: string
95
95
  # description: Type of documentation (general, getting-started, reference, faq)
96
96
  # default: general
97
- structurePlanFeedback:
97
+ feedback:
98
98
  type: string
99
99
  description: Feedback for structure planning adjustments
100
100
  # labels:
@@ -1,19 +1,19 @@
1
1
  export default async function findItemByPath({
2
- path,
2
+ "doc-path": docPath,
3
3
  structurePlanResult,
4
4
  boardId,
5
5
  }) {
6
6
  let foundItem = null;
7
7
 
8
8
  // First try direct path matching
9
- foundItem = structurePlanResult.find((item) => item.path === path);
9
+ foundItem = structurePlanResult.find((item) => item.path === docPath);
10
10
 
11
11
  // If not found and boardId is provided, try boardId-flattenedPath format matching
12
12
  if (!foundItem && boardId) {
13
13
  // Check if path starts with boardId followed by a dash
14
- if (path.startsWith(`${boardId}-`)) {
14
+ if (docPath.startsWith(`${boardId}-`)) {
15
15
  // Extract the flattened path part after boardId-
16
- const flattenedPath = path.substring(boardId.length + 1);
16
+ const flattenedPath = docPath.substring(boardId.length + 1);
17
17
 
18
18
  // Find item by comparing flattened paths
19
19
  foundItem = structurePlanResult.find((item) => {
@@ -28,7 +28,7 @@ export default async function findItemByPath({
28
28
 
29
29
  if (!foundItem) {
30
30
  throw new Error(
31
- `Item with path "${path}" not found in structurePlanResult`
31
+ `Item with path "${docPath}" not found in structurePlanResult`
32
32
  );
33
33
  }
34
34
 
@@ -155,7 +155,8 @@ export default async function loadSources({
155
155
  excludePatterns,
156
156
  outputDir,
157
157
  docsDir,
158
- currentPath,
158
+ "doc-path": docPath,
159
+ boardId,
159
160
  useDefaultPatterns = true,
160
161
  } = {}) {
161
162
  let files = Array.isArray(sources) ? [...sources] : [];
@@ -250,15 +251,32 @@ export default async function loadSources({
250
251
 
251
252
  // Get the last output result of the specified path
252
253
  let content;
253
- if (currentPath) {
254
- const flatName = currentPath.replace(/^\//, "").replace(/\//g, "-");
255
- const fileFullName = `${flatName}.md`;
256
- const filePath = path.join(docsDir, fileFullName);
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
+
257
262
  try {
258
263
  await access(filePath);
259
264
  content = await readFile(filePath, "utf8");
260
265
  } catch {
261
- // The file does not exist, content remains undefined
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
+ }
262
280
  }
263
281
  }
264
282
 
@@ -298,9 +316,13 @@ loadSources.input_schema = {
298
316
  description:
299
317
  "Whether to use default include/exclude patterns. Defaults to true.",
300
318
  },
301
- currentPath: {
319
+ "doc-path": {
320
+ type: "string",
321
+ description: "The document path to load content for",
322
+ },
323
+ boardId: {
302
324
  type: "string",
303
- description: "The current path of the document",
325
+ description: "The board ID for boardId-flattenedPath format matching",
304
326
  },
305
327
  },
306
328
  required: [],
@@ -23,7 +23,7 @@ input_schema:
23
23
  glossary:
24
24
  type: string
25
25
  description: 术语表
26
- structurePlanFeedback:
26
+ feedback:
27
27
  type: string
28
28
  description: 结构规划的反馈
29
29
  docsType:
package/aigne.yaml CHANGED
@@ -29,3 +29,15 @@ agents:
29
29
  - ./agents/load-config.mjs
30
30
  - ./agents/team-publish-docs.yaml
31
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
@@ -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 AIGNE Framework single docs detail";
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
- "/Users/lban/arcblock/code/arcblock-sdk-docs/packages/aigne-framework/output/structure-plan.json";
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 AIGNE Framework docs structure";
16
+ getDocsStructure.description = "Get docs structure";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/doc-smith",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -13,16 +13,18 @@
13
13
  {{ structurePlan }}
14
14
  ```
15
15
 
16
- - **用户反馈 (structurePlanFeedback)**:
16
+ - **用户反馈**:
17
17
  ```
18
- {{ structurePlanFeedback }}
18
+ {{ feedback }}
19
+
20
+ 根据最新的 Data Sources 按需要更新节点的 sourceIds ,更新至状态。
19
21
  ```
20
22
  </context>
21
23
 
22
24
  <goal>
23
25
  你的主要目标是验证两条关键规则:
24
26
  1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
25
- 2. **无关节点的稳定性**:没有在用户反馈中被提及的节点**绝不能**被修改,特别是它们的 `path` 属性。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
27
+ 2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path 属性不能被修改 **。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
26
28
  3. **数据有效性**: 所有 {{ nodeName }} 都有关联数据源,sourceIds 中都有值。
27
29
  </goal>
28
30
 
@@ -35,12 +37,12 @@
35
37
  这是主要场景。你必须执行详细的比较。
36
38
 
37
39
  **分步分析**:
38
- 1. **分析反馈**:仔细阅读并理解 `<context>` 中 `structurePlanFeedback` 提供的每一项变更要求。明确哪些节点是需要被修改、添加或删除的目标。
40
+ 1. **分析反馈**:仔细阅读并理解 `<context>` 中 用户反馈 提出的每一项变更要求。明确哪些节点是需要被修改、添加或删除的目标。
39
41
  2. **验证反馈的实现**:对比 `<context>` 中的 `structurePlan` 和 `originalStructurePlan`,确认所要求的变更是否已执行。例如,如果反馈是“移除‘示例’部分”,你必须检查该部分在 `structurePlan` 中是否已不存在。
40
42
  3. **验证无关节点的稳定性**:这是最关键的检查。遍历 `structurePlan` 中的所有节点。对于每一个在 `originalStructurePlan` 中也存在、但并未在反馈中被提及的节点:
41
43
  * **至关重要**:其 `path` 属性**必须**与 `originalStructurePlan` 中的完全相同。
42
44
  * 理想情况下,其他属性(如 `title`)也应保持稳定,除非这些变更是由某个被要求的变更直接导致的。
43
- * **`sourcesIds` 的变更是允许的**,可以根据最新的 DataSources 变更依赖的数据源
45
+ 4. **`sourcesIds` 是允许变更的**,每次结构规划可以根据最新的 DataSources 变更依赖的数据源,sourceIds 不能为空。
44
46
  </rules>
45
47
 
46
48
  <output>
@@ -28,7 +28,9 @@
28
28
  </last_structure_plan>
29
29
 
30
30
  <structure_plan_feedback>
31
- {{structurePlanFeedback}}
31
+ {{ feedback }}
32
+
33
+ 根据最新的 Data Sources 按需要更新节点的 sourceIds ,更新至状态。
32
34
  </structure_plan_feedback>
33
35
 
34
36
  <review_structure_plan>