@aigne/doc-smith 0.8.15-beta.8 → 0.8.15

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/agents/evaluate/document-structure.yaml +3 -1
  3. package/agents/evaluate/document.yaml +3 -1
  4. package/agents/evaluate/index.yaml +1 -3
  5. package/agents/generate/check-diagram.mjs +1 -1
  6. package/agents/generate/generate-structure.yaml +25 -71
  7. package/agents/generate/index.yaml +1 -2
  8. package/agents/generate/{merge-d2-diagram.yaml → merge-diagram.yaml} +7 -6
  9. package/agents/generate/update-document-structure.yaml +51 -45
  10. package/agents/generate/user-review-document-structure.mjs +3 -26
  11. package/agents/generate/utils/merge-document-structures.mjs +8 -32
  12. package/agents/init/check.mjs +1 -1
  13. package/agents/init/index.mjs +52 -2
  14. package/agents/init/validate.mjs +16 -0
  15. package/agents/publish/publish-docs.mjs +16 -10
  16. package/agents/schema/document-execution-structure.yaml +1 -1
  17. package/agents/schema/document-structure-item.yaml +1 -1
  18. package/agents/schema/document-structure-refine-item.yaml +20 -0
  19. package/agents/schema/document-structure.yaml +4 -2
  20. package/agents/update/batch-generate-document.yaml +1 -1
  21. package/agents/update/check-generate-diagram.mjs +84 -0
  22. package/agents/update/generate-diagram.yaml +0 -1
  23. package/agents/update/generate-document.yaml +4 -4
  24. package/agents/update/handle-document-update.yaml +9 -1
  25. package/agents/update/pre-check-generate-diagram.yaml +44 -0
  26. package/agents/update/update-document-detail.yaml +64 -58
  27. package/agents/update/update-single-document.yaml +1 -2
  28. package/agents/update/user-review-document.mjs +8 -6
  29. package/agents/utils/analyze-feedback-intent.yaml +29 -0
  30. package/agents/utils/choose-docs.mjs +16 -6
  31. package/agents/utils/find-item-by-path.mjs +4 -2
  32. package/agents/utils/load-sources.mjs +6 -6
  33. package/agents/utils/map-reasoning-effort-level.mjs +15 -0
  34. package/agents/utils/save-sidebar.mjs +12 -33
  35. package/agents/utils/{transform-detail-datasources.mjs → transform-detail-data-sources.mjs} +3 -3
  36. package/aigne.yaml +14 -3
  37. package/package.json +10 -9
  38. package/prompts/common/document/content-rules-core.md +6 -6
  39. package/prompts/common/document/openapi-usage-rules.md +36 -0
  40. package/prompts/common/document/role-and-personality.md +1 -2
  41. package/prompts/common/document-structure/conflict-resolution-guidance.md +2 -2
  42. package/prompts/common/document-structure/document-structure-rules.md +8 -8
  43. package/prompts/common/document-structure/output-constraints.md +3 -3
  44. package/prompts/detail/custom/custom-code-block.md +36 -1
  45. package/prompts/detail/custom/{custom-components.md → custom-components-usage-rules.md} +29 -7
  46. package/prompts/detail/d2-diagram/pre-check.md +23 -0
  47. package/prompts/detail/d2-diagram/rules.md +44 -29
  48. package/prompts/detail/d2-diagram/system-prompt.md +0 -14
  49. package/prompts/detail/d2-diagram/user-prompt.md +10 -1
  50. package/prompts/detail/generate/document-rules.md +3 -3
  51. package/prompts/detail/generate/system-prompt.md +2 -8
  52. package/prompts/detail/generate/user-prompt.md +13 -60
  53. package/prompts/detail/update/system-prompt.md +3 -8
  54. package/prompts/detail/update/user-prompt.md +9 -5
  55. package/prompts/evaluate/document.md +0 -4
  56. package/prompts/structure/check-document-structure.md +4 -4
  57. package/prompts/structure/generate/system-prompt.md +0 -1
  58. package/prompts/structure/generate/user-prompt.md +21 -18
  59. package/prompts/structure/review/structure-review-system.md +24 -16
  60. package/prompts/structure/update/system-prompt.md +0 -13
  61. package/prompts/structure/update/user-prompt.md +6 -5
  62. package/prompts/translate/translate-document.md +3 -3
  63. package/prompts/utils/analyze-feedback-intent.md +55 -0
  64. package/utils/constants/index.mjs +38 -0
  65. package/utils/deploy.mjs +3 -1
  66. package/utils/docs-finder-utils.mjs +37 -3
  67. package/utils/file-utils.mjs +97 -0
  68. package/utils/load-config.mjs +19 -0
