@aigne/doc-smith 0.8.12-beta.3 → 0.8.12-beta.4
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/.aigne/doc-smith/config.yaml +9 -6
- package/.aigne/doc-smith/output/structure-plan.json +123 -109
- package/.aigne/doc-smith/upload-cache.yaml +48 -0
- package/.github/workflows/publish-docs.yml +4 -7
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +13 -0
- package/agents/clear/choose-contents.mjs +22 -5
- package/agents/clear/clear-auth-tokens.mjs +2 -4
- package/agents/clear/clear-deployment-config.mjs +49 -0
- package/agents/clear/clear-document-config.mjs +2 -5
- package/agents/clear/clear-document-structure.mjs +2 -6
- package/agents/clear/clear-generated-docs.mjs +0 -1
- package/agents/generate/check-need-generate-structure.mjs +15 -60
- package/agents/generate/document-structure-tools/generate-sub-structure.mjs +131 -0
- package/agents/generate/generate-structure-without-tools.yaml +65 -0
- package/agents/generate/generate-structure.yaml +7 -1
- package/agents/generate/index.yaml +0 -3
- package/agents/generate/update-document-structure.yaml +3 -0
- package/agents/generate/user-review-document-structure.mjs +7 -5
- package/agents/init/index.mjs +15 -15
- package/agents/publish/publish-docs.mjs +130 -111
- package/agents/translate/index.yaml +1 -1
- package/agents/update/batch-generate-document.yaml +1 -1
- package/agents/update/batch-update-document.yaml +1 -1
- package/agents/update/check-document.mjs +3 -19
- package/agents/update/user-review-document.mjs +4 -3
- package/agents/utils/load-sources.mjs +54 -151
- package/agents/utils/transform-detail-datasources.mjs +14 -18
- package/aigne.yaml +2 -0
- package/biome.json +1 -1
- package/docs/_sidebar.md +13 -15
- package/docs/configuration-initial-setup.ja.md +179 -0
- package/docs/configuration-initial-setup.md +179 -0
- package/docs/configuration-initial-setup.zh-TW.md +179 -0
- package/docs/configuration-initial-setup.zh.md +179 -0
- package/docs/configuration-managing-preferences.ja.md +100 -0
- package/docs/configuration-managing-preferences.md +100 -0
- package/docs/configuration-managing-preferences.zh-TW.md +100 -0
- package/docs/configuration-managing-preferences.zh.md +100 -0
- package/docs/configuration.ja.md +68 -184
- package/docs/configuration.md +62 -178
- package/docs/configuration.zh-TW.md +70 -186
- package/docs/configuration.zh.md +67 -183
- package/docs/getting-started.ja.md +46 -78
- package/docs/getting-started.md +46 -78
- package/docs/getting-started.zh-TW.md +47 -79
- package/docs/getting-started.zh.md +47 -79
- package/docs/guides-cleaning-up.ja.md +50 -0
- package/docs/guides-cleaning-up.md +50 -0
- package/docs/guides-cleaning-up.zh-TW.md +50 -0
- package/docs/guides-cleaning-up.zh.md +50 -0
- package/docs/guides-evaluating-documents.ja.md +66 -0
- package/docs/guides-evaluating-documents.md +66 -0
- package/docs/guides-evaluating-documents.zh-TW.md +66 -0
- package/docs/guides-evaluating-documents.zh.md +66 -0
- package/docs/guides-generating-documentation.ja.md +149 -0
- package/docs/guides-generating-documentation.md +149 -0
- package/docs/guides-generating-documentation.zh-TW.md +149 -0
- package/docs/guides-generating-documentation.zh.md +149 -0
- package/docs/guides-interactive-chat.ja.md +85 -0
- package/docs/guides-interactive-chat.md +85 -0
- package/docs/guides-interactive-chat.zh-TW.md +85 -0
- package/docs/guides-interactive-chat.zh.md +85 -0
- package/docs/guides-managing-history.ja.md +51 -0
- package/docs/guides-managing-history.md +51 -0
- package/docs/guides-managing-history.zh-TW.md +51 -0
- package/docs/guides-managing-history.zh.md +51 -0
- package/docs/guides-publishing-your-docs.ja.md +78 -0
- package/docs/guides-publishing-your-docs.md +78 -0
- package/docs/guides-publishing-your-docs.zh-TW.md +78 -0
- package/docs/guides-publishing-your-docs.zh.md +78 -0
- package/docs/guides-translating-documentation.ja.md +95 -0
- package/docs/guides-translating-documentation.md +95 -0
- package/docs/guides-translating-documentation.zh-TW.md +95 -0
- package/docs/guides-translating-documentation.zh.md +95 -0
- package/docs/guides-updating-documentation.ja.md +77 -0
- package/docs/guides-updating-documentation.md +77 -0
- package/docs/guides-updating-documentation.zh-TW.md +77 -0
- package/docs/guides-updating-documentation.zh.md +77 -0
- package/docs/guides.ja.md +32 -0
- package/docs/guides.md +32 -0
- package/docs/guides.zh-TW.md +32 -0
- package/docs/guides.zh.md +32 -0
- package/docs/overview.ja.md +39 -60
- package/docs/overview.md +39 -60
- package/docs/overview.zh-TW.md +39 -60
- package/docs/overview.zh.md +39 -60
- package/docs/release-notes.ja.md +255 -0
- package/docs/release-notes.md +255 -0
- package/docs/release-notes.zh-TW.md +255 -0
- package/docs/release-notes.zh.md +255 -0
- package/package.json +4 -2
- package/prompts/common/document/content-rules-core.md +1 -0
- package/prompts/common/document-structure/document-structure-rules.md +8 -9
- package/prompts/common/document-structure/output-constraints.md +1 -1
- package/prompts/structure/document-rules.md +8 -2
- package/prompts/structure/generate/system-prompt.md +27 -2
- package/prompts/structure/generate/user-prompt.md +18 -0
- package/prompts/structure/update/system-prompt.md +12 -0
- package/prompts/structure/update/user-prompt.md +3 -0
- package/tests/agents/clear/choose-contents.test.mjs +8 -4
- package/tests/agents/generate/check-need-generate-structure.test.mjs +53 -63
- package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +277 -0
- package/tests/agents/init/init.test.mjs +18 -18
- package/tests/agents/publish/publish-docs.test.mjs +79 -0
- package/tests/agents/update/check-document.test.mjs +7 -67
- package/tests/agents/utils/load-sources.test.mjs +90 -90
- package/tests/agents/utils/transform-detail-datasources.test.mjs +153 -196
- package/tests/utils/file-utils.test.mjs +309 -1
- package/utils/auth-utils.mjs +9 -3
- package/utils/constants/index.mjs +3 -1
- package/utils/file-utils.mjs +315 -0
- package/utils/utils.mjs +89 -50
- package/docs/advanced-how-it-works.ja.md +0 -101
- package/docs/advanced-how-it-works.md +0 -101
- package/docs/advanced-how-it-works.zh-TW.md +0 -101
- package/docs/advanced-how-it-works.zh.md +0 -101
- package/docs/advanced-quality-assurance.ja.md +0 -92
- package/docs/advanced-quality-assurance.md +0 -92
- package/docs/advanced-quality-assurance.zh-TW.md +0 -92
- package/docs/advanced-quality-assurance.zh.md +0 -92
- package/docs/advanced.ja.md +0 -20
- package/docs/advanced.md +0 -20
- package/docs/advanced.zh-TW.md +0 -20
- package/docs/advanced.zh.md +0 -20
- package/docs/changelog.ja.md +0 -486
- package/docs/changelog.md +0 -486
- package/docs/changelog.zh-TW.md +0 -486
- package/docs/changelog.zh.md +0 -486
- package/docs/cli-reference.ja.md +0 -311
- package/docs/cli-reference.md +0 -311
- package/docs/cli-reference.zh-TW.md +0 -311
- package/docs/cli-reference.zh.md +0 -311
- package/docs/configuration-interactive-setup.ja.md +0 -138
- package/docs/configuration-interactive-setup.md +0 -138
- package/docs/configuration-interactive-setup.zh-TW.md +0 -138
- package/docs/configuration-interactive-setup.zh.md +0 -138
- package/docs/configuration-language-support.ja.md +0 -64
- package/docs/configuration-language-support.md +0 -64
- package/docs/configuration-language-support.zh-TW.md +0 -64
- package/docs/configuration-language-support.zh.md +0 -64
- package/docs/configuration-llm-setup.ja.md +0 -56
- package/docs/configuration-llm-setup.md +0 -56
- package/docs/configuration-llm-setup.zh-TW.md +0 -56
- package/docs/configuration-llm-setup.zh.md +0 -56
- package/docs/configuration-preferences.ja.md +0 -144
- package/docs/configuration-preferences.md +0 -144
- package/docs/configuration-preferences.zh-TW.md +0 -144
- package/docs/configuration-preferences.zh.md +0 -144
- package/docs/features-generate-documentation.ja.md +0 -95
- package/docs/features-generate-documentation.md +0 -95
- package/docs/features-generate-documentation.zh-TW.md +0 -95
- package/docs/features-generate-documentation.zh.md +0 -95
- package/docs/features-publish-your-docs.ja.md +0 -130
- package/docs/features-publish-your-docs.md +0 -130
- package/docs/features-publish-your-docs.zh-TW.md +0 -130
- package/docs/features-publish-your-docs.zh.md +0 -130
- package/docs/features-translate-documentation.ja.md +0 -90
- package/docs/features-translate-documentation.md +0 -90
- package/docs/features-translate-documentation.zh-TW.md +0 -90
- package/docs/features-translate-documentation.zh.md +0 -90
- package/docs/features-update-and-refine.ja.md +0 -142
- package/docs/features-update-and-refine.md +0 -142
- package/docs/features-update-and-refine.zh-TW.md +0 -143
- package/docs/features-update-and-refine.zh.md +0 -142
- package/docs/features.ja.md +0 -62
- package/docs/features.md +0 -62
- package/docs/features.zh-TW.md +0 -62
- package/docs/features.zh.md +0 -62
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { basename, join } from "node:path";
|
|
2
2
|
|
|
3
3
|
import { publishDocs as publishDocsFn } from "@aigne/publish-docs";
|
|
4
|
+
import { BrokerClient } from "@blocklet/payment-broker-client/node";
|
|
4
5
|
import chalk from "chalk";
|
|
5
6
|
import fs from "fs-extra";
|
|
6
7
|
|
|
7
|
-
import { getAccessToken } from "../../utils/auth-utils.mjs";
|
|
8
|
+
import { getAccessToken, getOfficialAccessToken } from "../../utils/auth-utils.mjs";
|
|
8
9
|
import {
|
|
9
10
|
CLOUD_SERVICE_URL_PROD,
|
|
10
11
|
DISCUSS_KIT_STORE_URL,
|
|
@@ -16,96 +17,112 @@ import { beforePublishHook, ensureTmpDir } from "../../utils/d2-utils.mjs";
|
|
|
16
17
|
import { deploy } from "../../utils/deploy.mjs";
|
|
17
18
|
import { getGithubRepoUrl, loadConfigFromFile, saveValueToConfig } from "../../utils/utils.mjs";
|
|
18
19
|
|
|
20
|
+
const BASE_URL = process.env.DOC_SMITH_BASE_URL || CLOUD_SERVICE_URL_PROD;
|
|
21
|
+
|
|
19
22
|
export default async function publishDocs(
|
|
20
23
|
{ docsDir: rawDocsDir, appUrl, boardId, projectName, projectDesc, projectLogo },
|
|
21
24
|
options,
|
|
22
25
|
) {
|
|
23
|
-
|
|
24
|
-
await ensureTmpDir();
|
|
25
|
-
|
|
26
|
-
const docsDir = join(DOC_SMITH_DIR, TMP_DIR, TMP_DOCS_DIR);
|
|
27
|
-
await fs.rm(docsDir, { recursive: true, force: true });
|
|
28
|
-
await fs.mkdir(docsDir, {
|
|
29
|
-
recursive: true,
|
|
30
|
-
});
|
|
31
|
-
await fs.cp(rawDocsDir, docsDir, { recursive: true });
|
|
32
|
-
|
|
33
|
-
// ----------------- trigger beforePublishHook -----------------------------
|
|
34
|
-
await beforePublishHook({ docsDir });
|
|
35
|
-
|
|
36
|
-
// ----------------- main publish process flow -----------------------------
|
|
37
|
-
// Check if DOC_DISCUSS_KIT_URL is set in environment variables
|
|
38
|
-
const envAppUrl = process.env.DOC_DISCUSS_KIT_URL;
|
|
39
|
-
const useEnvAppUrl = !!envAppUrl;
|
|
40
|
-
|
|
41
|
-
// Use environment variable if available, otherwise use the provided appUrl
|
|
42
|
-
if (useEnvAppUrl) {
|
|
43
|
-
appUrl = envAppUrl;
|
|
44
|
-
}
|
|
26
|
+
let message;
|
|
45
27
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const hasCachedCheckoutId = !!config?.checkoutId;
|
|
55
|
-
const choice = await options.prompts.select({
|
|
56
|
-
message: "Select platform to publish your documents:",
|
|
57
|
-
choices: [
|
|
58
|
-
{
|
|
59
|
-
name: `${chalk.blue("DocSmith Cloud (docsmith.aigne.io)")} – ${chalk.green("Free")} hosting. Your documents will be publicly accessible. Best for open-source projects or community sharing.`,
|
|
60
|
-
value: "default",
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: `${chalk.blue("Your existing website")} - Integrate and publish directly on your current site (setup required)`,
|
|
64
|
-
value: "custom",
|
|
65
|
-
},
|
|
66
|
-
...(hasCachedCheckoutId
|
|
67
|
-
? [
|
|
68
|
-
{
|
|
69
|
-
name: `${chalk.yellow("Resume previous website setup")} - ${chalk.green("Already paid.")} Continue where you left off. Your payment has already been processed.`,
|
|
70
|
-
value: "new-instance-continue",
|
|
71
|
-
},
|
|
72
|
-
]
|
|
73
|
-
: []),
|
|
74
|
-
{
|
|
75
|
-
name: `${chalk.blue("New website")} - ${chalk.yellow("Paid service.")} We'll help you set up a brand-new website with custom domain and hosting. Great if you want a professional presence.`,
|
|
76
|
-
value: "new-instance",
|
|
77
|
-
},
|
|
78
|
-
],
|
|
28
|
+
try {
|
|
29
|
+
// move work dir to tmp-dir
|
|
30
|
+
await ensureTmpDir();
|
|
31
|
+
|
|
32
|
+
const docsDir = join(DOC_SMITH_DIR, TMP_DIR, TMP_DOCS_DIR);
|
|
33
|
+
await fs.rm(docsDir, { recursive: true, force: true });
|
|
34
|
+
await fs.mkdir(docsDir, {
|
|
35
|
+
recursive: true,
|
|
79
36
|
});
|
|
37
|
+
await fs.cp(rawDocsDir, docsDir, { recursive: true });
|
|
38
|
+
|
|
39
|
+
// ----------------- trigger beforePublishHook -----------------------------
|
|
40
|
+
await beforePublishHook({ docsDir });
|
|
41
|
+
|
|
42
|
+
// ----------------- main publish process flow -----------------------------
|
|
43
|
+
// Check if DOC_DISCUSS_KIT_URL is set in environment variables
|
|
44
|
+
const envAppUrl = process.env.DOC_DISCUSS_KIT_URL;
|
|
45
|
+
const useEnvAppUrl = !!envAppUrl;
|
|
46
|
+
|
|
47
|
+
// Use environment variable if available, otherwise use the provided appUrl
|
|
48
|
+
if (useEnvAppUrl) {
|
|
49
|
+
appUrl = envAppUrl;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check if appUrl is default and not saved in config (only when not using env variable)
|
|
53
|
+
const config = await loadConfigFromFile();
|
|
54
|
+
const isDefaultAppUrl = appUrl === CLOUD_SERVICE_URL_PROD;
|
|
55
|
+
const hasAppUrlInConfig = config?.appUrl;
|
|
56
|
+
|
|
57
|
+
let token = "";
|
|
58
|
+
|
|
59
|
+
if (!useEnvAppUrl && isDefaultAppUrl && !hasAppUrlInConfig) {
|
|
60
|
+
const authToken = await getOfficialAccessToken(BASE_URL);
|
|
61
|
+
|
|
62
|
+
if (!authToken) {
|
|
63
|
+
throw new Error("Failed to get official access token");
|
|
64
|
+
}
|
|
80
65
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
66
|
+
const client = new BrokerClient({ baseUrl: BASE_URL, authToken });
|
|
67
|
+
|
|
68
|
+
const { sessionId, paymentLink } = await client.checkCacheSession({
|
|
69
|
+
needShortUrl: true,
|
|
70
|
+
sessionId: config?.checkoutId,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const choice = await options.prompts.select({
|
|
74
|
+
message: "Select platform to publish your documents:",
|
|
75
|
+
choices: [
|
|
76
|
+
{
|
|
77
|
+
name: `${chalk.blue("DocSmith Cloud (docsmith.aigne.io)")} – ${chalk.green("Free")} hosting. Your documents will be publicly accessible. Best for open-source projects or community sharing.`,
|
|
78
|
+
value: "default",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: `${chalk.blue("Your existing website")} - Integrate and publish directly on your current site (setup required)`,
|
|
82
|
+
value: "custom",
|
|
83
|
+
},
|
|
84
|
+
...(sessionId
|
|
85
|
+
? [
|
|
86
|
+
{
|
|
87
|
+
name: `${chalk.yellow("Resume previous website setup")} - ${chalk.green("Already paid.")} Continue where you left off. Your payment has already been processed.`,
|
|
88
|
+
value: "new-instance-continue",
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
: []),
|
|
92
|
+
{
|
|
93
|
+
name: `${chalk.blue("New website")} - ${chalk.yellow("Paid service.")} We'll help you set up a brand-new website with custom domain and hosting. Great if you want a professional presence.`,
|
|
94
|
+
value: "new-instance",
|
|
95
|
+
},
|
|
96
|
+
],
|
|
98
97
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
|
|
99
|
+
if (choice === "custom") {
|
|
100
|
+
console.log(
|
|
101
|
+
`${chalk.bold("\n💡 Tips")}\n\n` +
|
|
102
|
+
`Start here to run your own website:\n${chalk.cyan(DISCUSS_KIT_STORE_URL)}\n`,
|
|
103
|
+
);
|
|
104
|
+
const userInput = await options.prompts.input({
|
|
105
|
+
message: "Please enter your website URL:",
|
|
106
|
+
validate: (input) => {
|
|
107
|
+
try {
|
|
108
|
+
// Check if input contains protocol, if not, prepend https://
|
|
109
|
+
const urlWithProtocol = input.includes("://") ? input : `https://${input}`;
|
|
110
|
+
new URL(urlWithProtocol);
|
|
111
|
+
return true;
|
|
112
|
+
} catch {
|
|
113
|
+
return "Please enter a valid URL";
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
// Ensure appUrl has protocol
|
|
118
|
+
appUrl = userInput.includes("://") ? userInput : `https://${userInput}`;
|
|
119
|
+
} else if (["new-instance", "new-instance-continue"].includes(choice)) {
|
|
120
|
+
// Deploy a new Discuss Kit service
|
|
104
121
|
let id = "";
|
|
105
122
|
let paymentUrl = "";
|
|
106
123
|
if (choice === "new-instance-continue") {
|
|
107
|
-
id =
|
|
108
|
-
paymentUrl =
|
|
124
|
+
id = sessionId;
|
|
125
|
+
paymentUrl = paymentLink;
|
|
109
126
|
console.log(`\nResuming your previous website setup...`);
|
|
110
127
|
} else {
|
|
111
128
|
console.log(`\nCreating new website for your documentation...`);
|
|
@@ -114,42 +131,35 @@ export default async function publishDocs(
|
|
|
114
131
|
|
|
115
132
|
appUrl = homeUrl;
|
|
116
133
|
token = ltToken;
|
|
117
|
-
} catch (error) {
|
|
118
|
-
const errorMsg = error?.message || "Unknown error occurred";
|
|
119
|
-
return { message: `${chalk.red("❌ Failed to publish to website:")} ${errorMsg}` };
|
|
120
134
|
}
|
|
121
135
|
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
console.log(`\nPublishing docs to ${chalk.cyan(appUrl)}\n`);
|
|
125
136
|
|
|
126
|
-
|
|
137
|
+
console.log(`\nPublishing docs to ${chalk.cyan(appUrl)}\n`);
|
|
127
138
|
|
|
128
|
-
|
|
139
|
+
const accessToken = await getAccessToken(appUrl, token);
|
|
129
140
|
|
|
130
|
-
|
|
141
|
+
process.env.DOC_ROOT_DIR = docsDir;
|
|
131
142
|
|
|
132
|
-
|
|
133
|
-
const projectInfo = {
|
|
134
|
-
name: projectName || config?.projectName || basename(process.cwd()),
|
|
135
|
-
description: projectDesc || config?.projectDesc || "",
|
|
136
|
-
icon: projectLogo || config?.projectLogo || "",
|
|
137
|
-
};
|
|
143
|
+
const sidebarPath = join(docsDir, "_sidebar.md");
|
|
138
144
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
...(config?.locale ? [config.locale] : []),
|
|
146
|
-
...(config?.translateLanguages || []),
|
|
147
|
-
].filter((lang, index, arr) => arr.indexOf(lang) === index), // Remove duplicates
|
|
148
|
-
};
|
|
145
|
+
// Get project info from config
|
|
146
|
+
const projectInfo = {
|
|
147
|
+
name: projectName || config?.projectName || basename(process.cwd()),
|
|
148
|
+
description: projectDesc || config?.projectDesc || "",
|
|
149
|
+
icon: projectLogo || config?.projectLogo || "",
|
|
150
|
+
};
|
|
149
151
|
|
|
150
|
-
|
|
152
|
+
// Construct boardMeta object
|
|
153
|
+
const boardMeta = {
|
|
154
|
+
category: config?.documentPurpose || [],
|
|
155
|
+
githubRepoUrl: getGithubRepoUrl(),
|
|
156
|
+
commitSha: config?.lastGitHead || "",
|
|
157
|
+
languages: [
|
|
158
|
+
...(config?.locale ? [config.locale] : []),
|
|
159
|
+
...(config?.translateLanguages || []),
|
|
160
|
+
].filter((lang, index, arr) => arr.indexOf(lang) === index), // Remove duplicates
|
|
161
|
+
};
|
|
151
162
|
|
|
152
|
-
try {
|
|
153
163
|
const {
|
|
154
164
|
success,
|
|
155
165
|
boardId: newBoardId,
|
|
@@ -184,16 +194,25 @@ export default async function publishDocs(
|
|
|
184
194
|
} else {
|
|
185
195
|
// If the error is 401 or 403, it means the access token is invalid
|
|
186
196
|
if (error?.includes("401") || error?.includes("403")) {
|
|
187
|
-
message = `❌ Publishing failed: you don
|
|
197
|
+
message = `❌ Publishing failed: you don't have valid authorization.\n Run ${chalk.cyan("aigne doc clear")} to reset it, then publish again.`;
|
|
188
198
|
}
|
|
189
199
|
}
|
|
200
|
+
|
|
201
|
+
// clean up tmp work dir
|
|
202
|
+
await fs.rm(docsDir, { recursive: true, force: true });
|
|
190
203
|
} catch (error) {
|
|
191
204
|
message = `❌ Failed to publish docs: ${error.message}`;
|
|
205
|
+
|
|
206
|
+
// clean up tmp work dir in case of error
|
|
207
|
+
try {
|
|
208
|
+
const docsDir = join(DOC_SMITH_DIR, TMP_DIR, TMP_DOCS_DIR);
|
|
209
|
+
await fs.rm(docsDir, { recursive: true, force: true });
|
|
210
|
+
} catch {
|
|
211
|
+
// ignore cleanup errors
|
|
212
|
+
}
|
|
192
213
|
}
|
|
193
|
-
await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment service");
|
|
194
214
|
|
|
195
|
-
|
|
196
|
-
await fs.rm(docsDir, { recursive: true, force: true });
|
|
215
|
+
await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment service");
|
|
197
216
|
return message ? { message } : {};
|
|
198
217
|
}
|
|
199
218
|
|
|
@@ -2,7 +2,6 @@ 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 { hasSourceFilesChanged } from "../../utils/utils.mjs";
|
|
6
5
|
import checkDetailResult from "../utils/check-detail-result.mjs";
|
|
7
6
|
|
|
8
7
|
// Get current script directory
|
|
@@ -17,13 +16,14 @@ export default async function checkDocument(
|
|
|
17
16
|
documentStructure,
|
|
18
17
|
modifiedFiles,
|
|
19
18
|
forceRegenerate,
|
|
19
|
+
locale,
|
|
20
20
|
...rest
|
|
21
21
|
},
|
|
22
22
|
options,
|
|
23
23
|
) {
|
|
24
24
|
// Check if the detail file already exists
|
|
25
25
|
const flatName = path.replace(/^\//, "").replace(/\//g, "-");
|
|
26
|
-
const fileFullName = `${flatName}.md`;
|
|
26
|
+
const fileFullName = locale === "en" ? `${flatName}.md` : `${flatName}.${locale}.md`;
|
|
27
27
|
const filePath = join(docsDir, fileFullName);
|
|
28
28
|
let detailGenerated = true;
|
|
29
29
|
let fileContent = null;
|
|
@@ -69,16 +69,6 @@ export default async function checkDocument(
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Check if source files have changed since last generation
|
|
73
|
-
let sourceFilesChanged = false;
|
|
74
|
-
if (sourceIds && sourceIds.length > 0 && modifiedFiles) {
|
|
75
|
-
sourceFilesChanged = hasSourceFilesChanged(sourceIds, modifiedFiles);
|
|
76
|
-
|
|
77
|
-
if (sourceFilesChanged) {
|
|
78
|
-
console.log(`Source files changed for ${path}, will regenerate`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
72
|
// If file exists, check content validation
|
|
83
73
|
let contentValidationFailed = false;
|
|
84
74
|
let validationResult = {};
|
|
@@ -95,13 +85,7 @@ export default async function checkDocument(
|
|
|
95
85
|
}
|
|
96
86
|
|
|
97
87
|
// If file exists, sourceIds haven't changed, source files haven't changed, and content validation passes, no need to regenerate
|
|
98
|
-
if (
|
|
99
|
-
detailGenerated &&
|
|
100
|
-
!sourceIdsChanged &&
|
|
101
|
-
!sourceFilesChanged &&
|
|
102
|
-
!contentValidationFailed &&
|
|
103
|
-
!forceRegenerate
|
|
104
|
-
) {
|
|
88
|
+
if (detailGenerated && !sourceIdsChanged && !contentValidationFailed && !forceRegenerate) {
|
|
105
89
|
return {
|
|
106
90
|
path,
|
|
107
91
|
docsDir,
|
|
@@ -175,9 +175,10 @@ export default async function userReviewDocument(
|
|
|
175
175
|
const feedback = await options.prompts.input({
|
|
176
176
|
message:
|
|
177
177
|
"How would you like to improve this document?\n" +
|
|
178
|
-
"
|
|
179
|
-
" •
|
|
180
|
-
" •
|
|
178
|
+
"Examples:\n" +
|
|
179
|
+
" • Add troubleshooting section for common errors\n" +
|
|
180
|
+
" • Simplify the explanation for beginners\n" +
|
|
181
|
+
" • Remove the outdated information about version 1.0\n\n" +
|
|
181
182
|
" Your feedback:",
|
|
182
183
|
});
|
|
183
184
|
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { readFile
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
buildSourcesContent,
|
|
5
|
+
calculateFileStats,
|
|
6
|
+
loadFilesFromPaths,
|
|
7
|
+
readFileContents,
|
|
8
|
+
} from "../../utils/file-utils.mjs";
|
|
8
9
|
import {
|
|
9
10
|
getCurrentGitHead,
|
|
10
11
|
getModifiedFilesBetweenCommits,
|
|
11
|
-
|
|
12
|
+
toRelativePath,
|
|
12
13
|
} from "../../utils/utils.mjs";
|
|
14
|
+
import {
|
|
15
|
+
INTELLIGENT_SUGGESTION_TOKEN_THRESHOLD,
|
|
16
|
+
DEFAULT_EXCLUDE_PATTERNS,
|
|
17
|
+
DEFAULT_INCLUDE_PATTERNS,
|
|
18
|
+
} from "../../utils/constants/index.mjs";
|
|
13
19
|
|
|
14
20
|
export default async function loadSources({
|
|
15
21
|
sources = [],
|
|
@@ -27,103 +33,22 @@ export default async function loadSources({
|
|
|
27
33
|
let files = Array.isArray(sources) ? [...sources] : [];
|
|
28
34
|
|
|
29
35
|
if (sourcesPath) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// First try to access as a file or directory
|
|
41
|
-
const stats = await stat(dir);
|
|
42
|
-
|
|
43
|
-
if (stats.isFile()) {
|
|
44
|
-
// If it's a file, add it directly without filtering
|
|
45
|
-
allFiles.push(dir);
|
|
46
|
-
} else if (stats.isDirectory()) {
|
|
47
|
-
// If it's a directory, use the existing glob logic
|
|
48
|
-
// Load .gitignore for this directory
|
|
49
|
-
const gitignorePatterns = await loadGitignore(dir);
|
|
50
|
-
|
|
51
|
-
// Prepare patterns
|
|
52
|
-
let finalIncludePatterns = null;
|
|
53
|
-
let finalExcludePatterns = null;
|
|
54
|
-
|
|
55
|
-
if (useDefaultPatterns) {
|
|
56
|
-
// Merge with default patterns
|
|
57
|
-
const userInclude = includePatterns
|
|
58
|
-
? Array.isArray(includePatterns)
|
|
59
|
-
? includePatterns
|
|
60
|
-
: [includePatterns]
|
|
61
|
-
: [];
|
|
62
|
-
const userExclude = excludePatterns
|
|
63
|
-
? Array.isArray(excludePatterns)
|
|
64
|
-
? excludePatterns
|
|
65
|
-
: [excludePatterns]
|
|
66
|
-
: [];
|
|
67
|
-
|
|
68
|
-
finalIncludePatterns = [...DEFAULT_INCLUDE_PATTERNS, ...userInclude];
|
|
69
|
-
finalExcludePatterns = [...DEFAULT_EXCLUDE_PATTERNS, ...userExclude];
|
|
70
|
-
} else {
|
|
71
|
-
// Use only user patterns
|
|
72
|
-
if (includePatterns) {
|
|
73
|
-
finalIncludePatterns = Array.isArray(includePatterns)
|
|
74
|
-
? includePatterns
|
|
75
|
-
: [includePatterns];
|
|
76
|
-
}
|
|
77
|
-
if (excludePatterns) {
|
|
78
|
-
finalExcludePatterns = Array.isArray(excludePatterns)
|
|
79
|
-
? excludePatterns
|
|
80
|
-
: [excludePatterns];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Get files using glob
|
|
85
|
-
const filesInDir = await getFilesWithGlob(
|
|
86
|
-
dir,
|
|
87
|
-
finalIncludePatterns,
|
|
88
|
-
finalExcludePatterns,
|
|
89
|
-
gitignorePatterns,
|
|
90
|
-
);
|
|
91
|
-
allFiles = allFiles.concat(filesInDir);
|
|
92
|
-
}
|
|
93
|
-
} catch (err) {
|
|
94
|
-
if (err.code === "ENOENT") {
|
|
95
|
-
// Path doesn't exist as file or directory, try as glob pattern
|
|
96
|
-
try {
|
|
97
|
-
// Check if it looks like a glob pattern
|
|
98
|
-
const isGlobPatternResult = isGlobPattern(dir);
|
|
99
|
-
|
|
100
|
-
if (isGlobPatternResult) {
|
|
101
|
-
// Use glob to find matching files from current working directory
|
|
102
|
-
const { glob } = await import("glob");
|
|
103
|
-
const matchedFiles = await glob(dir, {
|
|
104
|
-
absolute: true,
|
|
105
|
-
nodir: true, // Only files, not directories
|
|
106
|
-
dot: false, // Don't include hidden files
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if (matchedFiles.length > 0) {
|
|
110
|
-
allFiles = allFiles.concat(matchedFiles);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
} catch (globErr) {
|
|
114
|
-
console.warn(`Failed to process glob pattern "${dir}": ${globErr.message}`);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
throw err;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
36
|
+
const allFiles = await loadFilesFromPaths(sourcesPath, {
|
|
37
|
+
includePatterns,
|
|
38
|
+
excludePatterns,
|
|
39
|
+
useDefaultPatterns,
|
|
40
|
+
defaultIncludePatterns: DEFAULT_INCLUDE_PATTERNS,
|
|
41
|
+
defaultExcludePatterns: DEFAULT_EXCLUDE_PATTERNS,
|
|
42
|
+
});
|
|
121
43
|
|
|
122
44
|
files = files.concat(allFiles);
|
|
123
45
|
}
|
|
124
46
|
|
|
125
47
|
files = [...new Set(files)];
|
|
126
48
|
|
|
49
|
+
// all files path
|
|
50
|
+
const allFilesPaths = files.map((file) => `- ${toRelativePath(file)}`).join("\n");
|
|
51
|
+
|
|
127
52
|
// Define media file extensions
|
|
128
53
|
const mediaExtensions = [
|
|
129
54
|
".jpg",
|
|
@@ -142,38 +67,40 @@ export default async function loadSources({
|
|
|
142
67
|
];
|
|
143
68
|
|
|
144
69
|
// Separate source files from media files
|
|
145
|
-
const
|
|
70
|
+
const sourceFilesPaths = [];
|
|
146
71
|
const mediaFiles = [];
|
|
147
|
-
let allSources = "";
|
|
148
72
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
const ext = path.extname(file).toLowerCase();
|
|
75
|
+
|
|
76
|
+
if (mediaExtensions.includes(ext)) {
|
|
77
|
+
// This is a media file
|
|
78
|
+
const relativePath = path.relative(docsDir, file);
|
|
79
|
+
const fileName = path.basename(file);
|
|
80
|
+
const description = path.parse(fileName).name;
|
|
81
|
+
|
|
82
|
+
mediaFiles.push({
|
|
83
|
+
name: fileName,
|
|
84
|
+
path: relativePath,
|
|
85
|
+
description,
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
// This is a source file
|
|
89
|
+
sourceFilesPaths.push(file);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Read all source files using the utility function
|
|
94
|
+
const sourceFiles = await readFileContents(sourceFilesPaths, process.cwd());
|
|
152
95
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const relativePath = path.relative(docsDir, file);
|
|
156
|
-
const fileName = path.basename(file);
|
|
157
|
-
const description = path.parse(fileName).name;
|
|
96
|
+
// Count tokens and lines using utility function
|
|
97
|
+
const { totalTokens, totalLines } = calculateFileStats(sourceFiles);
|
|
158
98
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
path: relativePath,
|
|
162
|
-
description,
|
|
163
|
-
});
|
|
164
|
-
} else {
|
|
165
|
-
// This is a source file
|
|
166
|
-
const content = await readFile(file, "utf8");
|
|
167
|
-
const relativePath = path.relative(process.cwd(), file);
|
|
168
|
-
allSources += `// sourceId: ${relativePath}\n${content}\n`;
|
|
99
|
+
// check if totalTokens is too large
|
|
100
|
+
const isLargeContext = totalTokens > INTELLIGENT_SUGGESTION_TOKEN_THRESHOLD;
|
|
169
101
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
content,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}),
|
|
176
|
-
);
|
|
102
|
+
// Build allSources string using utility function
|
|
103
|
+
const allSources = buildSourcesContent(sourceFiles, isLargeContext);
|
|
177
104
|
|
|
178
105
|
// Get the last documentation structure
|
|
179
106
|
let originalDocumentStructure;
|
|
@@ -283,31 +210,17 @@ export default async function loadSources({
|
|
|
283
210
|
assetsContent += "```\n";
|
|
284
211
|
}
|
|
285
212
|
|
|
286
|
-
// Count words and lines in allSources
|
|
287
|
-
let totalWords = 0;
|
|
288
|
-
let totalLines = 0;
|
|
289
|
-
|
|
290
|
-
for (const source of Object.values(allSources)) {
|
|
291
|
-
if (typeof source === "string") {
|
|
292
|
-
// Count English words (simple regex for words containing a-zA-Z)
|
|
293
|
-
const words = source.match(/[a-zA-Z]+/g) || [];
|
|
294
|
-
totalWords += words.length;
|
|
295
|
-
|
|
296
|
-
// Count lines (excluding empty lines)
|
|
297
|
-
totalLines += source.split("\n").filter((line) => line.trim() !== "").length;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
213
|
return {
|
|
302
|
-
datasourcesList: sourceFiles,
|
|
303
214
|
datasources: allSources,
|
|
304
215
|
content,
|
|
305
216
|
originalDocumentStructure,
|
|
306
217
|
files,
|
|
307
218
|
modifiedFiles,
|
|
308
|
-
|
|
219
|
+
totalTokens,
|
|
309
220
|
totalLines,
|
|
310
221
|
assetsContent,
|
|
222
|
+
isLargeContext,
|
|
223
|
+
allFilesPaths,
|
|
311
224
|
};
|
|
312
225
|
}
|
|
313
226
|
|
|
@@ -357,16 +270,6 @@ loadSources.output_schema = {
|
|
|
357
270
|
datasources: {
|
|
358
271
|
type: "string",
|
|
359
272
|
},
|
|
360
|
-
datasourcesList: {
|
|
361
|
-
type: "array",
|
|
362
|
-
items: {
|
|
363
|
-
type: "object",
|
|
364
|
-
properties: {
|
|
365
|
-
sourceId: { type: "string" },
|
|
366
|
-
content: { type: "string" },
|
|
367
|
-
},
|
|
368
|
-
},
|
|
369
|
-
},
|
|
370
273
|
files: {
|
|
371
274
|
type: "array",
|
|
372
275
|
items: { type: "string" },
|