@aigne/doc-smith 0.2.6 → 0.2.8
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 +19 -0
- package/agents/check-detail-result.mjs +2 -7
- package/agents/check-detail.mjs +4 -6
- package/agents/check-structure-plan.mjs +5 -10
- package/agents/find-item-by-path.mjs +2 -2
- package/agents/input-generator.mjs +12 -11
- package/agents/language-selector.mjs +6 -18
- package/agents/load-config.mjs +2 -2
- package/agents/load-sources.mjs +13 -40
- package/agents/publish-docs.mjs +8 -13
- package/agents/save-docs.mjs +8 -20
- package/agents/save-output.mjs +2 -9
- package/agents/save-single-doc.mjs +2 -2
- package/agents/schema/structure-plan.yaml +1 -1
- package/agents/transform-detail-datasources.mjs +2 -5
- package/biome.json +13 -3
- package/docs-mcp/get-docs-structure.mjs +1 -1
- package/docs-mcp/read-doc-content.mjs +1 -4
- package/package.json +10 -6
- package/tests/check-detail-result.test.mjs +8 -19
- package/tests/load-sources.test.mjs +65 -161
- package/tests/test-all-validation-cases.mjs +71 -37
- package/tests/test-save-docs.mjs +6 -17
- package/utils/constants.mjs +1 -2
- package/utils/markdown-checker.mjs +124 -57
- package/utils/mermaid-validator.mjs +5 -10
- package/utils/mermaid-worker-pool.mjs +7 -11
- package/utils/mermaid-worker.mjs +8 -17
- package/utils/utils.mjs +52 -104
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.8](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.2.7...v0.2.8) (2025-08-13)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Miscellaneous Chores
|
|
7
|
+
|
|
8
|
+
* release 0.2.8 ([da19bc0](https://github.com/AIGNE-io/aigne-doc-smith/commit/da19bc0b2c6c4e5fddaff84b4fa85c9d495b3ba0))
|
|
9
|
+
|
|
10
|
+
## [0.2.7](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.2.6...v0.2.7) (2025-08-12)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* polish detail check ([#21](https://github.com/AIGNE-io/aigne-doc-smith/issues/21)) ([0268732](https://github.com/AIGNE-io/aigne-doc-smith/commit/02687329c3507b73f9cbf1aa2ff1b87921452516))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Miscellaneous Chores
|
|
19
|
+
|
|
20
|
+
* release 0.2.7 ([3b807fe](https://github.com/AIGNE-io/aigne-doc-smith/commit/3b807fed833a5160931747bce37aac00cf11d9ac))
|
|
21
|
+
|
|
3
22
|
## [0.2.6](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.2.5...v0.2.6) (2025-08-12)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { checkMarkdown } from "../utils/markdown-checker.mjs";
|
|
2
2
|
|
|
3
|
-
export default async function checkDetailResult({
|
|
4
|
-
structurePlan,
|
|
5
|
-
reviewContent,
|
|
6
|
-
}) {
|
|
3
|
+
export default async function checkDetailResult({ structurePlan, reviewContent }) {
|
|
7
4
|
let isApproved = true;
|
|
8
5
|
const detailFeedback = [];
|
|
9
6
|
|
|
@@ -35,9 +32,7 @@ export default async function checkDetailResult({
|
|
|
35
32
|
}
|
|
36
33
|
} catch (error) {
|
|
37
34
|
isApproved = false;
|
|
38
|
-
detailFeedback.push(
|
|
39
|
-
`Found markdown validation error in result: ${error.message}`
|
|
40
|
-
);
|
|
35
|
+
detailFeedback.push(`Found markdown validation error in result: ${error.message}`);
|
|
41
36
|
}
|
|
42
37
|
|
|
43
38
|
return {
|
package/agents/check-detail.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import { access, readFile } from "node:fs/promises";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { TeamAgent } from "@aigne/core";
|
|
5
|
-
import checkDetailResult from "./check-detail-result.mjs";
|
|
6
5
|
import { hasSourceFilesChanged } from "../utils/utils.mjs";
|
|
6
|
+
import checkDetailResult from "./check-detail-result.mjs";
|
|
7
7
|
|
|
8
8
|
// Get current script directory
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -20,7 +20,7 @@ export default async function checkDetail(
|
|
|
20
20
|
forceRegenerate,
|
|
21
21
|
...rest
|
|
22
22
|
},
|
|
23
|
-
options
|
|
23
|
+
options,
|
|
24
24
|
) {
|
|
25
25
|
// Check if the detail file already exists
|
|
26
26
|
const flatName = path.replace(/^\//, "").replace(/\//g, "-");
|
|
@@ -41,11 +41,9 @@ export default async function checkDetail(
|
|
|
41
41
|
let sourceIdsChanged = false;
|
|
42
42
|
if (originalStructurePlan && sourceIds) {
|
|
43
43
|
// Find the original node in the structure plan
|
|
44
|
-
const originalNode = originalStructurePlan.find(
|
|
45
|
-
(node) => node.path === path
|
|
46
|
-
);
|
|
44
|
+
const originalNode = originalStructurePlan.find((node) => node.path === path);
|
|
47
45
|
|
|
48
|
-
if (originalNode
|
|
46
|
+
if (originalNode?.sourceIds) {
|
|
49
47
|
const originalSourceIds = originalNode.sourceIds;
|
|
50
48
|
const currentSourceIds = sourceIds;
|
|
51
49
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getCurrentGitHead,
|
|
3
|
+
getProjectInfo,
|
|
3
4
|
hasFileChangesBetweenCommits,
|
|
4
5
|
loadConfigFromFile,
|
|
5
6
|
saveValueToConfig,
|
|
6
|
-
getProjectInfo,
|
|
7
7
|
} from "../utils/utils.mjs";
|
|
8
8
|
|
|
9
9
|
export default async function checkStructurePlan(
|
|
10
10
|
{ originalStructurePlan, feedback, lastGitHead, ...rest },
|
|
11
|
-
options
|
|
11
|
+
options,
|
|
12
12
|
) {
|
|
13
13
|
// Check if we need to regenerate structure plan
|
|
14
14
|
let shouldRegenerate = false;
|
|
@@ -23,10 +23,7 @@ export default async function checkStructurePlan(
|
|
|
23
23
|
// Check if there are relevant file changes since last generation
|
|
24
24
|
const currentGitHead = getCurrentGitHead();
|
|
25
25
|
if (currentGitHead && currentGitHead !== lastGitHead) {
|
|
26
|
-
const hasChanges = hasFileChangesBetweenCommits(
|
|
27
|
-
lastGitHead,
|
|
28
|
-
currentGitHead
|
|
29
|
-
);
|
|
26
|
+
const hasChanges = hasFileChangesBetweenCommits(lastGitHead, currentGitHead);
|
|
30
27
|
if (hasChanges) {
|
|
31
28
|
shouldRegenerate = true;
|
|
32
29
|
}
|
|
@@ -71,11 +68,9 @@ export default async function checkStructurePlan(
|
|
|
71
68
|
|
|
72
69
|
// Check if user has modified project information
|
|
73
70
|
const userModifiedProjectName =
|
|
74
|
-
currentConfig?.projectName &&
|
|
75
|
-
currentConfig.projectName !== projectInfo.name;
|
|
71
|
+
currentConfig?.projectName && currentConfig.projectName !== projectInfo.name;
|
|
76
72
|
const userModifiedProjectDesc =
|
|
77
|
-
currentConfig?.projectDesc &&
|
|
78
|
-
currentConfig.projectDesc !== projectInfo.description;
|
|
73
|
+
currentConfig?.projectDesc && currentConfig.projectDesc !== projectInfo.description;
|
|
79
74
|
|
|
80
75
|
// If user hasn't modified project info and it's not from GitHub, save AI output
|
|
81
76
|
if (!userModifiedProjectName && !userModifiedProjectDesc) {
|
|
@@ -42,7 +42,7 @@ export default async function findItemByPath(
|
|
|
42
42
|
// Let user select a file
|
|
43
43
|
const selectedFile = await options.prompts.search({
|
|
44
44
|
message: getActionText(isTranslate, "Select a document to {action}:"),
|
|
45
|
-
source: async (input
|
|
45
|
+
source: async (input) => {
|
|
46
46
|
if (!input || input.trim() === "") {
|
|
47
47
|
return mainLanguageFiles.map((file) => ({
|
|
48
48
|
name: file,
|
|
@@ -159,7 +159,7 @@ export default async function findItemByPath(
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// Add feedback to result if provided
|
|
162
|
-
if (userFeedback
|
|
162
|
+
if (userFeedback?.trim()) {
|
|
163
163
|
result.feedback = userFeedback.trim();
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import {
|
|
5
|
-
validatePath,
|
|
6
|
-
getAvailablePaths,
|
|
7
|
-
getProjectInfo,
|
|
8
|
-
} from "../utils/utils.mjs";
|
|
9
|
-
import {
|
|
10
|
-
SUPPORTED_LANGUAGES,
|
|
11
5
|
DOCUMENT_STYLES,
|
|
6
|
+
SUPPORTED_LANGUAGES,
|
|
12
7
|
TARGET_AUDIENCES,
|
|
13
8
|
} from "../utils/constants.mjs";
|
|
9
|
+
import {
|
|
10
|
+
getAvailablePaths,
|
|
11
|
+
getProjectInfo,
|
|
12
|
+
validatePath,
|
|
13
|
+
} from "../utils/utils.mjs";
|
|
14
|
+
|
|
14
15
|
// UI constants
|
|
15
|
-
const
|
|
16
|
+
const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Guide users through multi-turn dialogue to collect information and generate YAML configuration
|
|
@@ -132,7 +133,7 @@ export default async function init(
|
|
|
132
133
|
while (true) {
|
|
133
134
|
const selectedPath = await options.prompts.search({
|
|
134
135
|
message: "Path:",
|
|
135
|
-
source: async (input
|
|
136
|
+
source: async (input) => {
|
|
136
137
|
if (!input || input.trim() === "") {
|
|
137
138
|
return [
|
|
138
139
|
{
|
|
@@ -242,7 +243,7 @@ function generateYAML(input) {
|
|
|
242
243
|
|
|
243
244
|
// Add rules (required field)
|
|
244
245
|
yaml += `rules: |\n`;
|
|
245
|
-
if (input.rules
|
|
246
|
+
if (input.rules?.trim()) {
|
|
246
247
|
yaml += ` ${input.rules.split("\n").join("\n ")}\n\n`;
|
|
247
248
|
} else {
|
|
248
249
|
yaml += ` \n\n`;
|
|
@@ -8,10 +8,7 @@ import { SUPPORTED_LANGUAGES } from "../utils/constants.mjs";
|
|
|
8
8
|
* @param {Object} options - Options object with prompts
|
|
9
9
|
* @returns {Promise<Object>} Selected languages
|
|
10
10
|
*/
|
|
11
|
-
export default async function languageSelector(
|
|
12
|
-
{ languages, translateLanguages },
|
|
13
|
-
options
|
|
14
|
-
) {
|
|
11
|
+
export default async function languageSelector({ languages, translateLanguages }, options) {
|
|
15
12
|
let selectedLanguages = [];
|
|
16
13
|
|
|
17
14
|
// Check if translateLanguages is available from config
|
|
@@ -21,24 +18,19 @@ export default async function languageSelector(
|
|
|
21
18
|
translateLanguages.length === 0
|
|
22
19
|
) {
|
|
23
20
|
throw new Error(
|
|
24
|
-
"No translation languages configured in config.yaml. Please add translateLanguages to your configuration."
|
|
21
|
+
"No translation languages configured in config.yaml. Please add translateLanguages to your configuration.",
|
|
25
22
|
);
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
// If languages are provided as parameter, validate against configured languages
|
|
29
26
|
if (languages && Array.isArray(languages) && languages.length > 0) {
|
|
30
|
-
const validLanguages = languages.filter((lang) =>
|
|
31
|
-
translateLanguages.includes(lang)
|
|
32
|
-
);
|
|
27
|
+
const validLanguages = languages.filter((lang) => translateLanguages.includes(lang));
|
|
33
28
|
|
|
34
29
|
if (validLanguages.length > 0) {
|
|
35
30
|
selectedLanguages = validLanguages;
|
|
36
31
|
} else {
|
|
37
32
|
console.log(`⚠️ Invalid languages provided: ${languages.join(", ")}`);
|
|
38
|
-
console.log(
|
|
39
|
-
"Available configured languages:",
|
|
40
|
-
translateLanguages.join(", ")
|
|
41
|
-
);
|
|
33
|
+
console.log("Available configured languages:", translateLanguages.join(", "));
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
36
|
|
|
@@ -46,13 +38,9 @@ export default async function languageSelector(
|
|
|
46
38
|
if (selectedLanguages.length === 0) {
|
|
47
39
|
// Create choices from configured languages with labels
|
|
48
40
|
const choices = translateLanguages.map((langCode) => {
|
|
49
|
-
const supportedLang = SUPPORTED_LANGUAGES.find(
|
|
50
|
-
(l) => l.code === langCode
|
|
51
|
-
);
|
|
41
|
+
const supportedLang = SUPPORTED_LANGUAGES.find((l) => l.code === langCode);
|
|
52
42
|
return {
|
|
53
|
-
name: supportedLang
|
|
54
|
-
? `${supportedLang.label} (${supportedLang.sample})`
|
|
55
|
-
: langCode,
|
|
43
|
+
name: supportedLang ? `${supportedLang.label} (${supportedLang.sample})` : langCode,
|
|
56
44
|
value: langCode,
|
|
57
45
|
short: langCode,
|
|
58
46
|
};
|
package/agents/load-config.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
import { parse } from "yaml";
|
|
4
4
|
|
|
5
5
|
export default async function loadConfig({ config }) {
|
|
@@ -8,7 +8,7 @@ export default async function loadConfig({ config }) {
|
|
|
8
8
|
try {
|
|
9
9
|
// Check if config file exists
|
|
10
10
|
await fs.access(configPath);
|
|
11
|
-
} catch (
|
|
11
|
+
} catch (_error) {
|
|
12
12
|
console.log(`Config file not found: ${configPath}`);
|
|
13
13
|
console.log("Please run 'aigne doc init' to create the config file.");
|
|
14
14
|
throw new Error(`Config file not found: ${configPath}`);
|
package/agents/load-sources.mjs
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { access, readFile, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { glob } from "glob";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
getModifiedFilesBetweenCommits,
|
|
7
|
-
} from "../utils/utils.mjs";
|
|
8
|
-
import {
|
|
9
|
-
DEFAULT_INCLUDE_PATTERNS,
|
|
10
|
-
DEFAULT_EXCLUDE_PATTERNS,
|
|
11
|
-
} from "../utils/constants.mjs";
|
|
4
|
+
import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS } from "../utils/constants.mjs";
|
|
5
|
+
import { getCurrentGitHead, getModifiedFilesBetweenCommits } from "../utils/utils.mjs";
|
|
12
6
|
|
|
13
7
|
/**
|
|
14
8
|
* Load .gitignore patterns from a directory
|
|
@@ -42,12 +36,7 @@ async function loadGitignore(dir) {
|
|
|
42
36
|
* @param {string[]} gitignorePatterns - .gitignore patterns
|
|
43
37
|
* @returns {Promise<string[]>} Array of file paths
|
|
44
38
|
*/
|
|
45
|
-
async function getFilesWithGlob(
|
|
46
|
-
dir,
|
|
47
|
-
includePatterns,
|
|
48
|
-
excludePatterns,
|
|
49
|
-
gitignorePatterns
|
|
50
|
-
) {
|
|
39
|
+
async function getFilesWithGlob(dir, includePatterns, excludePatterns, gitignorePatterns) {
|
|
51
40
|
// Prepare all ignore patterns
|
|
52
41
|
const allIgnorePatterns = [];
|
|
53
42
|
|
|
@@ -88,9 +77,7 @@ async function getFilesWithGlob(
|
|
|
88
77
|
|
|
89
78
|
return files;
|
|
90
79
|
} catch (error) {
|
|
91
|
-
console.warn(
|
|
92
|
-
`Warning: Error during glob search in ${dir}: ${error.message}`
|
|
93
|
-
);
|
|
80
|
+
console.warn(`Warning: Error during glob search in ${dir}: ${error.message}`);
|
|
94
81
|
return [];
|
|
95
82
|
}
|
|
96
83
|
}
|
|
@@ -143,14 +130,8 @@ export default async function loadSources({
|
|
|
143
130
|
: [excludePatterns]
|
|
144
131
|
: [];
|
|
145
132
|
|
|
146
|
-
finalIncludePatterns = [
|
|
147
|
-
|
|
148
|
-
...userInclude,
|
|
149
|
-
];
|
|
150
|
-
finalExcludePatterns = [
|
|
151
|
-
...DEFAULT_EXCLUDE_PATTERNS,
|
|
152
|
-
...userExclude,
|
|
153
|
-
];
|
|
133
|
+
finalIncludePatterns = [...DEFAULT_INCLUDE_PATTERNS, ...userInclude];
|
|
134
|
+
finalExcludePatterns = [...DEFAULT_EXCLUDE_PATTERNS, ...userExclude];
|
|
154
135
|
} else {
|
|
155
136
|
// Use only user patterns
|
|
156
137
|
if (includePatterns) {
|
|
@@ -170,7 +151,7 @@ export default async function loadSources({
|
|
|
170
151
|
dir,
|
|
171
152
|
finalIncludePatterns,
|
|
172
153
|
finalExcludePatterns,
|
|
173
|
-
gitignorePatterns
|
|
154
|
+
gitignorePatterns,
|
|
174
155
|
);
|
|
175
156
|
allFiles = allFiles.concat(filesInDir);
|
|
176
157
|
}
|
|
@@ -194,7 +175,7 @@ export default async function loadSources({
|
|
|
194
175
|
sourceId: relativePath,
|
|
195
176
|
content,
|
|
196
177
|
};
|
|
197
|
-
})
|
|
178
|
+
}),
|
|
198
179
|
);
|
|
199
180
|
|
|
200
181
|
// Get the last structure plan result
|
|
@@ -253,13 +234,8 @@ export default async function loadSources({
|
|
|
253
234
|
try {
|
|
254
235
|
currentGitHead = getCurrentGitHead();
|
|
255
236
|
if (currentGitHead && currentGitHead !== lastGitHead) {
|
|
256
|
-
modifiedFiles = getModifiedFilesBetweenCommits(
|
|
257
|
-
|
|
258
|
-
currentGitHead
|
|
259
|
-
);
|
|
260
|
-
console.log(
|
|
261
|
-
`Detected ${modifiedFiles.length} modified files since last generation`
|
|
262
|
-
);
|
|
237
|
+
modifiedFiles = getModifiedFilesBetweenCommits(lastGitHead, currentGitHead);
|
|
238
|
+
console.log(`Detected ${modifiedFiles.length} modified files since last generation`);
|
|
263
239
|
}
|
|
264
240
|
} catch (error) {
|
|
265
241
|
console.warn("Failed to detect git changes:", error.message);
|
|
@@ -290,18 +266,15 @@ loadSources.input_schema = {
|
|
|
290
266
|
},
|
|
291
267
|
includePatterns: {
|
|
292
268
|
anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
|
|
293
|
-
description:
|
|
294
|
-
"Glob patterns to filter files by path or filename. If not set, include all.",
|
|
269
|
+
description: "Glob patterns to filter files by path or filename. If not set, include all.",
|
|
295
270
|
},
|
|
296
271
|
excludePatterns: {
|
|
297
272
|
anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
|
|
298
|
-
description:
|
|
299
|
-
"Glob patterns to exclude files by path or filename. If not set, exclude none.",
|
|
273
|
+
description: "Glob patterns to exclude files by path or filename. If not set, exclude none.",
|
|
300
274
|
},
|
|
301
275
|
useDefaultPatterns: {
|
|
302
276
|
type: "boolean",
|
|
303
|
-
description:
|
|
304
|
-
"Whether to use default include/exclude patterns. Defaults to true.",
|
|
277
|
+
description: "Whether to use default include/exclude patterns. Defaults to true.",
|
|
305
278
|
},
|
|
306
279
|
"doc-path": {
|
|
307
280
|
type: "string",
|
package/agents/publish-docs.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { joinURL } from "ufo";
|
|
3
|
-
import open from "open";
|
|
4
|
-
import { publishDocs as publishDocsFn } from "@aigne/publish-docs";
|
|
5
|
-
import { createConnect } from "@aigne/cli/utils/load-aigne.js";
|
|
6
1
|
import { existsSync, mkdirSync } from "node:fs";
|
|
7
2
|
import { readFile, writeFile } from "node:fs/promises";
|
|
8
3
|
import { homedir } from "node:os";
|
|
4
|
+
import { basename, join } from "node:path";
|
|
5
|
+
import { createConnect } from "@aigne/aigne-hub";
|
|
6
|
+
import { publishDocs as publishDocsFn } from "@aigne/publish-docs";
|
|
7
|
+
import open from "open";
|
|
8
|
+
import { joinURL } from "ufo";
|
|
9
9
|
import { parse, stringify } from "yaml";
|
|
10
|
-
import { basename } from "node:path";
|
|
11
10
|
import { loadConfigFromFile, saveValueToConfig } from "../utils/utils.mjs";
|
|
12
11
|
|
|
13
12
|
const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
|
|
@@ -35,7 +34,7 @@ async function getAccessToken(appUrl) {
|
|
|
35
34
|
const data = await readFile(DOC_SMITH_ENV_FILE, "utf8");
|
|
36
35
|
if (data.includes("DOC_DISCUSS_KIT_ACCESS_TOKEN")) {
|
|
37
36
|
const envs = parse(data);
|
|
38
|
-
if (envs[hostname]
|
|
37
|
+
if (envs[hostname]?.DOC_DISCUSS_KIT_ACCESS_TOKEN) {
|
|
39
38
|
accessToken = envs[hostname].DOC_DISCUSS_KIT_ACCESS_TOKEN;
|
|
40
39
|
}
|
|
41
40
|
}
|
|
@@ -115,7 +114,7 @@ export default async function publishDocs(
|
|
|
115
114
|
// Check if appUrl is default and not saved in config (only when not using env variable)
|
|
116
115
|
const config = await loadConfigFromFile();
|
|
117
116
|
const isDefaultAppUrl = appUrl === DEFAULT_APP_URL;
|
|
118
|
-
const hasAppUrlInConfig = config
|
|
117
|
+
const hasAppUrlInConfig = config?.appUrl;
|
|
119
118
|
|
|
120
119
|
if (!useEnvAppUrl && isDefaultAppUrl && !hasAppUrlInConfig) {
|
|
121
120
|
const choice = await options.prompts.select({
|
|
@@ -161,11 +160,7 @@ export default async function publishDocs(
|
|
|
161
160
|
};
|
|
162
161
|
|
|
163
162
|
try {
|
|
164
|
-
const {
|
|
165
|
-
success,
|
|
166
|
-
boardId: newBoardId,
|
|
167
|
-
docsUrl,
|
|
168
|
-
} = await publishDocsFn({
|
|
163
|
+
const { success, boardId: newBoardId } = await publishDocsFn({
|
|
169
164
|
sidebarPath,
|
|
170
165
|
accessToken,
|
|
171
166
|
appUrl,
|
package/agents/save-docs.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readdir, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { getCurrentGitHead, saveGitHeadToConfig } from "../utils/utils.mjs";
|
|
4
3
|
import { shutdownMermaidWorkerPool } from "../utils/mermaid-worker-pool.mjs";
|
|
4
|
+
import { getCurrentGitHead, saveGitHeadToConfig } from "../utils/utils.mjs";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {Object} params
|
|
@@ -17,7 +17,7 @@ export default async function saveDocs({
|
|
|
17
17
|
locale,
|
|
18
18
|
projectInfoMessage,
|
|
19
19
|
}) {
|
|
20
|
-
const
|
|
20
|
+
const _results = [];
|
|
21
21
|
// Save current git HEAD to config.yaml for change detection
|
|
22
22
|
try {
|
|
23
23
|
const gitHead = getCurrentGitHead();
|
|
@@ -37,12 +37,7 @@ export default async function saveDocs({
|
|
|
37
37
|
|
|
38
38
|
// Clean up invalid .md files that are no longer in the structure plan
|
|
39
39
|
try {
|
|
40
|
-
await cleanupInvalidFiles(
|
|
41
|
-
structurePlan,
|
|
42
|
-
docsDir,
|
|
43
|
-
translateLanguages,
|
|
44
|
-
locale
|
|
45
|
-
);
|
|
40
|
+
await cleanupInvalidFiles(structurePlan, docsDir, translateLanguages, locale);
|
|
46
41
|
} catch (err) {
|
|
47
42
|
console.error("Failed to cleanup invalid .md files:", err.message);
|
|
48
43
|
}
|
|
@@ -112,12 +107,7 @@ function generateFileName(flatName, language) {
|
|
|
112
107
|
* @param {string} locale - Main language locale (e.g., 'en', 'zh', 'fr')
|
|
113
108
|
* @returns {Promise<Array<{ path: string, success: boolean, error?: string }>>}
|
|
114
109
|
*/
|
|
115
|
-
async function cleanupInvalidFiles(
|
|
116
|
-
structurePlan,
|
|
117
|
-
docsDir,
|
|
118
|
-
translateLanguages,
|
|
119
|
-
locale
|
|
120
|
-
) {
|
|
110
|
+
async function cleanupInvalidFiles(structurePlan, docsDir, translateLanguages, locale) {
|
|
121
111
|
const results = [];
|
|
122
112
|
|
|
123
113
|
try {
|
|
@@ -145,7 +135,7 @@ async function cleanupInvalidFiles(
|
|
|
145
135
|
|
|
146
136
|
// Find files to delete (files that are not in expectedFiles and not _sidebar.md)
|
|
147
137
|
const filesToDelete = mdFiles.filter(
|
|
148
|
-
(file) => !expectedFiles.has(file) && file !== "_sidebar.md"
|
|
138
|
+
(file) => !expectedFiles.has(file) && file !== "_sidebar.md",
|
|
149
139
|
);
|
|
150
140
|
|
|
151
141
|
// Delete invalid files
|
|
@@ -168,9 +158,7 @@ async function cleanupInvalidFiles(
|
|
|
168
158
|
}
|
|
169
159
|
|
|
170
160
|
if (filesToDelete.length > 0) {
|
|
171
|
-
console.log(
|
|
172
|
-
`Cleaned up ${filesToDelete.length} invalid .md files from ${docsDir}`
|
|
173
|
-
);
|
|
161
|
+
console.log(`Cleaned up ${filesToDelete.length} invalid .md files from ${docsDir}`);
|
|
174
162
|
}
|
|
175
163
|
} catch (err) {
|
|
176
164
|
// If docsDir doesn't exist or can't be read, that's okay
|
|
@@ -209,7 +197,7 @@ function generateSidebar(structurePlan) {
|
|
|
209
197
|
for (const key of Object.keys(node)) {
|
|
210
198
|
const item = node[key];
|
|
211
199
|
const fullSegments = [...parentSegments, key];
|
|
212
|
-
const flatFile = fullSegments.join("-")
|
|
200
|
+
const flatFile = `${fullSegments.join("-")}.md`;
|
|
213
201
|
if (item.__title) {
|
|
214
202
|
const realIndent = item.__parentId === null ? "" : indent;
|
|
215
203
|
out += `${realIndent}* [${item.__title}](/${flatFile})\n`;
|
package/agents/save-output.mjs
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
|
-
export default async function saveOutput({
|
|
5
|
-
savePath,
|
|
6
|
-
fileName,
|
|
7
|
-
saveKey,
|
|
8
|
-
...rest
|
|
9
|
-
}) {
|
|
4
|
+
export default async function saveOutput({ savePath, fileName, saveKey, ...rest }) {
|
|
10
5
|
if (!(saveKey in rest)) {
|
|
11
6
|
console.warn(`saveKey "${saveKey}" not found in input, skip saving.`);
|
|
12
7
|
return {
|
|
@@ -17,9 +12,7 @@ export default async function saveOutput({
|
|
|
17
12
|
|
|
18
13
|
const value = rest[saveKey];
|
|
19
14
|
const content =
|
|
20
|
-
typeof value === "object" && value !== null
|
|
21
|
-
? JSON.stringify(value, null, 2)
|
|
22
|
-
: String(value);
|
|
15
|
+
typeof value === "object" && value !== null ? JSON.stringify(value, null, 2) : String(value);
|
|
23
16
|
await fs.mkdir(savePath, { recursive: true });
|
|
24
17
|
const filePath = join(savePath, fileName);
|
|
25
18
|
await fs.writeFile(filePath, content, "utf8");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { saveDocWithTranslations } from "../utils/utils.mjs";
|
|
2
1
|
import { shutdownMermaidWorkerPool } from "../utils/mermaid-worker-pool.mjs";
|
|
2
|
+
import { saveDocWithTranslations } from "../utils/utils.mjs";
|
|
3
3
|
|
|
4
4
|
export default async function saveSingleDoc({
|
|
5
5
|
path,
|
|
@@ -11,7 +11,7 @@ export default async function saveSingleDoc({
|
|
|
11
11
|
isTranslate = false,
|
|
12
12
|
isShowMessage = false,
|
|
13
13
|
}) {
|
|
14
|
-
const
|
|
14
|
+
const _results = await saveDocWithTranslations({
|
|
15
15
|
path,
|
|
16
16
|
content,
|
|
17
17
|
docsDir,
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { normalizePath, toRelativePath } from "../utils/utils.mjs";
|
|
2
2
|
|
|
3
|
-
export default function transformDetailDatasources({
|
|
4
|
-
sourceIds,
|
|
5
|
-
datasourcesList,
|
|
6
|
-
}) {
|
|
3
|
+
export default function transformDetailDatasources({ sourceIds, datasourcesList }) {
|
|
7
4
|
// Build a map for fast lookup, with path normalization for compatibility
|
|
8
5
|
const dsMap = Object.fromEntries(
|
|
9
6
|
(datasourcesList || []).map((ds) => {
|
|
10
7
|
const normalizedSourceId = normalizePath(ds.sourceId);
|
|
11
8
|
return [normalizedSourceId, ds.content];
|
|
12
|
-
})
|
|
9
|
+
}),
|
|
13
10
|
);
|
|
14
11
|
|
|
15
12
|
// Collect formatted contents in order, with path normalization
|
package/biome.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://biomejs.dev/schemas/2.1.
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.1.4/schema.json",
|
|
3
3
|
"vcs": {
|
|
4
4
|
"enabled": true,
|
|
5
5
|
"clientKind": "git",
|
|
@@ -23,11 +23,21 @@
|
|
|
23
23
|
"noUnusedVariables": "error",
|
|
24
24
|
"noUnusedImports": "error",
|
|
25
25
|
"noUnusedFunctionParameters": "error",
|
|
26
|
-
"noUnusedPrivateClassMembers": "error"
|
|
26
|
+
"noUnusedPrivateClassMembers": "error",
|
|
27
|
+
"noUndeclaredVariables": "error",
|
|
28
|
+
"noUnreachable": "error",
|
|
29
|
+
"noSelfAssign": "error"
|
|
27
30
|
},
|
|
28
31
|
"suspicious": {
|
|
29
32
|
"noConfusingVoidType": "off",
|
|
30
|
-
"noExplicitAny": "off"
|
|
33
|
+
"noExplicitAny": "off",
|
|
34
|
+
"noDoubleEquals": "error",
|
|
35
|
+
"noGlobalAssign": "error",
|
|
36
|
+
"noAssignInExpressions": "warn"
|
|
37
|
+
},
|
|
38
|
+
"style": {
|
|
39
|
+
"useNodejsImportProtocol": "error",
|
|
40
|
+
"useTemplate": "error"
|
|
31
41
|
},
|
|
32
42
|
"complexity": {
|
|
33
43
|
"noForEach": "off",
|
|
@@ -3,10 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
const docsDir = path.join(process.cwd(), "./.aigne/doc-smith", "docs");
|
|
5
5
|
|
|
6
|
-
export default async function readDocContent({
|
|
7
|
-
relevantDocPaths,
|
|
8
|
-
docsDir: customDocsDir,
|
|
9
|
-
}) {
|
|
6
|
+
export default async function readDocContent({ relevantDocPaths, docsDir: customDocsDir }) {
|
|
10
7
|
const targetDocsDir = customDocsDir || docsDir;
|
|
11
8
|
const docContents = [];
|
|
12
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
"author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@aigne/
|
|
16
|
-
"@aigne/
|
|
17
|
-
"@aigne/
|
|
18
|
-
"@aigne/
|
|
19
|
-
"@aigne/
|
|
15
|
+
"@aigne/aigne-hub": "^0.4.9",
|
|
16
|
+
"@aigne/anthropic": "^0.11.0",
|
|
17
|
+
"@aigne/cli": "^1.34.0",
|
|
18
|
+
"@aigne/core": "^1.49.0",
|
|
19
|
+
"@aigne/gemini": "^0.9.0",
|
|
20
|
+
"@aigne/openai": "^0.11.0",
|
|
20
21
|
"@aigne/publish-docs": "^0.5.4",
|
|
21
22
|
"chalk": "^5.5.0",
|
|
22
23
|
"dompurify": "^3.2.6",
|
|
@@ -34,6 +35,9 @@
|
|
|
34
35
|
"vfile": "^6.0.3",
|
|
35
36
|
"yaml": "^2.8.0"
|
|
36
37
|
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@biomejs/biome": "^2.1.4"
|
|
40
|
+
},
|
|
37
41
|
"scripts": {
|
|
38
42
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
39
43
|
"lint": "biome check && pnpm -r run lint",
|