@@ -4,12 +4,11 @@ import { pathExists } from "./file-utils.mjs";
4
4
 
5
5
  /**
6
6
  * Get action-specific text based on isTranslate flag
7
- * @param {boolean} isTranslate - Whether this is a translation action
8
7
  * @param {string} baseText - Base text template with {action} placeholder
8
+ * @param {string} action - doc action type
9
9
  * @returns {string} Text with action replaced
10
10
  */
11
- export function getActionText(isTranslate, baseText) {
12
- const action = isTranslate ? "translate" : "update";
11
+ export function getActionText(baseText, action) {
13
12
  return baseText.replace("{action}", action);
14
13
  }
15
14
 
@@ -324,3 +323,38 @@ export async function loadDocumentStructure(outputDir) {
324
323
  return null;
325
324
  }
326
325
  }
326
+
327
+ /**
328
+ * Build a tree structure from a flat document structure array using parentId
329
+ * @param {Array} documentStructure - Flat array of document structure items with path and parentId
330
+ * @returns {Object} Object containing rootNodes (array of root nodes) and nodeMap (Map for lookups)
331
+ */
332
+ export function buildDocumentTree(documentStructure) {
333
+ // Create a map of nodes for easy lookup
334
+ const nodeMap = new Map();
335
+ const rootNodes = [];
336
+
337
+ // First pass: create node map
338
+ documentStructure.forEach((node) => {
339
+ nodeMap.set(node.path, {
340
+ ...node,
341
+ children: [],
342
+ });
343
+ });
344
+
345
+ // Build the tree structure using parentId
346
+ documentStructure.forEach((node) => {
347
+ if (node.parentId) {
348
+ const parent = nodeMap.get(node.parentId);
349
+ if (parent) {
350
+ parent.children.push(nodeMap.get(node.path));
351
+ } else {
352
+ rootNodes.push(nodeMap.get(node.path));
353
+ }
354
+ } else {
355
+ rootNodes.push(nodeMap.get(node.path));
356
+ }
357
+ });
358
+
359
+ return { rootNodes, nodeMap };
360
+ }
@@ -13,6 +13,7 @@ import { debug } from "./debug.mjs";
13
13
  import { isGlobPattern } from "./utils.mjs";
14
14
  import { uploadFiles } from "./upload-files.mjs";
15
15
  import { extractApi } from "./extract-api.mjs";
16
+ import { minimatch } from "minimatch";
16
17
 
