@aigne/doc-smith 0.8.12-beta.8 → 0.8.12
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 +15 -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
package/utils/file-utils.mjs
CHANGED
|
@@ -559,36 +559,81 @@ export function getStructurePlanPath(workDir) {
|
|
|
559
559
|
return path.join(cwd, ".aigne", "doc-smith", "output", "structure-plan.json");
|
|
560
560
|
}
|
|
561
561
|
|
|
562
|
+
// Shared extension → MIME type mapping table
|
|
563
|
+
const EXT_TO_MIME = {
|
|
564
|
+
".jpg": "image/jpeg",
|
|
565
|
+
".jpeg": "image/jpeg",
|
|
566
|
+
".png": "image/png",
|
|
567
|
+
".gif": "image/gif",
|
|
568
|
+
".bmp": "image/bmp",
|
|
569
|
+
".webp": "image/webp",
|
|
570
|
+
".svg": "image/svg+xml",
|
|
571
|
+
".heic": "image/heic",
|
|
572
|
+
".heif": "image/heif",
|
|
573
|
+
".mp4": "video/mp4",
|
|
574
|
+
".mpeg": "video/mpeg",
|
|
575
|
+
".mpg": "video/mpg",
|
|
576
|
+
".mov": "video/mov",
|
|
577
|
+
".avi": "video/avi",
|
|
578
|
+
".flv": "video/x-flv",
|
|
579
|
+
".mkv": "video/x-matroska",
|
|
580
|
+
".webm": "video/webm",
|
|
581
|
+
".wmv": "video/wmv",
|
|
582
|
+
".m4v": "video/x-m4v",
|
|
583
|
+
".3gpp": "video/3gpp",
|
|
584
|
+
".mp3": "audio/mpeg",
|
|
585
|
+
".wav": "audio/wav",
|
|
586
|
+
".pdf": "application/pdf",
|
|
587
|
+
".doc": "application/msword",
|
|
588
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
589
|
+
".xls": "application/vnd.ms-excel",
|
|
590
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
591
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
592
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
593
|
+
".txt": "text/plain",
|
|
594
|
+
".json": "application/json",
|
|
595
|
+
".xml": "application/xml",
|
|
596
|
+
".html": "text/html",
|
|
597
|
+
".css": "text/css",
|
|
598
|
+
".js": "application/javascript",
|
|
599
|
+
".zip": "application/zip",
|
|
600
|
+
".rar": "application/x-rar-compressed",
|
|
601
|
+
".7z": "application/x-7z-compressed",
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
// Build reverse mapping: MIME → extensions
|
|
605
|
+
const MIME_TO_EXTS = Object.entries(EXT_TO_MIME).reduce((acc, [ext, mime]) => {
|
|
606
|
+
const key = mime.toLowerCase();
|
|
607
|
+
if (!acc[key]) {
|
|
608
|
+
acc[key] = [];
|
|
609
|
+
}
|
|
610
|
+
acc[key].push(ext);
|
|
611
|
+
return acc;
|
|
612
|
+
}, {});
|
|
613
|
+
|
|
562
614
|
/**
|
|
563
615
|
* Get MIME type from file path based on extension
|
|
564
616
|
* @param {string} filePath - File path
|
|
565
617
|
* @returns {string} MIME type
|
|
566
618
|
*/
|
|
567
619
|
export function getMimeType(filePath) {
|
|
568
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
".mkv": "video/x-matroska",
|
|
586
|
-
".webm": "video/webm",
|
|
587
|
-
".wmv": "video/wmv",
|
|
588
|
-
".m4v": "video/x-m4v",
|
|
589
|
-
".3gpp": "video/3gpp",
|
|
590
|
-
};
|
|
591
|
-
return mimeTypes[ext] || "application/octet-stream";
|
|
620
|
+
const ext = path.extname(filePath || "").toLowerCase();
|
|
621
|
+
return EXT_TO_MIME[ext] || "application/octet-stream";
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Get file extension (without dot) from content type
|
|
626
|
+
* Handles content types with parameters (e.g., "image/jpeg; charset=utf-8")
|
|
627
|
+
* @param {string} contentType - Content type string
|
|
628
|
+
* @returns {string} File extension without dot
|
|
629
|
+
*/
|
|
630
|
+
export function getExtnameFromContentType(contentType) {
|
|
631
|
+
if (!contentType) return "";
|
|
632
|
+
const base = String(contentType).split(";")[0].trim().toLowerCase();
|
|
633
|
+
const exts = MIME_TO_EXTS[base];
|
|
634
|
+
if (exts?.length) return exts[0].slice(1); // Remove leading dot
|
|
635
|
+
const parts = base.split("/");
|
|
636
|
+
return parts[1] || "";
|
|
592
637
|
}
|
|
593
638
|
|
|
594
639
|
/**
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import pMap from "p-map";
|
|
4
3
|
import remarkGfm from "remark-gfm";
|
|
5
4
|
import remarkLint from "remark-lint";
|
|
6
5
|
import remarkParse from "remark-parse";
|
|
7
6
|
import { unified } from "unified";
|
|
8
7
|
import { visit } from "unist-util-visit";
|
|
9
8
|
import { VFile } from "vfile";
|
|
10
|
-
import { KROKI_CONCURRENCY } from "./constants/index.mjs";
|
|
11
|
-
import { checkContent, isValidCode } from "./d2-utils.mjs";
|
|
12
9
|
import { validateMermaidSyntax } from "./mermaid-validator.mjs";
|
|
13
10
|
|
|
14
11
|
/**
|
|
@@ -378,7 +375,6 @@ export async function checkMarkdown(markdown, source = "content", options = {})
|
|
|
378
375
|
|
|
379
376
|
// Check mermaid code blocks and other custom validations
|
|
380
377
|
const mermaidChecks = [];
|
|
381
|
-
const d2ChecksList = [];
|
|
382
378
|
visit(ast, "code", (node) => {
|
|
383
379
|
if (node.lang) {
|
|
384
380
|
const line = node.position?.start?.line || "unknown";
|
|
@@ -467,12 +463,6 @@ export async function checkMarkdown(markdown, source = "content", options = {})
|
|
|
467
463
|
specialCharMatch = nodeWithSpecialCharsRegex.exec(mermaidContent);
|
|
468
464
|
}
|
|
469
465
|
}
|
|
470
|
-
if (isValidCode(node.lang)) {
|
|
471
|
-
d2ChecksList.push({
|
|
472
|
-
content: node.value,
|
|
473
|
-
line,
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
466
|
}
|
|
477
467
|
});
|
|
478
468
|
|
|
@@ -524,16 +514,6 @@ export async function checkMarkdown(markdown, source = "content", options = {})
|
|
|
524
514
|
// Wait for all mermaid checks to complete
|
|
525
515
|
await Promise.all(mermaidChecks);
|
|
526
516
|
|
|
527
|
-
await pMap(
|
|
528
|
-
d2ChecksList,
|
|
529
|
-
async ({ content, line }) =>
|
|
530
|
-
checkContent({ content }).catch((err) => {
|
|
531
|
-
const errorMessage = err?.message || String(err) || "Unknown d2 syntax error";
|
|
532
|
-
errorMessages.push(`Found D2 syntax error in ${source} at line ${line}: ${errorMessage}`);
|
|
533
|
-
}),
|
|
534
|
-
{ concurrency: KROKI_CONCURRENCY },
|
|
535
|
-
);
|
|
536
|
-
|
|
537
517
|
// Run markdown linting rules
|
|
538
518
|
await processor.run(ast, file);
|
|
539
519
|
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import pLimit from "p-limit";
|
|
6
|
+
import pRetry from "p-retry";
|
|
7
|
+
|
|
8
|
+
import { getComponentMountPoint } from "./blocklet.mjs";
|
|
9
|
+
import { DISCUSS_KIT_DID } from "./constants/index.mjs";
|
|
10
|
+
import { getMimeType } from "./file-utils.mjs";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Perform single file upload
|
|
14
|
+
*/
|
|
15
|
+
async function performSingleUpload(filePath, fileHash, uploadEndpoint, accessToken, url) {
|
|
16
|
+
const baseFilename = path.basename(filePath, path.extname(filePath));
|
|
17
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
18
|
+
const stats = fs.statSync(filePath);
|
|
19
|
+
const fileSize = stats.size;
|
|
20
|
+
const fileExt = path.extname(filePath).substring(1);
|
|
21
|
+
const mimeType = getMimeType(filePath);
|
|
22
|
+
|
|
23
|
+
const hashBasedFilename = `${fileHash.substring(0, 16)}.${fileExt}`;
|
|
24
|
+
|
|
25
|
+
const uploaderId = "Uploader";
|
|
26
|
+
const fileId = `${uploaderId}-${baseFilename.toLowerCase().replace(/[^a-z0-9]/g, "")}-${fileHash.substring(0, 16)}`;
|
|
27
|
+
|
|
28
|
+
const tusMetadata = {
|
|
29
|
+
uploaderId,
|
|
30
|
+
relativePath: hashBasedFilename,
|
|
31
|
+
name: hashBasedFilename,
|
|
32
|
+
type: mimeType,
|
|
33
|
+
filetype: mimeType,
|
|
34
|
+
filename: hashBasedFilename,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const encodedMetadata = Object.entries(tusMetadata)
|
|
38
|
+
.map(([key, value]) => `${key} ${Buffer.from(value).toString("base64")}`)
|
|
39
|
+
.join(",");
|
|
40
|
+
|
|
41
|
+
const uploadEndpointUrl = new URL(uploadEndpoint);
|
|
42
|
+
const endpointPath = uploadEndpointUrl.pathname;
|
|
43
|
+
|
|
44
|
+
// Create upload
|
|
45
|
+
const createResponse = await fetch(uploadEndpoint, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: {
|
|
48
|
+
"Tus-Resumable": "1.0.0",
|
|
49
|
+
"Upload-Length": fileSize.toString(),
|
|
50
|
+
"Upload-Metadata": encodedMetadata,
|
|
51
|
+
Cookie: `login_token=${accessToken}`,
|
|
52
|
+
"x-uploader-file-name": hashBasedFilename,
|
|
53
|
+
"x-uploader-file-id": fileId,
|
|
54
|
+
"x-uploader-file-ext": fileExt,
|
|
55
|
+
"x-uploader-base-url": endpointPath,
|
|
56
|
+
"x-uploader-endpoint-url": uploadEndpoint,
|
|
57
|
+
"x-uploader-metadata": JSON.stringify({
|
|
58
|
+
uploaderId,
|
|
59
|
+
relativePath: hashBasedFilename,
|
|
60
|
+
name: hashBasedFilename,
|
|
61
|
+
type: mimeType,
|
|
62
|
+
}),
|
|
63
|
+
"x-component-did": DISCUSS_KIT_DID,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!createResponse.ok) {
|
|
68
|
+
const errorText = await createResponse.text();
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Failed to create upload: ${createResponse.status} ${createResponse.statusText}\n${errorText}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const uploadUrl = createResponse.headers.get("Location");
|
|
75
|
+
if (!uploadUrl) {
|
|
76
|
+
throw new Error("No upload URL received from server");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Upload file content
|
|
80
|
+
const uploadResponse = await fetch(`${url.origin}${uploadUrl}`, {
|
|
81
|
+
method: "PATCH",
|
|
82
|
+
headers: {
|
|
83
|
+
"Tus-Resumable": "1.0.0",
|
|
84
|
+
"Upload-Offset": "0",
|
|
85
|
+
"Content-Type": "application/offset+octet-stream",
|
|
86
|
+
Cookie: `login_token=${accessToken}`,
|
|
87
|
+
"x-uploader-file-name": hashBasedFilename,
|
|
88
|
+
"x-uploader-file-id": fileId,
|
|
89
|
+
"x-uploader-file-ext": fileExt,
|
|
90
|
+
"x-uploader-base-url": endpointPath,
|
|
91
|
+
"x-uploader-endpoint-url": uploadEndpoint,
|
|
92
|
+
"x-uploader-metadata": JSON.stringify({
|
|
93
|
+
uploaderId,
|
|
94
|
+
relativePath: hashBasedFilename,
|
|
95
|
+
name: hashBasedFilename,
|
|
96
|
+
type: mimeType,
|
|
97
|
+
}),
|
|
98
|
+
"x-component-did": DISCUSS_KIT_DID,
|
|
99
|
+
"x-uploader-file-exist": "true",
|
|
100
|
+
},
|
|
101
|
+
body: fileBuffer,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!uploadResponse.ok) {
|
|
105
|
+
const errorText = await uploadResponse.text();
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Failed to upload file: ${uploadResponse.status} ${uploadResponse.statusText}\n${errorText}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const uploadResult = await uploadResponse.json();
|
|
112
|
+
|
|
113
|
+
let uploadedFileUrl = uploadResult.url;
|
|
114
|
+
if (!uploadedFileUrl && uploadResult?.size) {
|
|
115
|
+
uploadedFileUrl = uploadResponse.url;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!uploadedFileUrl) {
|
|
119
|
+
throw new Error("No URL found in the upload response");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
filePath,
|
|
124
|
+
url: uploadedFileUrl,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Upload multiple files with concurrency control
|
|
130
|
+
* @param {Object} options - Upload options
|
|
131
|
+
* @param {string} options.appUrl - Application URL
|
|
132
|
+
* @param {string[]} options.filePaths - Array of file paths to upload
|
|
133
|
+
* @param {string} options.accessToken - Access token for authentication
|
|
134
|
+
* @param {number} [options.concurrency=3] - Number of concurrent uploads
|
|
135
|
+
* @param {string} [options.endpoint] - Custom upload endpoint
|
|
136
|
+
* @returns {Promise<{results: Array<{filePath: string, url: string}>}>}
|
|
137
|
+
*/
|
|
138
|
+
export async function uploadFiles(options) {
|
|
139
|
+
const { appUrl, filePaths, endpoint, concurrency = 3, accessToken } = options;
|
|
140
|
+
|
|
141
|
+
if (filePaths.length === 0) {
|
|
142
|
+
return { results: [] };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const url = new URL(appUrl);
|
|
146
|
+
const mountPoint = await getComponentMountPoint(appUrl, DISCUSS_KIT_DID);
|
|
147
|
+
|
|
148
|
+
// Use custom endpoint or default to discuss kit media endpoint
|
|
149
|
+
const uploadEndpoint = endpoint || `${url.origin}${mountPoint}/api/uploads`;
|
|
150
|
+
|
|
151
|
+
const limit = pLimit(concurrency);
|
|
152
|
+
const ongoingUploads = new Map();
|
|
153
|
+
|
|
154
|
+
const uploadPromises = filePaths.map((filePath) =>
|
|
155
|
+
limit(async () => {
|
|
156
|
+
const filename = path.basename(filePath);
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
160
|
+
const fileHash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
|
|
161
|
+
|
|
162
|
+
// Check if this file is already being uploaded
|
|
163
|
+
const existingUpload = ongoingUploads.get(fileHash);
|
|
164
|
+
if (existingUpload) {
|
|
165
|
+
const result = await existingUpload;
|
|
166
|
+
return {
|
|
167
|
+
filePath,
|
|
168
|
+
url: result.url,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Create upload promise and cache it
|
|
173
|
+
const uploadPromise = (async () => {
|
|
174
|
+
try {
|
|
175
|
+
const result = await pRetry(
|
|
176
|
+
() => performSingleUpload(filePath, fileHash, uploadEndpoint, accessToken, url),
|
|
177
|
+
{
|
|
178
|
+
retries: 3,
|
|
179
|
+
onFailedAttempt: (error) => {
|
|
180
|
+
console.warn(
|
|
181
|
+
`File upload attempt ${error.attemptNumber} failed for "${filename}". Remaining retries: ${error.retriesLeft}`,
|
|
182
|
+
);
|
|
183
|
+
if (error.retriesLeft === 0) {
|
|
184
|
+
console.error(
|
|
185
|
+
`File upload failed - all retry attempts exhausted for "${filename}"`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return result;
|
|
193
|
+
} catch (error) {
|
|
194
|
+
console.error(
|
|
195
|
+
`File upload failed - error uploading "${filename}" after all retries:`,
|
|
196
|
+
error,
|
|
197
|
+
);
|
|
198
|
+
return {
|
|
199
|
+
filePath,
|
|
200
|
+
url: "",
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
})();
|
|
204
|
+
|
|
205
|
+
// Cache the upload promise
|
|
206
|
+
ongoingUploads.set(fileHash, uploadPromise);
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const result = await uploadPromise;
|
|
210
|
+
return {
|
|
211
|
+
filePath,
|
|
212
|
+
url: result.url,
|
|
213
|
+
};
|
|
214
|
+
} finally {
|
|
215
|
+
// Clean up the ongoing upload tracking
|
|
216
|
+
ongoingUploads.delete(fileHash);
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error(`Error processing ${filename}:`, error);
|
|
220
|
+
return {
|
|
221
|
+
filePath,
|
|
222
|
+
url: "",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const uploadResults = await Promise.all(uploadPromises);
|
|
229
|
+
|
|
230
|
+
return { results: uploadResults };
|
|
231
|
+
}
|
package/utils/utils.mjs
CHANGED
|
@@ -47,6 +47,16 @@ export function isGlobPattern(pattern) {
|
|
|
47
47
|
return /[*?[\]]|(\*\*)/.test(pattern);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Check if a string is an HTTP/HTTPS URL
|
|
52
|
+
* @param {string} url - The string to check
|
|
53
|
+
* @returns {boolean} - True if the string starts with http:// or https://
|
|
54
|
+
*/
|
|
55
|
+
export function isHttp(url) {
|
|
56
|
+
if (typeof url !== "string") return false;
|
|
57
|
+
return url.startsWith("http://") || url.startsWith("https://");
|
|
58
|
+
}
|
|
59
|
+
|
|
50
60
|
export function processContent({ content }) {
|
|
51
61
|
// Match markdown regular links [text](link), exclude images 
|
|
52
62
|
return content.replace(/(?<!!)\[([^\]]+)\]\(([^)]+)\)/g, (match, text, link) => {
|
|
@@ -1112,7 +1122,7 @@ export async function resolveFileReferences(obj, basePath = process.cwd()) {
|
|
|
1112
1122
|
* @param {string} basePath - Base path for resolving relative paths
|
|
1113
1123
|
* @returns {Promise<any>} - The loaded content or original path if loading fails
|
|
1114
1124
|
*/
|
|
1115
|
-
async function loadFileContent(filePath, basePath) {
|
|
1125
|
+
export async function loadFileContent(filePath, basePath) {
|
|
1116
1126
|
try {
|
|
1117
1127
|
// Resolve path - if absolute, use as is; if relative, resolve from basePath
|
|
1118
1128
|
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(basePath, filePath);
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# Project information for documentation publishing
|
|
2
|
-
projectName: AIGNE DocSmith
|
|
3
|
-
projectDesc: AIGNE DocSmith is a powerful, AI-driven documentation generation tool built on the AIGNE Framework. It automates the creation of detailed, structured, and multi-language documentation directly from your source code.
|
|
4
|
-
projectLogo: https://docsmith.aigne.io/image-bin/uploads/9645caf64b4232699982c4d940b03b90.svg
|
|
5
|
-
|
|
6
|
-
# =============================================================================
|
|
7
|
-
# Documentation Configuration
|
|
8
|
-
# =============================================================================
|
|
9
|
-
|
|
10
|
-
# Purpose: What's the main outcome you want readers to achieve?
|
|
11
|
-
# Available options (uncomment and modify as needed):
|
|
12
|
-
# getStarted - Get started quickly: Help new users go from zero to working in <30 minutes
|
|
13
|
-
# completeTasks - Complete specific tasks: Guide users through common workflows and use cases
|
|
14
|
-
# findAnswers - Find answers fast: Provide searchable reference for all features and APIs
|
|
15
|
-
# understandSystem - Understand the system: Explain how it works, why design decisions were made
|
|
16
|
-
# solveProblems - Solve problems: Help users troubleshoot and fix issues
|
|
17
|
-
# mixedPurpose - Mix of above: Comprehensive documentation covering multiple needs
|
|
18
|
-
documentPurpose:
|
|
19
|
-
- getStarted
|
|
20
|
-
- completeTasks
|
|
21
|
-
|
|
22
|
-
# Target Audience: Who will be reading this most often?
|
|
23
|
-
# Available options (uncomment and modify as needed):
|
|
24
|
-
# endUsers - End users (non-technical): People who use the product but don't code
|
|
25
|
-
# developers - Developers integrating: Engineers adding this to their projects
|
|
26
|
-
# devops - DevOps/Infrastructure: Teams deploying, monitoring, maintaining systems
|
|
27
|
-
# decisionMakers - Technical decision makers: Architects, leads evaluating or planning implementation
|
|
28
|
-
# supportTeams - Support teams: People helping others use the product
|
|
29
|
-
# mixedTechnical - Mixed technical audience: Developers, DevOps, and technical users
|
|
30
|
-
targetAudienceTypes:
|
|
31
|
-
- endUsers
|
|
32
|
-
|
|
33
|
-
# Reader Knowledge Level: What do readers typically know when they arrive?
|
|
34
|
-
# Available options (uncomment and modify as needed):
|
|
35
|
-
# completeBeginners - Complete beginners: New to this domain/technology entirely
|
|
36
|
-
# domainFamiliar - Domain-familiar, tool-new: Know the problem space, new to this specific solution
|
|
37
|
-
# experiencedUsers - Experienced users: Regular users needing reference/advanced topics
|
|
38
|
-
# emergencyTroubleshooting - Emergency/troubleshooting: Something's broken, need to fix it quickly
|
|
39
|
-
# exploringEvaluating - Exploring/evaluating: Trying to understand if this fits their needs
|
|
40
|
-
readerKnowledgeLevel: completeBeginners
|
|
41
|
-
|
|
42
|
-
# Documentation Depth: How comprehensive should the documentation be?
|
|
43
|
-
# Available options (uncomment and modify as needed):
|
|
44
|
-
# essentialOnly - Essential only: Cover the 80% use cases, keep it concise
|
|
45
|
-
# balancedCoverage - Balanced coverage: Good depth with practical examples [RECOMMENDED]
|
|
46
|
-
# comprehensive - Comprehensive: Cover all features, edge cases, and advanced scenarios
|
|
47
|
-
# aiDecide - Let AI decide: Analyze code complexity and suggest appropriate depth
|
|
48
|
-
documentationDepth: comprehensive
|
|
49
|
-
|
|
50
|
-
# Custom Rules: Define specific documentation generation rules and requirements
|
|
51
|
-
rules: |
|
|
52
|
-
Avoid using vague or empty words that don't provide measurable or specific details, such as 'intelligently', 'seamlessly', 'comprehensive', or 'high-quality'. Focus on concrete, verifiable facts and information.
|
|
53
|
-
Focus on concrete, verifiable facts and information.
|
|
54
|
-
Must cover all subcommands of DocSmith
|
|
55
|
-
|
|
56
|
-
# Target Audience: Describe your specific target audience and their characteristics
|
|
57
|
-
targetAudience: |
|
|
58
|
-
|
|
59
|
-
locale: en
|
|
60
|
-
translateLanguages:
|
|
61
|
-
- zh
|
|
62
|
-
- zh-TW
|
|
63
|
-
- ja
|
|
64
|
-
docsDir: ./docs # Directory to save generated documentation
|
|
65
|
-
sourcesPath: # Source code paths to analyze
|
|
66
|
-
- ./README.md
|
|
67
|
-
- ./CHANGELOG.md
|
|
68
|
-
- ./aigne.yaml
|
|
69
|
-
- ./agents
|
|
70
|
-
- ./.aigne/doc-smith/config.yaml
|
|
71
|
-
- ./assets/screenshots
|
|
72
|
-
lastGitHead: f0db74dffd0876dab4cc3ad628523abd359c9430
|
|
73
|
-
# ⚠️ Warning: boardId is auto-generated by system, please do not edit manually
|
|
74
|
-
boardId: "docsmith"
|
|
75
|
-
appUrl: https://docsmith.aigne.io
|
|
76
|
-
# Checkout ID for document deployment service
|
|
77
|
-
checkoutId: ""
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
entries:
|
|
2
|
-
- timestamp: 2025-10-11T13:21:51.992Z
|
|
3
|
-
operation: translation_update
|
|
4
|
-
feedback: Do not translate the Target column in the Cleanup Targets table.
|
|
5
|
-
documentPath: /guides/cleaning-up
|
|
6
|
-
- timestamp: 2025-10-11T13:20:30.314Z
|
|
7
|
-
operation: document_update
|
|
8
|
-
feedback: The targets in Cleanup Targets are incomplete and need to be supplemented. The corresponding descriptions also require updating. Additionally, the target values should use the original enumeration values, such as 'generatedDocs'.
|
|
9
|
-
documentPath: /guides/cleaning-up
|
|
10
|
-
- timestamp: 2025-10-11T13:03:20.327Z
|
|
11
|
-
operation: document_update
|
|
12
|
-
feedback: The two aliases for the 'history' command in Viewing Update History can be combined into a single code block. The Short Hash in Understanding the History Output now consists of 8 characters. Additionally, operation types are separated by underscores, such as 'document_update'.
|
|
13
|
-
documentPath: /guides/managing-history
|
|
14
|
-
- timestamp: 2025-10-11T12:56:23.107Z
|
|
15
|
-
operation: document_update
|
|
16
|
-
feedback: In interactive mode, translated files are saved with a suffix appended to their original filenames within the same directory, rather than in dedicated language directories.
|
|
17
|
-
documentPath: /guides/translating-documentation
|
|
18
|
-
- timestamp: 2025-10-11T12:50:25.563Z
|
|
19
|
-
operation: document_update
|
|
20
|
-
feedback: The value of the 'docs' parameter in the demo should be a path separated by '-' rather than '/', and '.md' should be preserved.
|
|
21
|
-
documentPath: /guides/updating-documentation
|
|
22
|
-
- timestamp: 2025-10-11T12:46:37.507Z
|
|
23
|
-
operation: document_update
|
|
24
|
-
feedback: The value of the 'docs' parameter in the demo should be a path separated by '-' rather than '/'.
|
|
25
|
-
documentPath: /guides/updating-documentation
|
|
26
|
-
- timestamp: 2025-10-11T12:39:53.222Z
|
|
27
|
-
operation: document_update
|
|
28
|
-
feedback: The prompts in Review the Documentation Structure are outdated and need updating. Command Parameters also require updating.
|
|
29
|
-
documentPath: /guides/generating-documentation
|
|
30
|
-
- timestamp: 2025-10-11T12:26:24.598Z
|
|
31
|
-
operation: translation_update
|
|
32
|
-
feedback: AIGNE Framework is a proper noun and has its own link; no translation is required.
|
|
33
|
-
documentPath: /overview
|
|
34
|
-
- timestamp: 2025-10-11T12:24:05.477Z
|
|
35
|
-
operation: document_update
|
|
36
|
-
feedback: Add a link to the AIGNE Framework 'https://www.aigne.io/framework'.
|
|
37
|
-
documentPath: /overview
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
descriptions:
|
|
2
|
-
5838723847ec201191b002ef7d44937d92386a82755ca7a66374acff6b91325e:
|
|
3
|
-
path: ../assets/screenshots/doc-translate.png
|
|
4
|
-
description: This screenshot illustrates a user interface for document
|
|
5
|
-
translation. It displays options for selecting the source and target
|
|
6
|
-
languages, along with an area for document input or upload. The image
|
|
7
|
-
demonstrates the initial steps for translating a document within a
|
|
8
|
-
software application or web service.
|
|
9
|
-
generatedAt: 2025-10-13T10:16:56.300Z
|
|
10
|
-
ac51399fcd5ba2e36d7c84264dd28624acd10c57aa82f7d006da6f8434cb24de:
|
|
11
|
-
path: ../assets/screenshots/doc-regenerate.png
|
|
12
|
-
description: This screenshot displays a user interface element for a
|
|
13
|
-
'Regenerate' function, likely within an application or content management
|
|
14
|
-
system. It visually demonstrates how users can trigger the re-rendering or
|
|
15
|
-
updating of content, often showing a button or control and potentially the
|
|
16
|
-
immediate output or status of the regeneration process.
|
|
17
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
18
|
-
9871bff567cc5f1b73e99b84c03781bffc7f531635b9bd40f23a2aee5f9885e5:
|
|
19
|
-
path: ../assets/screenshots/doc-update.png
|
|
20
|
-
description: This image is a screenshot depicting a user interface for updating
|
|
21
|
-
documentation content. It showcases a main text editing area, likely with
|
|
22
|
-
rich text formatting capabilities, accompanied by buttons for actions such
|
|
23
|
-
as saving, previewing, or publishing changes. The layout suggests a
|
|
24
|
-
content management system or a wiki-style editing environment.
|
|
25
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
26
|
-
31353781ba6d1572359823faa399af9f5deca7b994f24939cb5f5143fcc96b14:
|
|
27
|
-
path: ../assets/screenshots/doc-translate-langs.png
|
|
28
|
-
description: This screenshot depicts a user interface element focused on
|
|
29
|
-
language selection for documentation translation. It displays a list or
|
|
30
|
-
menu of languages, allowing users to choose or configure the target
|
|
31
|
-
languages for translating documentation content. The image highlights the
|
|
32
|
-
functionality for managing multilingual documentation.
|
|
33
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
34
|
-
a42903e87ae020dcb81991e672b2a2990b94eb0e92d6c1cc87f3bf6223355344:
|
|
35
|
-
path: ../assets/screenshots/doc-publish.png
|
|
36
|
-
description: This is a screenshot of a "Publish Documentation" dialog box from a
|
|
37
|
-
user interface. It presents options for selecting documentation to publish
|
|
38
|
-
and configuring various publication settings, including checkboxes for
|
|
39
|
-
search indexing and versioning. The dialog features "Cancel" and "Publish"
|
|
40
|
-
action buttons at the bottom right.
|
|
41
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
42
|
-
c055a80de6c1120765757fd3ef91ef05718f77beb7d6dfdac41d8e234361a68a:
|
|
43
|
-
path: ../assets/screenshots/doc-generated-successfully.png
|
|
44
|
-
description: This is a screenshot of a success notification banner,
|
|
45
|
-
characterized by its wide and short dimensions. It displays a positive
|
|
46
|
-
message such as "Document generated successfully," likely accompanied by a
|
|
47
|
-
green checkmark or other visual cues indicating a successful operation.
|
|
48
|
-
This image is suitable for illustrating UI feedback when a document
|
|
49
|
-
generation process is completed.
|
|
50
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
51
|
-
f786c36289e0e5bfea866c9384edc7d44996c42adfad0cb6f613f46e27f0f2be:
|
|
52
|
-
path: ../assets/screenshots/doc-generate.png
|
|
53
|
-
description: This screenshot displays a "Generate Documentation" dialog,
|
|
54
|
-
presenting various options for outputting documentation files. Users can
|
|
55
|
-
specify an output path, choose to include example content, overwrite
|
|
56
|
-
existing files, and generate the documentation in dark mode, before
|
|
57
|
-
confirming with "Generate" or "Cancel."
|
|
58
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
59
|
-
2b41c70c6a61942727984b2d99010cbe7e1d9b4c75686f65af8b5a245e9b800d:
|
|
60
|
-
path: ../assets/screenshots/doc-generate-docs.png
|
|
61
|
-
description: This image is a screenshot illustrating a user interface for a
|
|
62
|
-
documentation generation process. It depicts a dialog or panel with
|
|
63
|
-
various configuration options and controls, likely including output format
|
|
64
|
-
selections and a prominent "Generate" button to initiate the creation of
|
|
65
|
-
documentation.
|
|
66
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
67
|
-
44cb2fc222a3dd15fa82f1088d9113b0bb1bfc8b29a0e568a2273d80e8f50a7d:
|
|
68
|
-
path: ../assets/screenshots/doc-complete-setup.png
|
|
69
|
-
description: This screenshot depicts the "Setup Complete" screen from a user
|
|
70
|
-
interface, indicating the successful conclusion of an installation or
|
|
71
|
-
configuration process. It features a prominent confirmation message, such
|
|
72
|
-
as "Setup Complete!", often accompanied by a success icon and an
|
|
73
|
-
actionable button like "Continue" or "Go to Dashboard" to proceed.
|
|
74
|
-
generatedAt: 2025-10-13T10:16:56.301Z
|
|
75
|
-
13a9073d16762909e189af4e53ceb004abe1c55681d12726fceb262205fbf180:
|
|
76
|
-
path: ../assets/screenshots/doc-generate.png
|
|
77
|
-
description: This screenshot displays a user interface for generating
|
|
78
|
-
documentation. It features various input fields and controls, likely for
|
|
79
|
-
configuring options such as output format, target location, and content
|
|
80
|
-
selection. The image serves to illustrate the steps or settings involved
|
|
81
|
-
in the documentation generation process.
|
|
82
|
-
generatedAt: 2025-10-13T14:07:35.096Z
|
|
83
|
-
90c0daa8347df01c8154b6a5b30879b691c4a94b49c970b0480435591603bf55:
|
|
84
|
-
path: ../assets/screenshots/doc-complete-setup.png
|
|
85
|
-
description: This image is a screenshot displaying a "Setup Complete" success
|
|
86
|
-
message within a user interface. It shows a clear green checkmark icon, a
|
|
87
|
-
bold headline confirming the setup is finished, and additional descriptive
|
|
88
|
-
text below. A prominent "Done" button is visible at the bottom of the
|
|
89
|
-
interface, indicating the next action for the user.
|
|
90
|
-
generatedAt: 2025-10-13T14:07:35.097Z
|
|
91
|
-
lastUpdated: 2025-10-13T14:07:35.098Z
|