@aigne/doc-smith 0.1.3 → 0.2.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/PULL_REQUEST_TEMPLATE.md +28 -0
- package/CHANGELOG.md +15 -0
- package/README.md +3 -3
- package/agents/batch-docs-detail-generator.yaml +4 -0
- package/agents/check-detail-generated.mjs +33 -3
- package/agents/check-detail-result.mjs +52 -41
- package/agents/check-structure-planning.mjs +43 -9
- package/agents/detail-regenerator.yaml +3 -0
- package/agents/docs-generator.yaml +3 -0
- package/agents/input-generator.mjs +148 -32
- package/agents/load-config.mjs +1 -0
- package/agents/load-sources.mjs +44 -63
- package/agents/publish-docs.mjs +53 -46
- package/agents/save-docs.mjs +9 -0
- package/agents/team-publish-docs.yaml +3 -0
- package/agents/transform-detail-datasources.mjs +19 -5
- package/package.json +7 -7
- package/prompts/check-structure-planning-result.md +1 -1
- package/prompts/structure-planning.md +1 -1
- package/utils/constants.mjs +60 -0
- package/utils/utils.mjs +299 -0
package/agents/load-sources.mjs
CHANGED
|
@@ -1,67 +1,14 @@
|
|
|
1
1
|
import { access, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { glob } from "glob";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"*.go",
|
|
13
|
-
"*.java",
|
|
14
|
-
"*.pyi",
|
|
15
|
-
"*.pyx",
|
|
16
|
-
"*.c",
|
|
17
|
-
"*.cc",
|
|
18
|
-
"*.cpp",
|
|
19
|
-
"*.h",
|
|
20
|
-
"*.md",
|
|
21
|
-
"*.rst",
|
|
22
|
-
"*.json",
|
|
23
|
-
"*Dockerfile",
|
|
24
|
-
"*Makefile",
|
|
25
|
-
"*.yaml",
|
|
26
|
-
"*.yml",
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const DEFAULT_EXCLUDE_PATTERNS = [
|
|
30
|
-
"aigne-docs/**",
|
|
31
|
-
"doc-smith/**",
|
|
32
|
-
"assets/**",
|
|
33
|
-
"data/**",
|
|
34
|
-
"images/**",
|
|
35
|
-
"public/**",
|
|
36
|
-
"static/**",
|
|
37
|
-
"**/vendor/**",
|
|
38
|
-
"temp/**",
|
|
39
|
-
"**/*docs/**",
|
|
40
|
-
"**/*doc/**",
|
|
41
|
-
"**/*venv/**",
|
|
42
|
-
"*.venv/**",
|
|
43
|
-
"*test*",
|
|
44
|
-
"**/*test/**",
|
|
45
|
-
"**/*tests/**",
|
|
46
|
-
"**/*examples/**",
|
|
47
|
-
"**/playgrounds/**",
|
|
48
|
-
"v1/**",
|
|
49
|
-
"**/dist/**",
|
|
50
|
-
"**/*build/**",
|
|
51
|
-
"**/*experimental/**",
|
|
52
|
-
"**/*deprecated/**",
|
|
53
|
-
"**/*misc/**",
|
|
54
|
-
"**/*legacy/**",
|
|
55
|
-
".git/**",
|
|
56
|
-
".github/**",
|
|
57
|
-
".next/**",
|
|
58
|
-
".vscode/**",
|
|
59
|
-
"**/*obj/**",
|
|
60
|
-
"**/*bin/**",
|
|
61
|
-
"**/*node_modules/**",
|
|
62
|
-
"*.log",
|
|
63
|
-
"**/*test.*",
|
|
64
|
-
];
|
|
4
|
+
import {
|
|
5
|
+
getCurrentGitHead,
|
|
6
|
+
getModifiedFilesBetweenCommits,
|
|
7
|
+
} from "../utils/utils.mjs";
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_INCLUDE_PATTERNS,
|
|
10
|
+
DEFAULT_EXCLUDE_PATTERNS,
|
|
11
|
+
} from "../utils/constants.mjs";
|
|
65
12
|
|
|
66
13
|
/**
|
|
67
14
|
* Load .gitignore patterns from a directory
|
|
@@ -158,6 +105,7 @@ export default async function loadSources({
|
|
|
158
105
|
"doc-path": docPath,
|
|
159
106
|
boardId,
|
|
160
107
|
useDefaultPatterns = true,
|
|
108
|
+
lastGitHead,
|
|
161
109
|
} = {}) {
|
|
162
110
|
let files = Array.isArray(sources) ? [...sources] : [];
|
|
163
111
|
|
|
@@ -224,9 +172,11 @@ export default async function loadSources({
|
|
|
224
172
|
const sourceFiles = await Promise.all(
|
|
225
173
|
files.map(async (file) => {
|
|
226
174
|
const content = await readFile(file, "utf8");
|
|
227
|
-
|
|
175
|
+
// Convert absolute path to relative path from project root
|
|
176
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
177
|
+
allSources += `// sourceId: ${relativePath}\n${content}\n`;
|
|
228
178
|
return {
|
|
229
|
-
sourceId:
|
|
179
|
+
sourceId: relativePath,
|
|
230
180
|
content,
|
|
231
181
|
};
|
|
232
182
|
})
|
|
@@ -280,12 +230,34 @@ export default async function loadSources({
|
|
|
280
230
|
}
|
|
281
231
|
}
|
|
282
232
|
|
|
233
|
+
// Get git change detection data
|
|
234
|
+
let modifiedFiles = [];
|
|
235
|
+
let currentGitHead = null;
|
|
236
|
+
|
|
237
|
+
if (lastGitHead) {
|
|
238
|
+
try {
|
|
239
|
+
currentGitHead = getCurrentGitHead();
|
|
240
|
+
if (currentGitHead && currentGitHead !== lastGitHead) {
|
|
241
|
+
modifiedFiles = getModifiedFilesBetweenCommits(
|
|
242
|
+
lastGitHead,
|
|
243
|
+
currentGitHead
|
|
244
|
+
);
|
|
245
|
+
console.log(
|
|
246
|
+
`Detected ${modifiedFiles.length} modified files since last generation`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.warn("Failed to detect git changes:", error.message);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
283
254
|
return {
|
|
284
255
|
datasourcesList: sourceFiles,
|
|
285
256
|
datasources: allSources,
|
|
286
257
|
content,
|
|
287
258
|
originalStructurePlan,
|
|
288
259
|
files,
|
|
260
|
+
modifiedFiles,
|
|
289
261
|
};
|
|
290
262
|
}
|
|
291
263
|
|
|
@@ -324,6 +296,10 @@ loadSources.input_schema = {
|
|
|
324
296
|
type: "string",
|
|
325
297
|
description: "The board ID for boardId-flattenedPath format matching",
|
|
326
298
|
},
|
|
299
|
+
lastGitHead: {
|
|
300
|
+
type: "string",
|
|
301
|
+
description: "The git HEAD from last generation for change detection",
|
|
302
|
+
},
|
|
327
303
|
},
|
|
328
304
|
required: [],
|
|
329
305
|
};
|
|
@@ -349,5 +325,10 @@ loadSources.output_schema = {
|
|
|
349
325
|
items: { type: "string" },
|
|
350
326
|
description: "Array of file paths that were loaded",
|
|
351
327
|
},
|
|
328
|
+
modifiedFiles: {
|
|
329
|
+
type: "array",
|
|
330
|
+
items: { type: "string" },
|
|
331
|
+
description: "Array of modified files since last generation",
|
|
332
|
+
},
|
|
352
333
|
},
|
|
353
334
|
};
|
package/agents/publish-docs.mjs
CHANGED
|
@@ -9,8 +9,10 @@ import { homedir } from "node:os";
|
|
|
9
9
|
import { parse, stringify } from "yaml";
|
|
10
10
|
import { execSync } from "node:child_process";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
|
+
import { loadConfigFromFile, saveValueToConfig } from "../utils/utils.mjs";
|
|
12
13
|
|
|
13
14
|
const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
|
|
15
|
+
const DEFAULT_APP_URL = "https://docsmith.aigne.io";
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Get project name from git repository or current directory
|
|
@@ -116,51 +118,50 @@ async function getAccessToken(appUrl) {
|
|
|
116
118
|
return accessToken;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const inputFilePath = join(docSmithDir, "config.yaml");
|
|
134
|
-
let fileContent = "";
|
|
135
|
-
|
|
136
|
-
// Read existing file content if it exists
|
|
137
|
-
if (existsSync(inputFilePath)) {
|
|
138
|
-
fileContent = await readFile(inputFilePath, "utf8");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Check if boardId already exists in the file
|
|
142
|
-
const boardIdRegex = /^boardId:\s*.*$/m;
|
|
143
|
-
const newBoardIdLine = `boardId: ${newBoardId}`;
|
|
144
|
-
|
|
145
|
-
if (boardIdRegex.test(fileContent)) {
|
|
146
|
-
// Replace existing boardId line
|
|
147
|
-
fileContent = fileContent.replace(boardIdRegex, newBoardIdLine);
|
|
148
|
-
} else {
|
|
149
|
-
// Add boardId to the end of file
|
|
150
|
-
if (fileContent && !fileContent.endsWith("\n")) {
|
|
151
|
-
fileContent += "\n";
|
|
152
|
-
}
|
|
153
|
-
fileContent += newBoardIdLine + "\n";
|
|
154
|
-
}
|
|
121
|
+
export default async function publishDocs(
|
|
122
|
+
{ docsDir, appUrl, boardId },
|
|
123
|
+
options
|
|
124
|
+
) {
|
|
125
|
+
// Check if appUrl is default and not saved in config
|
|
126
|
+
const config = await loadConfigFromFile();
|
|
127
|
+
const isDefaultAppUrl = appUrl === DEFAULT_APP_URL;
|
|
128
|
+
const hasAppUrlInConfig = config && config.appUrl;
|
|
129
|
+
|
|
130
|
+
if (isDefaultAppUrl && !hasAppUrlInConfig) {
|
|
131
|
+
console.log("\n=== Document Publishing Platform Selection ===");
|
|
132
|
+
console.log(
|
|
133
|
+
"Please select the platform where you want to publish your documents:"
|
|
134
|
+
);
|
|
155
135
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
136
|
+
const choice = await options.prompts.select({
|
|
137
|
+
message: "Select publishing platform:",
|
|
138
|
+
choices: [
|
|
139
|
+
{
|
|
140
|
+
name: "Use official platform (docsmith.aigne.io) - Documents will be publicly accessible, suitable for open source projects",
|
|
141
|
+
value: "default",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "Use private platform - Deploy your own Discuss Kit instance, suitable for internal documentation",
|
|
145
|
+
value: "custom",
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
if (choice === "custom") {
|
|
151
|
+
appUrl = await options.prompts.input({
|
|
152
|
+
message: "Please enter your Discuss Kit platform URL:",
|
|
153
|
+
validate: (input) => {
|
|
154
|
+
try {
|
|
155
|
+
new URL(input);
|
|
156
|
+
return true;
|
|
157
|
+
} catch {
|
|
158
|
+
return "Please enter a valid URL";
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
});
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
|
-
}
|
|
162
164
|
|
|
163
|
-
export default async function publishDocs({ docsDir, appUrl, boardId }) {
|
|
164
165
|
const accessToken = await getAccessToken(appUrl);
|
|
165
166
|
|
|
166
167
|
process.env.DOC_ROOT_DIR = docsDir;
|
|
@@ -179,8 +180,16 @@ export default async function publishDocs({ docsDir, appUrl, boardId }) {
|
|
|
179
180
|
autoCreateBoard: !boardId,
|
|
180
181
|
});
|
|
181
182
|
|
|
182
|
-
// Save
|
|
183
|
-
|
|
183
|
+
// Save values to config.yaml if publish was successful
|
|
184
|
+
if (success) {
|
|
185
|
+
// Save appUrl to config
|
|
186
|
+
await saveValueToConfig("appUrl", appUrl);
|
|
187
|
+
|
|
188
|
+
// Save boardId to config if it was auto-created
|
|
189
|
+
if (!boardId && newBoardId) {
|
|
190
|
+
await saveValueToConfig("boardId", newBoardId);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
184
193
|
|
|
185
194
|
return {
|
|
186
195
|
publishResult: {
|
|
@@ -199,9 +208,7 @@ publishDocs.input_schema = {
|
|
|
199
208
|
appUrl: {
|
|
200
209
|
type: "string",
|
|
201
210
|
description: "The url of the app",
|
|
202
|
-
default:
|
|
203
|
-
// "https://bbqawfllzdt3pahkdsrsone6p3wpxcwp62vlabtawfu.did.abtnet.io",
|
|
204
|
-
"https://www.staging.arcblock.io",
|
|
211
|
+
default: DEFAULT_APP_URL,
|
|
205
212
|
},
|
|
206
213
|
boardId: {
|
|
207
214
|
type: "string",
|
package/agents/save-docs.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { writeFile, readdir, unlink } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getCurrentGitHead, saveGitHeadToConfig } from "../utils/utils.mjs";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @param {Object} params
|
|
@@ -16,6 +17,14 @@ export default async function saveDocs({
|
|
|
16
17
|
}) {
|
|
17
18
|
const results = [];
|
|
18
19
|
|
|
20
|
+
// Save current git HEAD to config.yaml for change detection
|
|
21
|
+
try {
|
|
22
|
+
const gitHead = getCurrentGitHead();
|
|
23
|
+
await saveGitHeadToConfig(gitHead);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.warn("Failed to save git HEAD:", err.message);
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
// Generate _sidebar.md
|
|
20
29
|
try {
|
|
21
30
|
const sidebar = generateSidebar(structurePlan);
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
import { normalizePath, toRelativePath } from "../utils/utils.mjs";
|
|
2
|
+
|
|
1
3
|
export default function transformDetailDatasources({
|
|
2
4
|
sourceIds,
|
|
3
5
|
datasourcesList,
|
|
4
6
|
}) {
|
|
5
|
-
// Build a map for fast lookup
|
|
7
|
+
// Build a map for fast lookup, with path normalization for compatibility
|
|
6
8
|
const dsMap = Object.fromEntries(
|
|
7
|
-
(datasourcesList || []).map((ds) =>
|
|
9
|
+
(datasourcesList || []).map((ds) => {
|
|
10
|
+
const normalizedSourceId = normalizePath(ds.sourceId);
|
|
11
|
+
return [normalizedSourceId, ds.content];
|
|
12
|
+
})
|
|
8
13
|
);
|
|
9
|
-
|
|
14
|
+
|
|
15
|
+
// Collect formatted contents in order, with path normalization
|
|
10
16
|
const contents = (sourceIds || [])
|
|
11
|
-
.filter((id) =>
|
|
12
|
-
|
|
17
|
+
.filter((id) => {
|
|
18
|
+
const normalizedId = normalizePath(id);
|
|
19
|
+
return dsMap[normalizedId];
|
|
20
|
+
})
|
|
21
|
+
.map((id) => {
|
|
22
|
+
const normalizedId = normalizePath(id);
|
|
23
|
+
const relativeId = toRelativePath(id);
|
|
24
|
+
return `// sourceId: ${relativeId}\n${dsMap[normalizedId]}\n`;
|
|
25
|
+
});
|
|
26
|
+
|
|
13
27
|
return { detailDataSources: contents.join("") };
|
|
14
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@aigne/anthropic": "^0.10.
|
|
16
|
-
"@aigne/cli": "^1.
|
|
17
|
-
"@aigne/core": "^1.
|
|
18
|
-
"@aigne/gemini": "^0.8.
|
|
19
|
-
"@aigne/openai": "^0.10.
|
|
20
|
-
"@aigne/publish-docs": "^0.5.
|
|
15
|
+
"@aigne/anthropic": "^0.10.6",
|
|
16
|
+
"@aigne/cli": "^1.30.1",
|
|
17
|
+
"@aigne/core": "^1.43.0",
|
|
18
|
+
"@aigne/gemini": "^0.8.10",
|
|
19
|
+
"@aigne/openai": "^0.10.10",
|
|
20
|
+
"@aigne/publish-docs": "^0.5.2",
|
|
21
21
|
"glob": "^11.0.3",
|
|
22
22
|
"open": "^10.2.0",
|
|
23
23
|
"ufo": "^1.6.1",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Default file patterns for inclusion and exclusion
|
|
2
|
+
export const DEFAULT_INCLUDE_PATTERNS = [
|
|
3
|
+
"*.py",
|
|
4
|
+
"*.js",
|
|
5
|
+
"*.jsx",
|
|
6
|
+
"*.ts",
|
|
7
|
+
"*.tsx",
|
|
8
|
+
"*.go",
|
|
9
|
+
"*.java",
|
|
10
|
+
"*.pyi",
|
|
11
|
+
"*.pyx",
|
|
12
|
+
"*.c",
|
|
13
|
+
"*.cc",
|
|
14
|
+
"*.cpp",
|
|
15
|
+
"*.h",
|
|
16
|
+
"*.md",
|
|
17
|
+
"*.rst",
|
|
18
|
+
"*.json",
|
|
19
|
+
"*Dockerfile",
|
|
20
|
+
"*Makefile",
|
|
21
|
+
"*.yaml",
|
|
22
|
+
"*.yml",
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
export const DEFAULT_EXCLUDE_PATTERNS = [
|
|
26
|
+
"aigne-docs/**",
|
|
27
|
+
"doc-smith/**",
|
|
28
|
+
"assets/**",
|
|
29
|
+
"data/**",
|
|
30
|
+
"images/**",
|
|
31
|
+
"public/**",
|
|
32
|
+
"static/**",
|
|
33
|
+
"**/vendor/**",
|
|
34
|
+
"temp/**",
|
|
35
|
+
"**/*docs/**",
|
|
36
|
+
"**/*doc/**",
|
|
37
|
+
"**/*venv/**",
|
|
38
|
+
"*.venv/**",
|
|
39
|
+
"*test*",
|
|
40
|
+
"**/*test/**",
|
|
41
|
+
"**/*tests/**",
|
|
42
|
+
"**/*examples/**",
|
|
43
|
+
"**/playgrounds/**",
|
|
44
|
+
"v1/**",
|
|
45
|
+
"**/dist/**",
|
|
46
|
+
"**/*build/**",
|
|
47
|
+
"**/*experimental/**",
|
|
48
|
+
"**/*deprecated/**",
|
|
49
|
+
"**/*misc/**",
|
|
50
|
+
"**/*legacy/**",
|
|
51
|
+
".git/**",
|
|
52
|
+
".github/**",
|
|
53
|
+
".next/**",
|
|
54
|
+
".vscode/**",
|
|
55
|
+
"**/*obj/**",
|
|
56
|
+
"**/*bin/**",
|
|
57
|
+
"**/*node_modules/**",
|
|
58
|
+
"*.log",
|
|
59
|
+
"**/*test.*",
|
|
60
|
+
];
|