@aigne/doc-smith 0.8.12-beta.8 → 0.8.12-beta.9
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 +13 -0
- package/agents/publish/index.yaml +4 -0
- package/agents/publish/publish-docs.mjs +77 -5
- package/agents/publish/translate-meta.mjs +103 -0
- package/agents/update/generate-document.yaml +30 -28
- package/agents/update/update-document-detail.yaml +3 -1
- package/agents/utils/update-branding.mjs +69 -0
- package/package.json +16 -2
- package/prompts/common/document/role-and-personality.md +3 -1
- package/prompts/detail/d2-diagram/guide.md +7 -1
- package/prompts/detail/d2-diagram/user-prompt.md +3 -0
- package/prompts/detail/generate/system-prompt.md +6 -7
- package/prompts/detail/generate/user-prompt.md +12 -3
- package/prompts/detail/update/user-prompt.md +0 -2
- package/prompts/structure/update/user-prompt.md +0 -4
- package/utils/file-utils.mjs +69 -24
- package/utils/markdown-checker.mjs +0 -20
- package/utils/request.mjs +7 -0
- package/utils/upload-files.mjs +231 -0
- package/utils/utils.mjs +11 -1
- package/.aigne/doc-smith/config.yaml +0 -77
- package/.aigne/doc-smith/history.yaml +0 -37
- package/.aigne/doc-smith/media-description.yaml +0 -91
- package/.aigne/doc-smith/output/structure-plan.json +0 -162
- package/.aigne/doc-smith/preferences.yml +0 -97
- package/.aigne/doc-smith/upload-cache.yaml +0 -1830
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
- package/.github/workflows/ci.yml +0 -54
- package/.github/workflows/create-release-pr.yaml +0 -21
- package/.github/workflows/publish-docs.yml +0 -65
- package/.github/workflows/release.yml +0 -49
- package/.github/workflows/reviewer.yml +0 -54
- package/.release-please-manifest.json +0 -3
- package/RELEASE.md +0 -9
- package/assets/screenshots/doc-complete-setup.png +0 -0
- package/assets/screenshots/doc-generate-docs.png +0 -0
- package/assets/screenshots/doc-generate.png +0 -0
- package/assets/screenshots/doc-generated-successfully.png +0 -0
- package/assets/screenshots/doc-publish.png +0 -0
- package/assets/screenshots/doc-regenerate.png +0 -0
- package/assets/screenshots/doc-translate-langs.png +0 -0
- package/assets/screenshots/doc-translate.png +0 -0
- package/assets/screenshots/doc-update.png +0 -0
- package/biome.json +0 -73
- package/codecov.yml +0 -15
- package/docs/_sidebar.md +0 -15
- package/docs/configuration-initial-setup.ja.md +0 -179
- package/docs/configuration-initial-setup.md +0 -198
- package/docs/configuration-initial-setup.zh-TW.md +0 -179
- package/docs/configuration-initial-setup.zh.md +0 -179
- package/docs/configuration-managing-preferences.ja.md +0 -100
- package/docs/configuration-managing-preferences.md +0 -100
- package/docs/configuration-managing-preferences.zh-TW.md +0 -100
- package/docs/configuration-managing-preferences.zh.md +0 -100
- package/docs/configuration.ja.md +0 -69
- package/docs/configuration.md +0 -69
- package/docs/configuration.zh-TW.md +0 -69
- package/docs/configuration.zh.md +0 -69
- package/docs/getting-started.ja.md +0 -107
- package/docs/getting-started.md +0 -107
- package/docs/getting-started.zh-TW.md +0 -107
- package/docs/getting-started.zh.md +0 -107
- package/docs/guides-cleaning-up.ja.md +0 -51
- package/docs/guides-cleaning-up.md +0 -52
- package/docs/guides-cleaning-up.zh-TW.md +0 -51
- package/docs/guides-cleaning-up.zh.md +0 -51
- package/docs/guides-evaluating-documents.ja.md +0 -66
- package/docs/guides-evaluating-documents.md +0 -107
- package/docs/guides-evaluating-documents.zh-TW.md +0 -66
- package/docs/guides-evaluating-documents.zh.md +0 -66
- package/docs/guides-generating-documentation.ja.md +0 -151
- package/docs/guides-generating-documentation.md +0 -89
- package/docs/guides-generating-documentation.zh-TW.md +0 -151
- package/docs/guides-generating-documentation.zh.md +0 -151
- package/docs/guides-interactive-chat.ja.md +0 -85
- package/docs/guides-interactive-chat.md +0 -93
- package/docs/guides-interactive-chat.zh-TW.md +0 -85
- package/docs/guides-interactive-chat.zh.md +0 -85
- package/docs/guides-managing-history.ja.md +0 -48
- package/docs/guides-managing-history.md +0 -53
- package/docs/guides-managing-history.zh-TW.md +0 -48
- package/docs/guides-managing-history.zh.md +0 -48
- package/docs/guides-publishing-your-docs.ja.md +0 -78
- package/docs/guides-publishing-your-docs.md +0 -83
- package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
- package/docs/guides-publishing-your-docs.zh.md +0 -78
- package/docs/guides-translating-documentation.ja.md +0 -95
- package/docs/guides-translating-documentation.md +0 -100
- package/docs/guides-translating-documentation.zh-TW.md +0 -95
- package/docs/guides-translating-documentation.zh.md +0 -95
- package/docs/guides-updating-documentation.ja.md +0 -77
- package/docs/guides-updating-documentation.md +0 -79
- package/docs/guides-updating-documentation.zh-TW.md +0 -77
- package/docs/guides-updating-documentation.zh.md +0 -77
- package/docs/guides.ja.md +0 -32
- package/docs/guides.md +0 -32
- package/docs/guides.zh-TW.md +0 -32
- package/docs/guides.zh.md +0 -32
- package/docs/overview.ja.md +0 -61
- package/docs/overview.md +0 -61
- package/docs/overview.zh-TW.md +0 -61
- package/docs/overview.zh.md +0 -61
- package/docs/release-notes.ja.md +0 -255
- package/docs/release-notes.md +0 -288
- package/docs/release-notes.zh-TW.md +0 -255
- package/docs/release-notes.zh.md +0 -255
- package/prompts/common/afs/afs-tools-usage.md +0 -5
- package/prompts/common/afs/use-afs-instruction.md +0 -1
- package/release-please-config.json +0 -14
- package/tests/agents/chat/chat.test.mjs +0 -46
- package/tests/agents/clear/choose-contents.test.mjs +0 -284
- package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
- package/tests/agents/clear/clear-document-config.test.mjs +0 -167
- package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
- package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
- package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
- package/tests/agents/evaluate/fixtures/api-services.md +0 -87
- package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
- package/tests/agents/evaluate/generate-report.test.mjs +0 -312
- package/tests/agents/generate/check-document-structure.test.mjs +0 -45
- package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
- package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
- package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
- package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
- package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
- package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
- package/tests/agents/generate/generate-structure.test.mjs +0 -45
- package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
- package/tests/agents/history/view.test.mjs +0 -97
- package/tests/agents/init/init.test.mjs +0 -1657
- package/tests/agents/prefs/prefs.test.mjs +0 -431
- package/tests/agents/publish/publish-docs.test.mjs +0 -787
- package/tests/agents/translate/choose-language.test.mjs +0 -311
- package/tests/agents/translate/translate-document.test.mjs +0 -51
- package/tests/agents/update/check-document.test.mjs +0 -463
- package/tests/agents/update/check-update-is-single.test.mjs +0 -300
- package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
- package/tests/agents/update/generate-document.test.mjs +0 -51
- package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
- package/tests/agents/update/user-review-document.test.mjs +0 -582
- package/tests/agents/utils/action-success.test.mjs +0 -54
- package/tests/agents/utils/check-detail-result.test.mjs +0 -743
- package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
- package/tests/agents/utils/choose-docs.test.mjs +0 -406
- package/tests/agents/utils/exit.test.mjs +0 -70
- package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
- package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
- package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
- package/tests/agents/utils/format-document-structure.test.mjs +0 -364
- package/tests/agents/utils/fs.test.mjs +0 -267
- package/tests/agents/utils/load-sources.test.mjs +0 -1470
- package/tests/agents/utils/save-docs.test.mjs +0 -109
- package/tests/agents/utils/save-output.test.mjs +0 -315
- package/tests/agents/utils/save-single-doc.test.mjs +0 -364
- package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
- package/tests/utils/auth-utils.test.mjs +0 -596
- package/tests/utils/blocklet.test.mjs +0 -336
- package/tests/utils/conflict-detector.test.mjs +0 -355
- package/tests/utils/constants.test.mjs +0 -295
- package/tests/utils/d2-utils.test.mjs +0 -437
- package/tests/utils/deploy.test.mjs +0 -399
- package/tests/utils/docs-finder-utils.test.mjs +0 -650
- package/tests/utils/file-utils.test.mjs +0 -521
- package/tests/utils/history-utils.test.mjs +0 -206
- package/tests/utils/kroki-utils.test.mjs +0 -646
- package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
- package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
- package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
- package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
- package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
- package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
- package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
- package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
- package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
- package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
- package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
- package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
- package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
- package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
- package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
- package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
- package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
- package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
- package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
- package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
- package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
- package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
- package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
- package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
- package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
- package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
- package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
- package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
- package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
- package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
- package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
- package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
- package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
- package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
- package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
- package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
- package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
- package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
- package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
- package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
- package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
- package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
- package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
- package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
- package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
- package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
- package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
- package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
- package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
- package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
- package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
- package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
- package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
- package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
- package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
- package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
- package/tests/utils/linter/index.test.mjs +0 -440
- package/tests/utils/linter/scan-results.mjs +0 -42
- package/tests/utils/load-config.test.mjs +0 -141
- package/tests/utils/markdown/index.test.mjs +0 -478
- package/tests/utils/mermaid-validator.test.mjs +0 -541
- package/tests/utils/mock-chat-model.mjs +0 -12
- package/tests/utils/preferences-utils.test.mjs +0 -465
- package/tests/utils/save-value-to-config.test.mjs +0 -483
- package/tests/utils/utils.test.mjs +0 -941
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
|
|
2
|
-
import userReviewDocumentStructure from "../../../agents/generate/user-review-document-structure.mjs";
|
|
3
|
-
|
|
4
|
-
import * as preferencesUtils from "../../../utils/preferences-utils.mjs";
|
|
5
|
-
import * as historyUtils from "../../../utils/history-utils.mjs";
|
|
6
|
-
|
|
7
|
-
describe("user-review-document-structure", () => {
|
|
8
|
-
let mockOptions;
|
|
9
|
-
let documentStructure;
|
|
10
|
-
|
|
11
|
-
// Spies for internal utils
|
|
12
|
-
let getActiveRulesForScopeSpy;
|
|
13
|
-
let consoleSpy;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
// Reset all mocks
|
|
17
|
-
mock.restore();
|
|
18
|
-
|
|
19
|
-
documentStructure = [
|
|
20
|
-
{
|
|
21
|
-
path: "/getting-started",
|
|
22
|
-
title: "Getting Started",
|
|
23
|
-
description: "Introduction and setup guide",
|
|
24
|
-
parentId: null,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
path: "/getting-started/installation",
|
|
28
|
-
title: "Installation",
|
|
29
|
-
description: "How to install the project",
|
|
30
|
-
parentId: "/getting-started",
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
path: "/api",
|
|
34
|
-
title: "API Reference",
|
|
35
|
-
description: "Complete API documentation",
|
|
36
|
-
parentId: null,
|
|
37
|
-
},
|
|
38
|
-
];
|
|
39
|
-
|
|
40
|
-
mockOptions = {
|
|
41
|
-
prompts: {
|
|
42
|
-
select: mock(async () => "no"),
|
|
43
|
-
input: mock(async () => ""),
|
|
44
|
-
},
|
|
45
|
-
context: {
|
|
46
|
-
agents: {
|
|
47
|
-
updateDocumentStructure: {},
|
|
48
|
-
checkFeedbackRefiner: {},
|
|
49
|
-
},
|
|
50
|
-
invoke: mock(async () => ({
|
|
51
|
-
documentStructure: documentStructure,
|
|
52
|
-
})),
|
|
53
|
-
userContext: {
|
|
54
|
-
currentStructure: [],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Set up spies for internal utils
|
|
60
|
-
getActiveRulesForScopeSpy = spyOn(preferencesUtils, "getActiveRulesForScope").mockReturnValue(
|
|
61
|
-
[],
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
consoleSpy = spyOn(console, "log").mockImplementation(() => {});
|
|
65
|
-
spyOn(historyUtils, "recordUpdate").mockImplementation(() => {});
|
|
66
|
-
|
|
67
|
-
// Clear prompts mock call history
|
|
68
|
-
mockOptions.prompts.select.mockClear();
|
|
69
|
-
mockOptions.prompts.input.mockClear();
|
|
70
|
-
mockOptions.context.invoke.mockClear();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
afterEach(() => {
|
|
74
|
-
// Restore all spies
|
|
75
|
-
getActiveRulesForScopeSpy?.mockRestore();
|
|
76
|
-
consoleSpy?.mockRestore();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("should return original structure when no documentation structure provided", async () => {
|
|
80
|
-
const result = await userReviewDocumentStructure({}, mockOptions);
|
|
81
|
-
|
|
82
|
-
expect(result).toBeDefined();
|
|
83
|
-
expect(result.documentStructure).toBeUndefined();
|
|
84
|
-
expect(mockOptions.prompts.select).not.toHaveBeenCalled();
|
|
85
|
-
expect(consoleSpy).toHaveBeenCalledWith("No documentation structure was generated to review.");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test("should return original structure when empty array provided", async () => {
|
|
89
|
-
const result = await userReviewDocumentStructure({ documentStructure: [] }, mockOptions);
|
|
90
|
-
|
|
91
|
-
expect(result).toBeDefined();
|
|
92
|
-
expect(result.documentStructure).toEqual([]);
|
|
93
|
-
expect(mockOptions.prompts.select).not.toHaveBeenCalled();
|
|
94
|
-
expect(consoleSpy).toHaveBeenCalledWith("No documentation structure was generated to review.");
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test("should return original structure when user chooses not to review", async () => {
|
|
98
|
-
mockOptions.prompts.select.mockImplementation(async () => "no");
|
|
99
|
-
|
|
100
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
101
|
-
|
|
102
|
-
expect(result).toBeDefined();
|
|
103
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
104
|
-
expect(mockOptions.prompts.select).toHaveBeenCalled();
|
|
105
|
-
expect(mockOptions.prompts.input).not.toHaveBeenCalled();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test("should enter review loop when user chooses to review", async () => {
|
|
109
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
110
|
-
mockOptions.prompts.input.mockImplementation(async () => ""); // Empty feedback to exit loop
|
|
111
|
-
|
|
112
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
113
|
-
|
|
114
|
-
expect(result).toBeDefined();
|
|
115
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
116
|
-
expect(mockOptions.prompts.select).toHaveBeenCalled();
|
|
117
|
-
expect(mockOptions.prompts.input).toHaveBeenCalled();
|
|
118
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
119
|
-
expect.stringContaining("Current Documentation Structure"),
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test("should process user feedback and call refineDocumentStructure agent", async () => {
|
|
124
|
-
const feedback = "Please add more details to the API section";
|
|
125
|
-
const refinedStructure = [
|
|
126
|
-
...documentStructure,
|
|
127
|
-
{
|
|
128
|
-
path: "/api/authentication",
|
|
129
|
-
title: "Authentication",
|
|
130
|
-
description: "How to authenticate API requests",
|
|
131
|
-
parentId: "/api",
|
|
132
|
-
},
|
|
133
|
-
];
|
|
134
|
-
|
|
135
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
136
|
-
mockOptions.prompts.input
|
|
137
|
-
.mockImplementationOnce(async () => feedback)
|
|
138
|
-
.mockImplementationOnce(async () => ""); // Exit loop on second call
|
|
139
|
-
|
|
140
|
-
mockOptions.context.invoke.mockImplementation(async () => {
|
|
141
|
-
// Simulate the agent updating the shared context
|
|
142
|
-
mockOptions.context.userContext.currentStructure = refinedStructure;
|
|
143
|
-
return {
|
|
144
|
-
documentStructure: refinedStructure,
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
149
|
-
|
|
150
|
-
expect(mockOptions.context.invoke).toHaveBeenCalledWith(
|
|
151
|
-
mockOptions.context.agents.updateDocumentStructure,
|
|
152
|
-
expect.objectContaining({
|
|
153
|
-
feedback: feedback,
|
|
154
|
-
documentStructure: documentStructure,
|
|
155
|
-
userPreferences: "",
|
|
156
|
-
}),
|
|
157
|
-
);
|
|
158
|
-
expect(mockOptions.context.invoke).toHaveBeenCalledWith(
|
|
159
|
-
mockOptions.context.agents.checkFeedbackRefiner,
|
|
160
|
-
expect.objectContaining({
|
|
161
|
-
documentStructureFeedback: feedback,
|
|
162
|
-
stage: "structure",
|
|
163
|
-
}),
|
|
164
|
-
);
|
|
165
|
-
expect(result.documentStructure).toEqual(refinedStructure);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test("should include user preferences in refinement call", async () => {
|
|
169
|
-
const mockRules = [{ rule: "Keep sections concise" }, { rule: "Use clear headings" }];
|
|
170
|
-
const expectedPreferences = "Keep sections concise\n\nUse clear headings";
|
|
171
|
-
|
|
172
|
-
getActiveRulesForScopeSpy
|
|
173
|
-
.mockImplementationOnce(() => mockRules) // structure rules
|
|
174
|
-
.mockImplementationOnce(() => []); // global rules
|
|
175
|
-
|
|
176
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
177
|
-
mockOptions.prompts.input
|
|
178
|
-
.mockImplementationOnce(async () => "Add more examples")
|
|
179
|
-
.mockImplementationOnce(async () => "");
|
|
180
|
-
|
|
181
|
-
await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
182
|
-
|
|
183
|
-
expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("structure", []);
|
|
184
|
-
expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
|
|
185
|
-
expect(mockOptions.context.invoke).toHaveBeenCalledWith(
|
|
186
|
-
mockOptions.context.agents.updateDocumentStructure,
|
|
187
|
-
expect.objectContaining({
|
|
188
|
-
userPreferences: expectedPreferences,
|
|
189
|
-
}),
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
test("should handle missing updateDocumentStructure agent", async () => {
|
|
194
|
-
mockOptions.context.agents = {}; // No updateDocumentStructure agent
|
|
195
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
196
|
-
mockOptions.prompts.input.mockImplementation(async () => "Some feedback");
|
|
197
|
-
|
|
198
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
199
|
-
|
|
200
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
201
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
202
|
-
"Unable to process your feedback - the documentation structure update feature is unavailable.",
|
|
203
|
-
);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
test("should handle errors from updateDocumentStructure agent", async () => {
|
|
207
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
208
|
-
mockOptions.prompts.input
|
|
209
|
-
.mockImplementationOnce(async () => "Some feedback")
|
|
210
|
-
.mockImplementationOnce(async () => "");
|
|
211
|
-
|
|
212
|
-
mockOptions.context.invoke.mockImplementation(async () => {
|
|
213
|
-
throw new Error("Agent failed");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
217
|
-
|
|
218
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
219
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
220
|
-
"\nPlease try rephrasing your feedback or continue with the current structure.",
|
|
221
|
-
);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
test("should handle multiple feedback rounds", async () => {
|
|
225
|
-
const firstFeedback = "Add authentication section";
|
|
226
|
-
const secondFeedback = "Reorganize API structure";
|
|
227
|
-
|
|
228
|
-
const firstRefinedStructure = [
|
|
229
|
-
...documentStructure,
|
|
230
|
-
{
|
|
231
|
-
path: "/api/auth",
|
|
232
|
-
title: "Authentication",
|
|
233
|
-
description: "Auth guide",
|
|
234
|
-
parentId: "/api",
|
|
235
|
-
},
|
|
236
|
-
];
|
|
237
|
-
|
|
238
|
-
const finalRefinedStructure = [
|
|
239
|
-
...firstRefinedStructure,
|
|
240
|
-
{
|
|
241
|
-
path: "/api/endpoints",
|
|
242
|
-
title: "Endpoints",
|
|
243
|
-
description: "API endpoints",
|
|
244
|
-
parentId: "/api",
|
|
245
|
-
},
|
|
246
|
-
];
|
|
247
|
-
|
|
248
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
249
|
-
mockOptions.prompts.input
|
|
250
|
-
.mockImplementationOnce(async () => firstFeedback)
|
|
251
|
-
.mockImplementationOnce(async () => secondFeedback)
|
|
252
|
-
.mockImplementationOnce(async () => ""); // Exit loop
|
|
253
|
-
|
|
254
|
-
let invokeCount = 0;
|
|
255
|
-
mockOptions.context.invoke.mockImplementation(async () => {
|
|
256
|
-
invokeCount++;
|
|
257
|
-
if (invokeCount === 1) {
|
|
258
|
-
// refineDocumentStructure 1st call
|
|
259
|
-
mockOptions.context.userContext.currentStructure = firstRefinedStructure;
|
|
260
|
-
return { documentStructure: firstRefinedStructure };
|
|
261
|
-
} else if (invokeCount === 2) {
|
|
262
|
-
// checkFeedbackRefiner 1st call
|
|
263
|
-
return {};
|
|
264
|
-
} else if (invokeCount === 3) {
|
|
265
|
-
// refineDocumentStructure 2nd call
|
|
266
|
-
mockOptions.context.userContext.currentStructure = finalRefinedStructure;
|
|
267
|
-
return { documentStructure: finalRefinedStructure };
|
|
268
|
-
} else {
|
|
269
|
-
// checkFeedbackRefiner 2nd call
|
|
270
|
-
return {};
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
275
|
-
|
|
276
|
-
expect(mockOptions.context.invoke).toHaveBeenCalledTimes(4); // 2 refine + 2 feedback refiner calls
|
|
277
|
-
expect(result.documentStructure).toEqual(finalRefinedStructure);
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
test("should handle missing checkFeedbackRefiner agent gracefully", async () => {
|
|
281
|
-
const feedback = "Some feedback";
|
|
282
|
-
mockOptions.context.agents = { updateDocumentStructure: {} }; // No checkFeedbackRefiner agent
|
|
283
|
-
|
|
284
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
285
|
-
mockOptions.prompts.input
|
|
286
|
-
.mockImplementationOnce(async () => feedback)
|
|
287
|
-
.mockImplementationOnce(async () => "");
|
|
288
|
-
|
|
289
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
290
|
-
|
|
291
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
292
|
-
expect(mockOptions.context.invoke).toHaveBeenCalledTimes(1); // Only refineDocumentStructure called
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
test("should handle checkFeedbackRefiner errors gracefully", async () => {
|
|
296
|
-
const feedback = "Some feedback";
|
|
297
|
-
const warnSpy = spyOn(console, "warn").mockImplementation(() => {});
|
|
298
|
-
|
|
299
|
-
mockOptions.prompts.select.mockImplementation(async () => "yes");
|
|
300
|
-
mockOptions.prompts.input
|
|
301
|
-
.mockImplementationOnce(async () => feedback)
|
|
302
|
-
.mockImplementationOnce(async () => "");
|
|
303
|
-
|
|
304
|
-
mockOptions.context.invoke
|
|
305
|
-
.mockImplementationOnce(async () => ({ documentStructure })) // refineDocumentStructure
|
|
306
|
-
.mockImplementationOnce(async () => {
|
|
307
|
-
throw new Error("Refiner failed");
|
|
308
|
-
}); // checkFeedbackRefiner
|
|
309
|
-
|
|
310
|
-
const result = await userReviewDocumentStructure({ documentStructure }, mockOptions);
|
|
311
|
-
|
|
312
|
-
expect(result.documentStructure).toEqual(documentStructure);
|
|
313
|
-
expect(warnSpy).toHaveBeenCalledWith(
|
|
314
|
-
"Your feedback was applied but not saved as a preference.",
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
warnSpy.mockRestore();
|
|
318
|
-
});
|
|
319
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, test, mock, spyOn } from "bun:test";
|
|
2
|
-
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { DOC_SMITH_DIR } from "../../../utils/constants/index.mjs";
|
|
5
|
-
import viewHistory from "../../../agents/history/view.mjs";
|
|
6
|
-
|
|
7
|
-
const TEST_DIR = join(process.cwd(), `${DOC_SMITH_DIR}-test`);
|
|
8
|
-
const ORIGINAL_CWD = process.cwd();
|
|
9
|
-
|
|
10
|
-
describe("History View", () => {
|
|
11
|
-
let consoleLogMock;
|
|
12
|
-
|
|
13
|
-
beforeEach(async () => {
|
|
14
|
-
// Clean up test directory
|
|
15
|
-
if (existsSync(TEST_DIR)) {
|
|
16
|
-
rmSync(TEST_DIR, { recursive: true });
|
|
17
|
-
}
|
|
18
|
-
mkdirSync(TEST_DIR, { recursive: true });
|
|
19
|
-
|
|
20
|
-
// Change to test directory
|
|
21
|
-
process.chdir(TEST_DIR);
|
|
22
|
-
|
|
23
|
-
// Spy on console.log
|
|
24
|
-
consoleLogMock = spyOn(console, "log");
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
// Restore original directory
|
|
29
|
-
process.chdir(ORIGINAL_CWD);
|
|
30
|
-
|
|
31
|
-
// Clean up
|
|
32
|
-
if (existsSync(TEST_DIR)) {
|
|
33
|
-
rmSync(TEST_DIR, { recursive: true });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
mock.restore();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test("should display message when no history exists", () => {
|
|
40
|
-
// No history file exists
|
|
41
|
-
const result = viewHistory();
|
|
42
|
-
|
|
43
|
-
expect(result).toEqual({});
|
|
44
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("No update history found"));
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test("should display formatted history entries", async () => {
|
|
48
|
-
// Create history file with sample data
|
|
49
|
-
const historyPath = join(process.cwd(), DOC_SMITH_DIR, "history.yaml");
|
|
50
|
-
mkdirSync(join(process.cwd(), DOC_SMITH_DIR), { recursive: true });
|
|
51
|
-
|
|
52
|
-
const historyData = {
|
|
53
|
-
entries: [
|
|
54
|
-
{
|
|
55
|
-
timestamp: "2023-01-01T00:00:00.000Z",
|
|
56
|
-
operation: "document_update",
|
|
57
|
-
feedback: "Updated documentation",
|
|
58
|
-
documentPath: "/readme.md",
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
timestamp: "2023-01-02T00:00:00.000Z",
|
|
62
|
-
operation: "structure_update",
|
|
63
|
-
feedback: "Reorganized sections",
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// Use YAML format instead of JSON
|
|
69
|
-
const { stringify } = await import("yaml");
|
|
70
|
-
writeFileSync(historyPath, stringify(historyData), "utf8");
|
|
71
|
-
|
|
72
|
-
const result = viewHistory();
|
|
73
|
-
|
|
74
|
-
expect(result).toEqual({});
|
|
75
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("📜 Update History"));
|
|
76
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("document_update"));
|
|
77
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("structure_update"));
|
|
78
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("Updated documentation"));
|
|
79
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("Reorganized sections"));
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("should handle empty history entries", async () => {
|
|
83
|
-
// Create history file with empty entries
|
|
84
|
-
const historyPath = join(process.cwd(), DOC_SMITH_DIR, "history.yaml");
|
|
85
|
-
mkdirSync(join(process.cwd(), DOC_SMITH_DIR), { recursive: true });
|
|
86
|
-
|
|
87
|
-
const historyData = { entries: [] };
|
|
88
|
-
// Use YAML format instead of JSON
|
|
89
|
-
const { stringify } = await import("yaml");
|
|
90
|
-
writeFileSync(historyPath, stringify(historyData), "utf8");
|
|
91
|
-
|
|
92
|
-
const result = viewHistory();
|
|
93
|
-
|
|
94
|
-
expect(result).toEqual({});
|
|
95
|
-
expect(consoleLogMock).toHaveBeenCalledWith(expect.stringContaining("No update history found"));
|
|
96
|
-
});
|
|
97
|
-
});
|