@aigne/doc-smith 0.8.11-beta.4 → 0.8.11-beta.6
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 +2 -4
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +17 -2
- package/README.md +1 -1
- package/agents/clear/choose-contents.mjs +2 -2
- package/agents/clear/clear-document-structure.mjs +8 -8
- package/agents/clear/index.yaml +1 -1
- package/agents/evaluate/document-structure.yaml +1 -1
- package/agents/generate/check-d2-diagram-valid.mjs +26 -0
- package/agents/generate/check-document-structure.yaml +3 -3
- package/agents/generate/check-need-generate-structure.mjs +8 -8
- package/agents/generate/document-structure-tools/add-document.mjs +3 -3
- package/agents/generate/document-structure-tools/delete-document.mjs +2 -2
- package/agents/generate/document-structure-tools/move-document.mjs +3 -2
- package/agents/generate/document-structure-tools/update-document.mjs +2 -2
- package/agents/generate/generate-d2-diagram.yaml +23 -0
- package/agents/generate/generate-structure.yaml +1 -1
- package/agents/generate/merge-d2-diagram.yaml +39 -0
- package/agents/generate/update-document-structure.yaml +3 -3
- package/agents/generate/user-review-document-structure.mjs +10 -10
- package/agents/init/index.mjs +18 -10
- package/agents/publish/publish-docs.mjs +17 -20
- package/agents/update/batch-generate-document.yaml +1 -1
- package/agents/update/check-document.mjs +2 -2
- package/agents/update/generate-document.yaml +25 -0
- package/agents/utils/check-feedback-refiner.mjs +1 -1
- package/agents/utils/choose-docs.mjs +1 -1
- package/agents/utils/load-document-all-content.mjs +3 -3
- package/agents/utils/load-sources.mjs +1 -1
- package/agents/utils/save-docs.mjs +7 -28
- package/aigne.yaml +2 -2
- package/docs/_sidebar.md +1 -1
- package/docs/advanced-how-it-works.md +3 -3
- package/docs/advanced-quality-assurance.md +1 -1
- package/docs/cli-reference.ja.md +151 -80
- package/docs/cli-reference.md +126 -55
- package/docs/cli-reference.zh-TW.md +133 -62
- package/docs/cli-reference.zh.md +143 -72
- package/docs/configuration-interactive-setup.md +1 -1
- package/docs/configuration-language-support.md +1 -1
- package/docs/configuration-preferences.md +1 -1
- package/docs/configuration.ja.md +104 -48
- package/docs/configuration.md +58 -2
- package/docs/configuration.zh-TW.md +99 -42
- package/docs/configuration.zh.md +78 -21
- package/docs/features-generate-documentation.ja.md +63 -44
- package/docs/features-generate-documentation.md +54 -35
- package/docs/features-generate-documentation.zh-TW.md +67 -48
- package/docs/features-generate-documentation.zh.md +61 -41
- package/docs/features-publish-your-docs.ja.md +69 -46
- package/docs/features-publish-your-docs.md +65 -42
- package/docs/features-publish-your-docs.zh-TW.md +73 -50
- package/docs/features-publish-your-docs.zh.md +67 -44
- package/docs/features-translate-documentation.ja.md +35 -33
- package/docs/features-translate-documentation.md +24 -22
- package/docs/features-translate-documentation.zh-TW.md +32 -30
- package/docs/features-translate-documentation.zh.md +29 -27
- package/docs/features-update-and-refine.ja.md +120 -66
- package/docs/features-update-and-refine.md +110 -56
- package/docs/features-update-and-refine.zh-TW.md +116 -62
- package/docs/features-update-and-refine.zh.md +118 -64
- package/docs/getting-started.ja.md +22 -22
- package/docs/getting-started.md +1 -1
- package/docs/getting-started.zh-TW.md +16 -16
- package/docs/getting-started.zh.md +28 -28
- package/docs/overview.md +3 -3
- package/docs-mcp/analyze-docs-relevance.yaml +6 -6
- package/docs-mcp/docs-search.yaml +1 -1
- package/package.json +3 -3
- package/prompts/common/document-structure/conflict-resolution-guidance.md +3 -3
- package/prompts/common/document-structure/document-structure-rules.md +2 -2
- package/prompts/detail/{d2-chart/rules.md → d2-diagram/rules-system.md} +41 -5
- package/prompts/detail/d2-diagram/rules-user.md +4 -0
- package/prompts/detail/document-rules.md +3 -4
- package/prompts/detail/generate-document.md +8 -2
- package/prompts/detail/update-document.md +0 -2
- package/prompts/evaluate/document-structure.md +6 -6
- package/prompts/structure/check-document-structure.md +10 -10
- package/prompts/structure/document-rules.md +2 -2
- package/prompts/structure/generate-structure-system.md +3 -3
- package/prompts/structure/structure-example.md +1 -1
- package/prompts/structure/structure-getting-started.md +1 -1
- package/prompts/structure/update-document-structure.md +9 -9
- package/prompts/utils/feedback-refiner.md +1 -1
- package/tests/agents/clear/choose-contents.test.mjs +1 -1
- package/tests/agents/clear/clear-document-structure.test.mjs +36 -30
- package/tests/agents/evaluate/generate-report.test.mjs +1 -1
- package/tests/agents/generate/check-need-generate-structure.test.mjs +1 -1
- package/tests/agents/generate/document-structure-tools/add-document.test.mjs +2 -2
- package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +4 -4
- package/tests/agents/generate/document-structure-tools/move-document.test.mjs +3 -3
- package/tests/agents/generate/document-structure-tools/update-document.test.mjs +3 -3
- package/tests/agents/generate/user-review-document-structure.test.mjs +7 -5
- package/tests/agents/init/init.test.mjs +25 -19
- package/tests/agents/publish/publish-docs.test.mjs +99 -0
- package/tests/agents/update/check-document.test.mjs +1 -1
- package/tests/agents/utils/check-detail-result.test.mjs +2 -15
- package/tests/agents/utils/format-document-structure.test.mjs +5 -5
- package/tests/agents/utils/load-sources.test.mjs +4 -4
- package/tests/agents/utils/save-docs.test.mjs +1 -1
- package/tests/utils/auth-utils.test.mjs +1 -1
- package/tests/utils/conflict-detector.test.mjs +1 -1
- package/tests/utils/d2-utils.test.mjs +4 -4
- package/tests/utils/deploy.test.mjs +3 -10
- package/tests/utils/docs-finder-utils.test.mjs +8 -8
- package/tests/utils/kroki-utils.test.mjs +5 -5
- package/tests/utils/preferences-utils.test.mjs +5 -3
- package/tests/utils/save-value-to-config.test.mjs +3 -1
- package/types/document-structure-schema.mjs +9 -9
- package/utils/auth-utils.mjs +4 -0
- package/utils/conflict-detector.mjs +1 -1
- package/utils/constants/index.mjs +7 -4
- package/utils/d2-utils.mjs +11 -6
- package/utils/deploy.mjs +4 -20
- package/utils/docs-finder-utils.mjs +11 -11
- package/utils/kroki-utils.mjs +5 -4
- package/utils/markdown-checker.mjs +1 -21
- /package/prompts/detail/{d2-chart → d2-diagram}/official-examples.md +0 -0
|
@@ -15,6 +15,7 @@ import publishDocs from "../../../agents/publish/publish-docs.mjs";
|
|
|
15
15
|
import * as authUtils from "../../../utils/auth-utils.mjs";
|
|
16
16
|
import * as d2Utils from "../../../utils/d2-utils.mjs";
|
|
17
17
|
import * as utils from "../../../utils/utils.mjs";
|
|
18
|
+
import * as deployUtils from "../../../utils/deploy.mjs";
|
|
18
19
|
|
|
19
20
|
// Mock all external dependencies
|
|
20
21
|
const mockPublishDocs = {
|
|
@@ -51,6 +52,7 @@ describe("publish-docs", () => {
|
|
|
51
52
|
let getGithubRepoUrlSpy;
|
|
52
53
|
let loadConfigFromFileSpy;
|
|
53
54
|
let saveValueToConfigSpy;
|
|
55
|
+
let deploySpy;
|
|
54
56
|
|
|
55
57
|
beforeAll(() => {
|
|
56
58
|
// Apply mocks for external dependencies only
|
|
@@ -98,6 +100,10 @@ describe("publish-docs", () => {
|
|
|
98
100
|
);
|
|
99
101
|
loadConfigFromFileSpy = spyOn(utils, "loadConfigFromFile").mockResolvedValue({});
|
|
100
102
|
saveValueToConfigSpy = spyOn(utils, "saveValueToConfig").mockResolvedValue();
|
|
103
|
+
deploySpy = spyOn(deployUtils, "deploy").mockResolvedValue({
|
|
104
|
+
appUrl: "https://deployed.example.com",
|
|
105
|
+
token: "deploy-token",
|
|
106
|
+
});
|
|
101
107
|
|
|
102
108
|
mockOptions = {
|
|
103
109
|
prompts: {
|
|
@@ -125,6 +131,7 @@ describe("publish-docs", () => {
|
|
|
125
131
|
getGithubRepoUrlSpy?.mockRestore();
|
|
126
132
|
loadConfigFromFileSpy?.mockRestore();
|
|
127
133
|
saveValueToConfigSpy?.mockRestore();
|
|
134
|
+
deploySpy?.mockRestore();
|
|
128
135
|
});
|
|
129
136
|
|
|
130
137
|
// BASIC FUNCTIONALITY TESTS
|
|
@@ -593,6 +600,98 @@ describe("publish-docs", () => {
|
|
|
593
600
|
expect(mockOptions.prompts.select).not.toHaveBeenCalled();
|
|
594
601
|
});
|
|
595
602
|
|
|
603
|
+
// RESUME PREVIOUS WEBSITE SETUP TESTS
|
|
604
|
+
test("should show resume option when checkoutId exists in config", async () => {
|
|
605
|
+
loadConfigFromFileSpy.mockResolvedValue({
|
|
606
|
+
checkoutId: "cached-checkout-123",
|
|
607
|
+
});
|
|
608
|
+
mockOptions.prompts.select.mockResolvedValue("default");
|
|
609
|
+
|
|
610
|
+
await publishDocs(
|
|
611
|
+
{
|
|
612
|
+
docsDir: "./docs",
|
|
613
|
+
appUrl: "https://docsmith.aigne.io",
|
|
614
|
+
},
|
|
615
|
+
mockOptions,
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
expect(mockOptions.prompts.select).toHaveBeenCalledWith(
|
|
619
|
+
expect.objectContaining({
|
|
620
|
+
message: "Select platform to publish your documents:",
|
|
621
|
+
choices: expect.arrayContaining([
|
|
622
|
+
expect.objectContaining({
|
|
623
|
+
name: expect.stringContaining("Resume previous website setup"),
|
|
624
|
+
value: "new-instance-continue",
|
|
625
|
+
}),
|
|
626
|
+
]),
|
|
627
|
+
}),
|
|
628
|
+
);
|
|
629
|
+
|
|
630
|
+
// Verify the exact text content
|
|
631
|
+
const selectCall = mockOptions.prompts.select.mock.calls[0][0];
|
|
632
|
+
const resumeChoice = selectCall.choices.find(
|
|
633
|
+
(choice) => choice.value === "new-instance-continue",
|
|
634
|
+
);
|
|
635
|
+
expect(resumeChoice.name).toContain("Resume previous website setup");
|
|
636
|
+
expect(resumeChoice.name).toContain("Already paid.");
|
|
637
|
+
expect(resumeChoice.name).toContain(
|
|
638
|
+
"Continue where you left off. Your payment has already been processed.",
|
|
639
|
+
);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
test("should not show resume option when no checkoutId in config", async () => {
|
|
643
|
+
loadConfigFromFileSpy.mockResolvedValue({});
|
|
644
|
+
mockOptions.prompts.select.mockResolvedValue("default");
|
|
645
|
+
|
|
646
|
+
await publishDocs(
|
|
647
|
+
{
|
|
648
|
+
docsDir: "./docs",
|
|
649
|
+
appUrl: "https://docsmith.aigne.io",
|
|
650
|
+
},
|
|
651
|
+
mockOptions,
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
expect(mockOptions.prompts.select).toHaveBeenCalledWith(
|
|
655
|
+
expect.objectContaining({
|
|
656
|
+
message: "Select platform to publish your documents:",
|
|
657
|
+
choices: expect.not.arrayContaining([
|
|
658
|
+
expect.objectContaining({
|
|
659
|
+
value: "new-instance-continue",
|
|
660
|
+
}),
|
|
661
|
+
]),
|
|
662
|
+
}),
|
|
663
|
+
);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
test("should handle resume previous website setup selection", async () => {
|
|
667
|
+
deploySpy.mockResolvedValue({
|
|
668
|
+
appUrl: "https://resumed.example.com",
|
|
669
|
+
token: "resume-token",
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
loadConfigFromFileSpy.mockResolvedValue({
|
|
673
|
+
checkoutId: "cached-checkout-123",
|
|
674
|
+
paymentUrl: "https://payment.example.com",
|
|
675
|
+
});
|
|
676
|
+
mockOptions.prompts.select.mockResolvedValue("new-instance-continue");
|
|
677
|
+
|
|
678
|
+
const consoleSpy = spyOn(console, "log").mockImplementation(() => {});
|
|
679
|
+
|
|
680
|
+
await publishDocs(
|
|
681
|
+
{
|
|
682
|
+
docsDir: "./docs",
|
|
683
|
+
appUrl: "https://docsmith.aigne.io",
|
|
684
|
+
},
|
|
685
|
+
mockOptions,
|
|
686
|
+
);
|
|
687
|
+
|
|
688
|
+
expect(consoleSpy).toHaveBeenCalledWith("\nResuming your previous website setup...");
|
|
689
|
+
expect(deploySpy).toHaveBeenCalledWith("cached-checkout-123", "https://payment.example.com");
|
|
690
|
+
expect(getAccessTokenSpy).toHaveBeenCalledWith("https://resumed.example.com", "resume-token");
|
|
691
|
+
|
|
692
|
+
consoleSpy.mockRestore();
|
|
693
|
+
});
|
|
694
|
+
|
|
596
695
|
test("should handle URL validation edge cases", async () => {
|
|
597
696
|
loadConfigFromFileSpy.mockResolvedValue({});
|
|
598
697
|
mockOptions.prompts.select.mockResolvedValue("custom");
|
|
@@ -177,7 +177,7 @@ describe("check-document", () => {
|
|
|
177
177
|
expect(mockOptions.context.invoke).not.toHaveBeenCalled();
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
test("should handle missing original node in
|
|
180
|
+
test("should handle missing original node in documentation structure", async () => {
|
|
181
181
|
accessSpy.mockResolvedValue();
|
|
182
182
|
checkDetailResultSpy.mockResolvedValue({ isApproved: true });
|
|
183
183
|
|
|
@@ -229,7 +229,7 @@ set -euo pipefail
|
|
|
229
229
|
function deploy_app() {
|
|
230
230
|
local app_name="$1"
|
|
231
231
|
local version="$2"
|
|
232
|
-
|
|
232
|
+
|
|
233
233
|
echo "Deploying $app_name version $version"
|
|
234
234
|
docker run --rm "$app_name:$version"
|
|
235
235
|
}
|
|
@@ -337,19 +337,6 @@ This document demonstrates various programming language code blocks.`;
|
|
|
337
337
|
});
|
|
338
338
|
});
|
|
339
339
|
|
|
340
|
-
describe("D2 syntax validation", () => {
|
|
341
|
-
test("should handle D2 syntax errors", async () => {
|
|
342
|
-
const documentStructure = [];
|
|
343
|
-
const reviewContent =
|
|
344
|
-
"```d2\n" +
|
|
345
|
-
"invalid d2 syntax {{\n" + // Malformed D2
|
|
346
|
-
"```\n\n" +
|
|
347
|
-
"This has proper structure.";
|
|
348
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
349
|
-
expect(result.isApproved).toBe(false);
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
|
|
353
340
|
describe("Advanced table edge cases", () => {
|
|
354
341
|
test("should handle empty table cells correctly", async () => {
|
|
355
342
|
const documentStructure = [];
|
|
@@ -660,7 +647,7 @@ flowchart TD
|
|
|
660
647
|
A["1. Create Backend Implementation<br>api/src/providers/"]
|
|
661
648
|
B["2. Add Backend Configuration<br>api/src/providers/models.ts"]
|
|
662
649
|
C["3. Update Frontend Selector<br>src/pages/config/ai-providers/"]
|
|
663
|
-
|
|
650
|
+
|
|
664
651
|
A --> B --> C
|
|
665
652
|
\`\`\`
|
|
666
653
|
|
|
@@ -104,7 +104,7 @@ describe("format-document-structure", () => {
|
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
// BASIC FUNCTIONALITY TESTS
|
|
107
|
-
test("should format empty
|
|
107
|
+
test("should format empty documentation structure", async () => {
|
|
108
108
|
const result = await formatDocumentStructure({
|
|
109
109
|
documentStructure: [],
|
|
110
110
|
});
|
|
@@ -121,7 +121,7 @@ describe("format-document-structure", () => {
|
|
|
121
121
|
});
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
test("should format single item
|
|
124
|
+
test("should format single item documentation structure", async () => {
|
|
125
125
|
const documentStructure = [
|
|
126
126
|
{
|
|
127
127
|
title: "Getting Started",
|
|
@@ -152,7 +152,7 @@ describe("format-document-structure", () => {
|
|
|
152
152
|
expect(result.documentStructureYaml).toBe(expectedYaml);
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
test("should format multiple items
|
|
155
|
+
test("should format multiple items documentation structure", async () => {
|
|
156
156
|
const documentStructure = [
|
|
157
157
|
{
|
|
158
158
|
title: "API Reference",
|
|
@@ -321,7 +321,7 @@ describe("format-document-structure", () => {
|
|
|
321
321
|
expect(result.documentStructure).toEqual(documentStructure);
|
|
322
322
|
});
|
|
323
323
|
|
|
324
|
-
test("should return both yaml string and original
|
|
324
|
+
test("should return both yaml string and original documentation structure", async () => {
|
|
325
325
|
const documentStructure = [
|
|
326
326
|
{
|
|
327
327
|
title: "Return Test",
|
|
@@ -339,7 +339,7 @@ describe("format-document-structure", () => {
|
|
|
339
339
|
expect(result.documentStructure).toBe(documentStructure); // Should be the same reference
|
|
340
340
|
});
|
|
341
341
|
|
|
342
|
-
test("should preserve original
|
|
342
|
+
test("should preserve original documentation structure unchanged", async () => {
|
|
343
343
|
const originalDocumentStructure = [
|
|
344
344
|
{
|
|
345
345
|
title: "Original",
|
|
@@ -1030,8 +1030,8 @@ describe("load-sources", () => {
|
|
|
1030
1030
|
});
|
|
1031
1031
|
});
|
|
1032
1032
|
|
|
1033
|
-
describe("Document path and
|
|
1034
|
-
test("should load existing
|
|
1033
|
+
describe("Document path and documentation structure handling", () => {
|
|
1034
|
+
test("should load existing documentation structure", async () => {
|
|
1035
1035
|
const documentStructure = {
|
|
1036
1036
|
sections: ["Introduction", "API", "Examples"],
|
|
1037
1037
|
lastUpdated: new Date().toISOString(),
|
|
@@ -1050,7 +1050,7 @@ describe("load-sources", () => {
|
|
|
1050
1050
|
expect(result.originalDocumentStructure).toEqual(documentStructure);
|
|
1051
1051
|
});
|
|
1052
1052
|
|
|
1053
|
-
test("should handle malformed
|
|
1053
|
+
test("should handle malformed documentation structure JSON", async () => {
|
|
1054
1054
|
await writeFile(path.join(tempDir, "structure-plan.json"), "{ invalid json content");
|
|
1055
1055
|
|
|
1056
1056
|
const result = await loadSources({
|
|
@@ -1064,7 +1064,7 @@ describe("load-sources", () => {
|
|
|
1064
1064
|
expect(result.originalDocumentStructure).toBeUndefined();
|
|
1065
1065
|
});
|
|
1066
1066
|
|
|
1067
|
-
test("should handle non-ENOENT errors when reading
|
|
1067
|
+
test("should handle non-ENOENT errors when reading documentation structure JSON", async () => {
|
|
1068
1068
|
// Import fs promises module to spy on
|
|
1069
1069
|
const fsPromises = await import("node:fs/promises");
|
|
1070
1070
|
|
|
@@ -52,7 +52,7 @@ describe("save-docs", () => {
|
|
|
52
52
|
expect(initialFiles).toContain("getting-started.md");
|
|
53
53
|
expect(initialFiles).toContain("old-file.md");
|
|
54
54
|
|
|
55
|
-
// Test
|
|
55
|
+
// Test documentation structure
|
|
56
56
|
const documentStructure = [
|
|
57
57
|
{
|
|
58
58
|
path: "/overview",
|
|
@@ -336,7 +336,7 @@ describe("auth-utils", () => {
|
|
|
336
336
|
|
|
337
337
|
// Test that openPage calls the mock open function
|
|
338
338
|
await capturedOpenPage("https://auth.example.com");
|
|
339
|
-
expect(mockOpen).toHaveBeenCalledWith("https://auth.example.com
|
|
339
|
+
expect(mockOpen).toHaveBeenCalledWith("https://auth.example.com/?required_roles=owner%2Cadmin");
|
|
340
340
|
});
|
|
341
341
|
|
|
342
342
|
test("should handle authorization failure", async () => {
|
|
@@ -309,7 +309,7 @@ describe("conflict-detector", () => {
|
|
|
309
309
|
|
|
310
310
|
// Should include conflict resolution rules in final rules
|
|
311
311
|
expect(result.rules).toContain("=== Conflict Resolution Guidelines ===");
|
|
312
|
-
expect(result.rules).toContain("Create layered
|
|
312
|
+
expect(result.rules).toContain("Create layered documentation structure");
|
|
313
313
|
expect(result.rules).toContain("Create separate user paths");
|
|
314
314
|
|
|
315
315
|
// Should also include regular configuration content with enhanced format
|
|
@@ -6,7 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
|
|
7
7
|
import Debug from "debug";
|
|
8
8
|
|
|
9
|
-
import { TMP_ASSETS_DIR } from "../../utils/constants/index.mjs";
|
|
9
|
+
import { DOC_SMITH_DIR, TMP_ASSETS_DIR, TMP_DIR } from "../../utils/constants/index.mjs";
|
|
10
10
|
import {
|
|
11
11
|
beforePublishHook,
|
|
12
12
|
checkContent,
|
|
@@ -346,7 +346,7 @@ E -> F
|
|
|
346
346
|
try {
|
|
347
347
|
await checkContent({ content });
|
|
348
348
|
|
|
349
|
-
const assetDir = path.join(process.cwd(),
|
|
349
|
+
const assetDir = path.join(process.cwd(), DOC_SMITH_DIR, TMP_DIR, TMP_ASSETS_DIR, "d2");
|
|
350
350
|
const files = await readdir(assetDir);
|
|
351
351
|
const d2File = files.find((file) => file.endsWith(".d2"));
|
|
352
352
|
expect(d2File).toBeDefined();
|
|
@@ -365,7 +365,7 @@ E -> F
|
|
|
365
365
|
try {
|
|
366
366
|
await ensureTmpDir();
|
|
367
367
|
|
|
368
|
-
const tmpDir = path.join(tempDir,
|
|
368
|
+
const tmpDir = path.join(tempDir, DOC_SMITH_DIR, TMP_DIR);
|
|
369
369
|
const gitignorePath = path.join(tmpDir, ".gitignore");
|
|
370
370
|
|
|
371
371
|
expect(existsSync(tmpDir)).toBe(true);
|
|
@@ -386,7 +386,7 @@ E -> F
|
|
|
386
386
|
// First call
|
|
387
387
|
await ensureTmpDir();
|
|
388
388
|
|
|
389
|
-
const tmpDir = path.join(tempDir,
|
|
389
|
+
const tmpDir = path.join(tempDir, DOC_SMITH_DIR, TMP_DIR);
|
|
390
390
|
const gitignorePath = path.join(tmpDir, ".gitignore");
|
|
391
391
|
|
|
392
392
|
// Modify .gitignore to test if it gets overwritten
|
|
@@ -91,15 +91,8 @@ describe("deploy", () => {
|
|
|
91
91
|
|
|
92
92
|
// Verify BrokerClient was constructed with correct config
|
|
93
93
|
expect(mockBrokerClientConstructor).toHaveBeenCalledWith({
|
|
94
|
-
baseUrl: "",
|
|
95
94
|
authToken: "mock-auth-token",
|
|
96
|
-
|
|
97
|
-
timeout: 300000,
|
|
98
|
-
polling: {
|
|
99
|
-
interval: 3000,
|
|
100
|
-
maxAttempts: 100,
|
|
101
|
-
backoffStrategy: "linear",
|
|
102
|
-
},
|
|
95
|
+
baseUrl: "https://docsmith.aigne.io",
|
|
103
96
|
});
|
|
104
97
|
|
|
105
98
|
// Verify deploy was called with correct parameters
|
|
@@ -120,7 +113,6 @@ describe("deploy", () => {
|
|
|
120
113
|
ACCESS_PREPARING: expect.any(Function),
|
|
121
114
|
ACCESS_READY: expect.any(Function),
|
|
122
115
|
}),
|
|
123
|
-
onError: expect.any(Function),
|
|
124
116
|
}),
|
|
125
117
|
);
|
|
126
118
|
|
|
@@ -348,7 +340,8 @@ describe("deploy", () => {
|
|
|
348
340
|
// Verify BrokerClient was constructed with empty baseUrl
|
|
349
341
|
expect(mockBrokerClientConstructor).toHaveBeenCalledWith(
|
|
350
342
|
expect.objectContaining({
|
|
351
|
-
|
|
343
|
+
authToken: "mock-auth-token",
|
|
344
|
+
baseUrl: "https://docsmith.aigne.io",
|
|
352
345
|
}),
|
|
353
346
|
);
|
|
354
347
|
});
|
|
@@ -125,7 +125,7 @@ describe("docs-finder-utils", () => {
|
|
|
125
125
|
expect(result).toBeUndefined();
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
-
test("should handle empty
|
|
128
|
+
test("should handle empty documentation structure", () => {
|
|
129
129
|
const result = findItemByFlatName([], "any-name");
|
|
130
130
|
expect(result).toBeUndefined();
|
|
131
131
|
});
|
|
@@ -243,7 +243,7 @@ describe("docs-finder-utils", () => {
|
|
|
243
243
|
expect(result).toEqual(["guide.zh.md", "overview.zh.md"]);
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
-
test("should sort files by
|
|
246
|
+
test("should sort files by documentation structure order", async () => {
|
|
247
247
|
readdirSpy.mockResolvedValue(["guide.md", "overview.md", "advanced.md"]);
|
|
248
248
|
|
|
249
249
|
const documentStructure = [{ path: "/overview" }, { path: "/guide" }, { path: "/advanced" }];
|
|
@@ -253,7 +253,7 @@ describe("docs-finder-utils", () => {
|
|
|
253
253
|
expect(result).toEqual(["overview.md", "guide.md", "advanced.md"]);
|
|
254
254
|
});
|
|
255
255
|
|
|
256
|
-
test("should handle files not in
|
|
256
|
+
test("should handle files not in documentation structure", async () => {
|
|
257
257
|
readdirSpy.mockResolvedValue(["guide.md", "extra.md", "overview.md"]);
|
|
258
258
|
|
|
259
259
|
const documentStructure = [{ path: "/overview" }, { path: "/guide" }];
|
|
@@ -480,7 +480,7 @@ describe("docs-finder-utils", () => {
|
|
|
480
480
|
]);
|
|
481
481
|
});
|
|
482
482
|
|
|
483
|
-
test("should warn for files not in
|
|
483
|
+
test("should warn for files not in documentation structure", async () => {
|
|
484
484
|
readFileSpy.mockResolvedValue("content");
|
|
485
485
|
|
|
486
486
|
const selectedFiles = ["unknown.md"];
|
|
@@ -488,7 +488,7 @@ describe("docs-finder-utils", () => {
|
|
|
488
488
|
|
|
489
489
|
expect(result).toEqual([]);
|
|
490
490
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
491
|
-
"⚠️ No
|
|
491
|
+
"⚠️ No documentation structure item found for file: unknown.md",
|
|
492
492
|
);
|
|
493
493
|
});
|
|
494
494
|
|
|
@@ -508,7 +508,7 @@ describe("docs-finder-utils", () => {
|
|
|
508
508
|
},
|
|
509
509
|
]);
|
|
510
510
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
511
|
-
"⚠️ No
|
|
511
|
+
"⚠️ No documentation structure item found for file: unknown.md",
|
|
512
512
|
);
|
|
513
513
|
});
|
|
514
514
|
|
|
@@ -623,14 +623,14 @@ describe("docs-finder-utils", () => {
|
|
|
623
623
|
await expect(getMainLanguageFiles("/denied", "en")).rejects.toThrow("Permission denied");
|
|
624
624
|
});
|
|
625
625
|
|
|
626
|
-
test("processSelectedFiles should handle empty
|
|
626
|
+
test("processSelectedFiles should handle empty documentation structure", async () => {
|
|
627
627
|
readFileSpy.mockResolvedValue("content");
|
|
628
628
|
|
|
629
629
|
const result = await processSelectedFiles(["test.md"], [], "/docs");
|
|
630
630
|
|
|
631
631
|
expect(result).toEqual([]);
|
|
632
632
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
633
|
-
"⚠️ No
|
|
633
|
+
"⚠️ No documentation structure item found for file: test.md",
|
|
634
634
|
);
|
|
635
635
|
});
|
|
636
636
|
});
|
|
@@ -6,7 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
|
|
7
7
|
import Debug from "debug";
|
|
8
8
|
|
|
9
|
-
import { TMP_ASSETS_DIR } from "../../utils/constants/index.mjs";
|
|
9
|
+
import { DOC_SMITH_DIR, TMP_ASSETS_DIR, TMP_DIR } from "../../utils/constants/index.mjs";
|
|
10
10
|
import {
|
|
11
11
|
beforePublishHook,
|
|
12
12
|
checkD2Content,
|
|
@@ -451,7 +451,7 @@ E -> F
|
|
|
451
451
|
try {
|
|
452
452
|
await checkD2Content({ content });
|
|
453
453
|
|
|
454
|
-
const assetDir = path.join(process.cwd(),
|
|
454
|
+
const assetDir = path.join(process.cwd(), DOC_SMITH_DIR, TMP_DIR, TMP_ASSETS_DIR, "d2");
|
|
455
455
|
const files = await readdir(assetDir);
|
|
456
456
|
const d2File = files.find((file) => file.endsWith(".d2"));
|
|
457
457
|
expect(d2File).toBeDefined();
|
|
@@ -470,7 +470,7 @@ E -> F
|
|
|
470
470
|
try {
|
|
471
471
|
await ensureTmpDir();
|
|
472
472
|
|
|
473
|
-
const tmpDir = path.join(tempDir,
|
|
473
|
+
const tmpDir = path.join(tempDir, DOC_SMITH_DIR, TMP_DIR);
|
|
474
474
|
const gitignorePath = path.join(tmpDir, ".gitignore");
|
|
475
475
|
|
|
476
476
|
expect(existsSync(tmpDir)).toBe(true);
|
|
@@ -491,7 +491,7 @@ E -> F
|
|
|
491
491
|
// First call
|
|
492
492
|
await ensureTmpDir();
|
|
493
493
|
|
|
494
|
-
const tmpDir = path.join(tempDir,
|
|
494
|
+
const tmpDir = path.join(tempDir, DOC_SMITH_DIR, TMP_DIR);
|
|
495
495
|
const gitignorePath = path.join(tmpDir, ".gitignore");
|
|
496
496
|
|
|
497
497
|
// Modify .gitignore to test if it gets overwritten
|
|
@@ -632,7 +632,7 @@ E -> F
|
|
|
632
632
|
await Promise.all(promises);
|
|
633
633
|
|
|
634
634
|
// Should only create directory once
|
|
635
|
-
const tmpDir = path.join(tempDir,
|
|
635
|
+
const tmpDir = path.join(tempDir, DOC_SMITH_DIR, TMP_DIR);
|
|
636
636
|
expect(existsSync(tmpDir)).toBe(true);
|
|
637
637
|
|
|
638
638
|
// .gitignore should be created properly
|
|
@@ -3,6 +3,8 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { DOC_SMITH_DIR } from "../../utils/constants/index.mjs";
|
|
6
8
|
import {
|
|
7
9
|
addPreferenceRule,
|
|
8
10
|
deactivateRule,
|
|
@@ -44,7 +46,7 @@ describe("preferences-utils", () => {
|
|
|
44
46
|
|
|
45
47
|
test("should read existing preferences file", async () => {
|
|
46
48
|
// Create preferences directory and file
|
|
47
|
-
const prefsDir = join(testDir,
|
|
49
|
+
const prefsDir = join(testDir, DOC_SMITH_DIR);
|
|
48
50
|
await mkdir(prefsDir, { recursive: true });
|
|
49
51
|
|
|
50
52
|
await writeFile(
|
|
@@ -69,7 +71,7 @@ describe("preferences-utils", () => {
|
|
|
69
71
|
|
|
70
72
|
test("should handle malformed YAML gracefully", async () => {
|
|
71
73
|
// Create preferences directory and invalid file
|
|
72
|
-
const prefsDir = join(testDir,
|
|
74
|
+
const prefsDir = join(testDir, DOC_SMITH_DIR);
|
|
73
75
|
await mkdir(prefsDir, { recursive: true });
|
|
74
76
|
|
|
75
77
|
await writeFile(join(prefsDir, "preferences.yml"), "invalid: yaml: content: [", "utf8");
|
|
@@ -85,7 +87,7 @@ describe("preferences-utils", () => {
|
|
|
85
87
|
|
|
86
88
|
writePreferences(testPreferences);
|
|
87
89
|
|
|
88
|
-
const prefsDir = join(testDir,
|
|
90
|
+
const prefsDir = join(testDir, DOC_SMITH_DIR);
|
|
89
91
|
expect(existsSync(prefsDir)).toBe(true);
|
|
90
92
|
expect(existsSync(join(prefsDir, "preferences.yml"))).toBe(true);
|
|
91
93
|
});
|
|
@@ -5,6 +5,8 @@ import fsPromisesDefault, * as fsPromises from "node:fs/promises";
|
|
|
5
5
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
import { DOC_SMITH_DIR } from "../../utils/constants/index.mjs";
|
|
8
10
|
import { saveValueToConfig } from "../../utils/utils.mjs";
|
|
9
11
|
|
|
10
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -12,7 +14,7 @@ const __dirname = dirname(__filename);
|
|
|
12
14
|
|
|
13
15
|
// Test directory for isolated testing
|
|
14
16
|
const TEST_DIR = join(__dirname, "temp-config-test");
|
|
15
|
-
const TEST_CONFIG_DIR = join(TEST_DIR,
|
|
17
|
+
const TEST_CONFIG_DIR = join(TEST_DIR, DOC_SMITH_DIR);
|
|
16
18
|
const TEST_CONFIG_PATH = join(TEST_CONFIG_DIR, "config.yaml");
|
|
17
19
|
|
|
18
20
|
// Store original working directory
|
|
@@ -10,7 +10,7 @@ export const documentItemSchema = z.object({
|
|
|
10
10
|
sourceIds: z.array(z.string()).min(1, "At least one source ID is required"),
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// Documentation structure schema - represents the entire documentation structure array
|
|
14
14
|
export const documentStructureSchema = z.array(documentItemSchema);
|
|
15
15
|
|
|
16
16
|
// Add document schemas
|
|
@@ -80,7 +80,7 @@ export const getAddDocumentInputJsonSchema = () => {
|
|
|
80
80
|
const schema = zodToJsonSchema(addDocumentInputSchema);
|
|
81
81
|
// Add custom descriptions
|
|
82
82
|
if (schema.properties) {
|
|
83
|
-
schema.properties.documentStructure.description = "Current
|
|
83
|
+
schema.properties.documentStructure.description = "Current documentation structure array";
|
|
84
84
|
schema.properties.title.description = "Title of the new document";
|
|
85
85
|
schema.properties.description.description = "Description of the new document";
|
|
86
86
|
schema.properties.path.description = "URL path for the new document (must start with '/')";
|
|
@@ -96,7 +96,7 @@ export const getAddDocumentOutputJsonSchema = () => {
|
|
|
96
96
|
const schema = zodToJsonSchema(addDocumentOutputSchema);
|
|
97
97
|
if (schema.properties) {
|
|
98
98
|
schema.properties.documentStructure.description =
|
|
99
|
-
"Updated
|
|
99
|
+
"Updated documentation structure array with the new document added";
|
|
100
100
|
schema.properties.addedDocument.description = "The newly added document object";
|
|
101
101
|
}
|
|
102
102
|
return schema;
|
|
@@ -105,7 +105,7 @@ export const getAddDocumentOutputJsonSchema = () => {
|
|
|
105
105
|
export const getDeleteDocumentInputJsonSchema = () => {
|
|
106
106
|
const schema = zodToJsonSchema(deleteDocumentInputSchema);
|
|
107
107
|
if (schema.properties) {
|
|
108
|
-
schema.properties.documentStructure.description = "Current
|
|
108
|
+
schema.properties.documentStructure.description = "Current documentation structure array";
|
|
109
109
|
schema.properties.path.description = "URL path of the document to delete";
|
|
110
110
|
}
|
|
111
111
|
return schema;
|
|
@@ -115,7 +115,7 @@ export const getDeleteDocumentOutputJsonSchema = () => {
|
|
|
115
115
|
const schema = zodToJsonSchema(deleteDocumentOutputSchema);
|
|
116
116
|
if (schema.properties) {
|
|
117
117
|
schema.properties.documentStructure.description =
|
|
118
|
-
"Updated
|
|
118
|
+
"Updated documentation structure array with the document removed";
|
|
119
119
|
schema.properties.deletedDocument.description = "The deleted document object";
|
|
120
120
|
}
|
|
121
121
|
return schema;
|
|
@@ -124,7 +124,7 @@ export const getDeleteDocumentOutputJsonSchema = () => {
|
|
|
124
124
|
export const getMoveDocumentInputJsonSchema = () => {
|
|
125
125
|
const schema = zodToJsonSchema(moveDocumentInputSchema);
|
|
126
126
|
if (schema.properties) {
|
|
127
|
-
schema.properties.documentStructure.description = "Current
|
|
127
|
+
schema.properties.documentStructure.description = "Current documentation structure array";
|
|
128
128
|
schema.properties.path.description = "URL path of the document to move";
|
|
129
129
|
schema.properties.newParentId.description =
|
|
130
130
|
"Path of the new parent document (leave empty for top-level)";
|
|
@@ -136,7 +136,7 @@ export const getMoveDocumentOutputJsonSchema = () => {
|
|
|
136
136
|
const schema = zodToJsonSchema(moveDocumentOutputSchema);
|
|
137
137
|
if (schema.properties) {
|
|
138
138
|
schema.properties.documentStructure.description =
|
|
139
|
-
"Updated
|
|
139
|
+
"Updated documentation structure array with the document moved";
|
|
140
140
|
schema.properties.originalDocument.description = "The original document object before moving";
|
|
141
141
|
schema.properties.updatedDocument.description = "The updated document object after moving";
|
|
142
142
|
}
|
|
@@ -146,7 +146,7 @@ export const getMoveDocumentOutputJsonSchema = () => {
|
|
|
146
146
|
export const getUpdateDocumentInputJsonSchema = () => {
|
|
147
147
|
const schema = zodToJsonSchema(updateDocumentInputSchema);
|
|
148
148
|
if (schema.properties) {
|
|
149
|
-
schema.properties.documentStructure.description = "Current
|
|
149
|
+
schema.properties.documentStructure.description = "Current documentation structure array";
|
|
150
150
|
schema.properties.path.description = "URL path of the document to update";
|
|
151
151
|
schema.properties.title.description = "New title for the document (optional)";
|
|
152
152
|
schema.properties.description.description = "New description for the document (optional)";
|
|
@@ -166,7 +166,7 @@ export const getUpdateDocumentOutputJsonSchema = () => {
|
|
|
166
166
|
const schema = zodToJsonSchema(updateDocumentOutputSchema);
|
|
167
167
|
if (schema.properties) {
|
|
168
168
|
schema.properties.documentStructure.description =
|
|
169
|
-
"Updated
|
|
169
|
+
"Updated documentation structure array with the document modified";
|
|
170
170
|
schema.properties.originalDocument.description = "The original document object before update";
|
|
171
171
|
schema.properties.updatedDocument.description =
|
|
172
172
|
"The updated document object after modification";
|
package/utils/auth-utils.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "./blocklet.mjs";
|
|
16
16
|
import {
|
|
17
17
|
BLOCKLET_ADD_COMPONENT_DOCS,
|
|
18
|
+
DEFAULT_APP_URL,
|
|
18
19
|
DISCUSS_KIT_DID,
|
|
19
20
|
DISCUSS_KIT_STORE_URL,
|
|
20
21
|
DOC_OFFICIAL_ACCESS_TOKEN,
|
|
@@ -97,6 +98,9 @@ export async function getAccessToken(appUrl, ltToken = "") {
|
|
|
97
98
|
appLogo: "https://docsmith.aigne.io/image-bin/uploads/9645caf64b4232699982c4d940b03b90.svg",
|
|
98
99
|
openPage: (pageUrl) => {
|
|
99
100
|
const url = new URL(pageUrl);
|
|
101
|
+
if (url.hostname !== DEFAULT_APP_URL) {
|
|
102
|
+
url.searchParams.set("required_roles", "owner,admin");
|
|
103
|
+
}
|
|
100
104
|
if (ltToken) {
|
|
101
105
|
url.searchParams.set("__lt", ltToken);
|
|
102
106
|
}
|
|
@@ -76,7 +76,7 @@ export function getFilteredOptions(targetQuestion, currentSelections, allOptions
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Detect conflicts in user configuration selections that can be resolved through
|
|
79
|
+
* Detect conflicts in user configuration selections that can be resolved through documentation structure
|
|
80
80
|
* @param {Object} config - User configuration
|
|
81
81
|
* @returns {Array} Array of detected conflicts with resolution strategies
|
|
82
82
|
*/
|