17
18
  /**
18
19
  * Check if a directory is inside a git repository using git command
@@ -859,3 +860,99 @@ export async function downloadAndUploadImage(imageUrl, docsDir, appUrl, accessTo
859
860
  return { url: imageUrl, downloadFinalPath: null };
860
861
  }
861
862
  }
863
+
864
+ /**
865
+ * Extract the path prefix from a glob pattern until the first glob character
866
+ */
867
+ export function getPathPrefix(pattern) {
868
+ const segments = pattern.split("/");
869
+ const result = [];
870
+
871
+ for (const segment of segments) {
872
+ if (isGlobPattern(segment)) {
873
+ break;
874
+ }
875
+ result.push(segment);
876
+ }
877
+
878
+ return result.join("/") || ".";
879
+ }
880
+
881
+ /**
882
+ * Check if a dir matches any exclude pattern
883
+ */
884
+ export function isDirExcluded(dir, excludePatterns) {
885
+ if (!dir || typeof dir !== "string") {
886
+ return false;
887
+ }
888
+
889
+ let normalizedDir = dir.replace(/\\/g, "/").replace(/^\.\/+/, "");
890
+ normalizedDir = normalizedDir.endsWith("/") ? normalizedDir : `${normalizedDir}/`;
891
+
892
+ for (const excludePattern of excludePatterns) {
893
+ if (minimatch(normalizedDir, excludePattern, { dot: true })) {
894
+ return true;
895
+ }
896
+ }
897
+
898
+ return false;
899
+ }
900
+
901
+ /**
902
+ * Return source paths that would be excluded by exclude patterns (files are skipped, directories use minimatch, glob patterns use path prefix heuristic)
903
+ */
904
+ export async function findInvalidSourcePaths(sourcePaths, excludePatterns) {
905
+ if (!Array.isArray(sourcePaths) || sourcePaths.length === 0) {
906
+ return [];
907
+ }
908
+
909
+ if (!Array.isArray(excludePatterns) || excludePatterns.length === 0) {
910
+ return [];
911
+ }
912
+
913
+ const invalidPaths = [];
914
+
915
+ for (const sourcePath of sourcePaths) {
916
+ if (typeof sourcePath !== "string" || !sourcePath) {
917
+ continue;
918
+ }
919
+
920
+ // Skip paths starting with "!" (exclusion patterns)
921
+ if (sourcePath.startsWith("!")) {
922
+ continue;
923
+ }
924
+
925
+ // Skip remote URLs
926
+ if (isRemoteFile(sourcePath)) {
927
+ continue;
928
+ }
929
+
930
+ // Check glob pattern: use heuristic algorithm
931
+ if (isGlobPattern(sourcePath)) {
932
+ const representativePath = getPathPrefix(sourcePath);
933
+ if (isDirExcluded(representativePath, excludePatterns)) {
934
+ invalidPaths.push(sourcePath);
935
+ }
936
+ continue;
937
+ }
938
+
939
+ try {
940
+ const stats = await stat(sourcePath);
941
+ // Skip file
942
+ if (stats.isFile()) {
943
+ continue;
944
+ }
945
+ // Check dir with minimatch
946
+ if (stats.isDirectory()) {
947
+ if (isDirExcluded(sourcePath, excludePatterns)) {
948
+ invalidPaths.push(sourcePath);
949
+ }
950
+ }
951
+ } catch {
952
+ // Path doesn't exist
953
+ invalidPaths.push(sourcePath);
954
+ }
955
+ }
956
+
957
+ return invalidPaths;
958
+ }
@@ -1,7 +1,10 @@
1
1
  import fs from "node:fs/promises";
2
+ import chalk from "chalk";
2
3
  import path from "node:path";
3
4
  import { parse } from "yaml";
4
5
  import { processConfigFields, resolveFileReferences } from "./utils.mjs";
6
+ import { DEFAULT_EXCLUDE_PATTERNS } from "./constants/index.mjs";
7
+ import { findInvalidSourcePaths, toDisplayPath } from "./file-utils.mjs";
5
8
 
6
9
  export default async function loadConfig({ config, appUrl }) {
7
10
  const configPath = path.isAbsolute(config) ? config : path.join(process.cwd(), config);
@@ -30,6 +33,22 @@ export default async function loadConfig({ config, appUrl }) {
30
33
  // Parse new configuration fields and convert keys to actual content
31
34
  const processedConfig = await processConfigFields(parsedConfig);
32
35
 
36
+ // Validate sourcePaths against exclude patterns
37
+ const sourcesPath = processedConfig.sourcesPath || parsedConfig.sourcesPath;
38
+ if (sourcesPath) {
39
+ const excludePatterns = [
40
+ ...DEFAULT_EXCLUDE_PATTERNS,
41
+ ...(processedConfig.excludePatterns || parsedConfig.excludePatterns || []),
42
+ ];
43
+
44
+ const invalidPaths = await findInvalidSourcePaths(sourcesPath, excludePatterns);
45
+ if (invalidPaths.length > 0) {
46
+ console.warn(
47
+ `⚠️ Some source paths have been excluded and will not be processed:\n${invalidPaths.map((p) => ` - ${chalk.yellow(p)}`).join("\n")}\n💡 Tip: You can remove these paths in ${toDisplayPath(configPath)}\n`,
48
+ );
49
+ }
50
+ }
51
+
33
52
  return {
34
53
  lastGitHead: parsedConfig.lastGitHead || "",
35
54
  ...parsedConfig,