@aigne/doc-smith 0.8.10 → 0.8.11-beta.1

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 (260) hide show
  1. package/.aigne/doc-smith/config.yaml +2 -0
  2. package/.aigne/doc-smith/output/structure-plan.json +3 -3
  3. package/.aigne/doc-smith/upload-cache.yaml +252 -0
  4. package/.github/workflows/create-release-pr.yaml +21 -0
  5. package/.github/workflows/publish-docs.yml +67 -0
  6. package/.github/workflows/release.yml +3 -7
  7. package/.release-please-manifest.json +1 -1
  8. package/CHANGELOG.md +22 -0
  9. package/README.md +48 -115
  10. package/RELEASE.md +1 -2
  11. package/agents/clear/choose-contents.mjs +170 -0
  12. package/agents/clear/clear-auth-tokens.mjs +111 -0
  13. package/agents/clear/clear-document-config.mjs +39 -0
  14. package/agents/clear/clear-document-structure.mjs +106 -0
  15. package/agents/clear/clear-generated-docs.mjs +51 -0
  16. package/agents/clear/index.yaml +23 -0
  17. package/agents/evaluate/code-snippet.mjs +93 -0
  18. package/agents/evaluate/document-structure.yaml +70 -0
  19. package/agents/evaluate/document.yaml +79 -0
  20. package/agents/evaluate/generate-report.mjs +78 -0
  21. package/agents/evaluate/index.yaml +39 -0
  22. package/agents/generate/document-structure-tools/add-document.mjs +56 -0
  23. package/agents/generate/document-structure-tools/delete-document.mjs +49 -0
  24. package/agents/generate/document-structure-tools/move-document.mjs +82 -0
  25. package/agents/generate/document-structure-tools/update-document.mjs +50 -0
  26. package/agents/generate/generate-structure.yaml +1 -1
  27. package/agents/generate/update-document-structure.yaml +42 -0
  28. package/agents/generate/user-review-document-structure.mjs +6 -4
  29. package/agents/init/index.mjs +1 -1
  30. package/agents/publish/publish-docs.mjs +12 -3
  31. package/agents/translate/choose-language.mjs +1 -1
  32. package/agents/update/batch-update-document.yaml +7 -0
  33. package/agents/update/check-update-is-single.mjs +38 -0
  34. package/agents/update/document-tools/update-document-content.mjs +293 -0
  35. package/agents/update/index.yaml +4 -10
  36. package/agents/update/update-document-detail.yaml +52 -0
  37. package/agents/update/update-single-document.yaml +15 -0
  38. package/agents/update/user-review-document.mjs +248 -0
  39. package/agents/utils/choose-docs.mjs +4 -2
  40. package/agents/utils/format-document-structure.mjs +12 -2
  41. package/agents/utils/load-document-all-content.mjs +84 -0
  42. package/agents/utils/load-sources.mjs +4 -1
  43. package/aigne.yaml +59 -20
  44. package/assets/report-template/report.html +198 -0
  45. package/biome.json +14 -2
  46. package/docs/advanced-how-it-works.ja.md +101 -0
  47. package/docs/advanced-how-it-works.zh-TW.md +101 -0
  48. package/docs/advanced-how-it-works.zh.md +20 -20
  49. package/docs/advanced-quality-assurance.ja.md +96 -0
  50. package/docs/advanced-quality-assurance.zh-TW.md +96 -0
  51. package/docs/advanced-quality-assurance.zh.md +18 -18
  52. package/docs/advanced.ja.md +16 -0
  53. package/docs/advanced.zh-TW.md +16 -0
  54. package/docs/advanced.zh.md +4 -4
  55. package/docs/changelog.ja.md +309 -0
  56. package/docs/changelog.zh-TW.md +309 -0
  57. package/docs/changelog.zh.md +23 -23
  58. package/docs/cli-reference.ja.md +210 -0
  59. package/docs/cli-reference.zh-TW.md +210 -0
  60. package/docs/cli-reference.zh.md +21 -21
  61. package/docs/configuration-interactive-setup.ja.md +135 -0
  62. package/docs/configuration-interactive-setup.zh-TW.md +135 -0
  63. package/docs/configuration-interactive-setup.zh.md +29 -29
  64. package/docs/configuration-language-support.ja.md +94 -0
  65. package/docs/configuration-language-support.zh-TW.md +94 -0
  66. package/docs/configuration-language-support.zh.md +13 -13
  67. package/docs/configuration-llm-setup.ja.md +54 -0
  68. package/docs/configuration-llm-setup.zh-TW.md +54 -0
  69. package/docs/configuration-llm-setup.zh.md +12 -12
  70. package/docs/configuration-preferences.ja.md +129 -0
  71. package/docs/configuration-preferences.zh-TW.md +129 -0
  72. package/docs/configuration-preferences.zh.md +36 -36
  73. package/docs/configuration.ja.md +172 -0
  74. package/docs/configuration.zh-TW.md +172 -0
  75. package/docs/configuration.zh.md +49 -49
  76. package/docs/features-generate-documentation.ja.md +101 -0
  77. package/docs/features-generate-documentation.zh-TW.md +101 -0
  78. package/docs/features-generate-documentation.zh.md +17 -17
  79. package/docs/features-publish-your-docs.ja.md +107 -0
  80. package/docs/features-publish-your-docs.zh-TW.md +107 -0
  81. package/docs/features-publish-your-docs.zh.md +22 -22
  82. package/docs/features-translate-documentation.ja.md +79 -0
  83. package/docs/features-translate-documentation.zh-TW.md +79 -0
  84. package/docs/features-translate-documentation.zh.md +12 -12
  85. package/docs/features-update-and-refine.ja.md +138 -0
  86. package/docs/features-update-and-refine.zh-TW.md +138 -0
  87. package/docs/features-update-and-refine.zh.md +21 -21
  88. package/docs/features.ja.md +52 -0
  89. package/docs/features.zh-TW.md +52 -0
  90. package/docs/features.zh.md +8 -8
  91. package/docs/getting-started.ja.md +123 -0
  92. package/docs/getting-started.zh-TW.md +123 -0
  93. package/docs/getting-started.zh.md +24 -24
  94. package/docs/overview.ja.md +30 -0
  95. package/docs/overview.zh-TW.md +30 -0
  96. package/docs/overview.zh.md +8 -8
  97. package/package.json +19 -11
  98. package/prompts/common/document/content-rules-core.md +19 -0
  99. package/prompts/common/document/media-handling-rules.md +9 -0
  100. package/prompts/common/document/role-and-personality.md +15 -0
  101. package/prompts/common/document/user-preferences.md +9 -0
  102. package/prompts/common/document-structure/conflict-resolution-guidance.md +16 -0
  103. package/prompts/common/document-structure/document-structure-rules.md +45 -0
  104. package/prompts/common/document-structure/glossary.md +7 -0
  105. package/prompts/common/document-structure/intj-traits.md +5 -0
  106. package/prompts/common/document-structure/output-constraints.md +9 -0
  107. package/prompts/common/document-structure/user-locale-rules.md +10 -0
  108. package/prompts/common/document-structure/user-preferences.md +9 -0
  109. package/prompts/detail/custom/custom-components.md +9 -1
  110. package/prompts/detail/document-rules.md +6 -6
  111. package/prompts/detail/generate-document.md +5 -45
  112. package/prompts/detail/update-document.md +145 -0
  113. package/prompts/evaluate/document-structure.md +94 -0
  114. package/prompts/evaluate/document.md +149 -0
  115. package/prompts/structure/document-rules.md +1 -1
  116. package/prompts/structure/generate-structure-system.md +74 -0
  117. package/prompts/structure/generate-structure-user.md +41 -0
  118. package/prompts/structure/update-document-structure.md +118 -0
  119. package/prompts/translate/translate-document.md +1 -1
  120. package/prompts/utils/feedback-refiner.md +3 -3
  121. package/release-please-config.json +4 -3
  122. package/tests/agents/clear/choose-contents.test.mjs +280 -0
  123. package/tests/agents/clear/clear-auth-tokens.test.mjs +268 -0
  124. package/tests/agents/clear/clear-document-config.test.mjs +167 -0
  125. package/tests/agents/clear/clear-document-structure.test.mjs +374 -0
  126. package/tests/agents/clear/clear-generated-docs.test.mjs +222 -0
  127. package/tests/agents/evaluate/code-snippet.test.mjs +163 -0
  128. package/tests/agents/evaluate/fixtures/api-services.md +87 -0
  129. package/tests/agents/evaluate/fixtures/js-sdk.md +94 -0
  130. package/tests/agents/evaluate/generate-report.test.mjs +312 -0
  131. package/tests/agents/generate/check-document-structure.test.mjs +0 -6
  132. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +449 -0
  133. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +410 -0
  134. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +476 -0
  135. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +548 -0
  136. package/tests/agents/generate/generate-structure.test.mjs +0 -6
  137. package/tests/agents/generate/user-review-document-structure.test.mjs +9 -9
  138. package/tests/agents/publish/publish-docs.test.mjs +2 -2
  139. package/tests/agents/update/check-update-is-single.test.mjs +300 -0
  140. package/tests/agents/update/document-tools/update-document-content.test.mjs +326 -0
  141. package/tests/agents/update/user-review-document.test.mjs +561 -0
  142. package/tests/agents/utils/format-document-structure.test.mjs +100 -0
  143. package/tests/utils/auth-utils.test.mjs +239 -1
  144. package/tests/utils/blocklet.test.mjs +9 -7
  145. package/tests/utils/constants.test.mjs +1 -1
  146. package/tests/utils/d2-utils.test.mjs +1 -1
  147. package/tests/utils/deploy.test.mjs +310 -366
  148. package/tests/utils/kroki-utils.test.mjs +2 -15
  149. package/tests/utils/linter/fixtures/css/keyword-error.css +1 -0
  150. package/tests/utils/linter/fixtures/css/missing-semicolon.css +1 -0
  151. package/tests/utils/linter/fixtures/css/syntax-error.css +1 -0
  152. package/tests/utils/linter/fixtures/css/undeclare-variable.css +1 -0
  153. package/tests/utils/linter/fixtures/css/unused-variable.css +2 -0
  154. package/tests/utils/linter/fixtures/css/valid-code.css +1 -0
  155. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +1 -0
  156. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +2 -0
  157. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +2 -0
  158. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +1 -0
  159. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +1 -0
  160. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +2 -0
  161. package/tests/utils/linter/fixtures/go/keyword-error.go +5 -0
  162. package/tests/utils/linter/fixtures/go/missing-semicolon.go +5 -0
  163. package/tests/utils/linter/fixtures/go/syntax-error.go +6 -0
  164. package/tests/utils/linter/fixtures/go/undeclare-variable.go +5 -0
  165. package/tests/utils/linter/fixtures/go/unused-variable.go +5 -0
  166. package/tests/utils/linter/fixtures/go/valid-code.go +7 -0
  167. package/tests/utils/linter/fixtures/js/keyword-error.js +3 -0
  168. package/tests/utils/linter/fixtures/js/missing-semicolon.js +6 -0
  169. package/tests/utils/linter/fixtures/js/syntax-error.js +4 -0
  170. package/tests/utils/linter/fixtures/js/undeclare-variable.js +3 -0
  171. package/tests/utils/linter/fixtures/js/unused-variable.js +7 -0
  172. package/tests/utils/linter/fixtures/js/valid-code.js +15 -0
  173. package/tests/utils/linter/fixtures/json/keyword-error.json +1 -0
  174. package/tests/utils/linter/fixtures/json/missing-semicolon.json +1 -0
  175. package/tests/utils/linter/fixtures/json/syntax-error.json +1 -0
  176. package/tests/utils/linter/fixtures/json/undeclare-variable.json +1 -0
  177. package/tests/utils/linter/fixtures/json/unused-variable.json +1 -0
  178. package/tests/utils/linter/fixtures/json/valid-code.json +1 -0
  179. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +5 -0
  180. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +5 -0
  181. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +5 -0
  182. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +5 -0
  183. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +4 -0
  184. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +5 -0
  185. package/tests/utils/linter/fixtures/python/keyword-error.py +3 -0
  186. package/tests/utils/linter/fixtures/python/missing-semicolon.py +2 -0
  187. package/tests/utils/linter/fixtures/python/syntax-error.py +3 -0
  188. package/tests/utils/linter/fixtures/python/undeclare-variable.py +3 -0
  189. package/tests/utils/linter/fixtures/python/unused-variable.py +6 -0
  190. package/tests/utils/linter/fixtures/python/valid-code.py +12 -0
  191. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +2 -0
  192. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +1 -0
  193. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +2 -0
  194. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +1 -0
  195. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +2 -0
  196. package/tests/utils/linter/fixtures/ruby/valid-code.rb +1 -0
  197. package/tests/utils/linter/fixtures/sass/keyword-error.sass +2 -0
  198. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +3 -0
  199. package/tests/utils/linter/fixtures/sass/syntax-error.sass +3 -0
  200. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +2 -0
  201. package/tests/utils/linter/fixtures/sass/unused-variable.sass +4 -0
  202. package/tests/utils/linter/fixtures/sass/valid-code.sass +2 -0
  203. package/tests/utils/linter/fixtures/scss/keyword-error.scss +1 -0
  204. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +1 -0
  205. package/tests/utils/linter/fixtures/scss/syntax-error.scss +1 -0
  206. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +1 -0
  207. package/tests/utils/linter/fixtures/scss/unused-variable.scss +2 -0
  208. package/tests/utils/linter/fixtures/scss/valid-code.scss +1 -0
  209. package/tests/utils/linter/fixtures/shell/keyword-error.sh +5 -0
  210. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +3 -0
  211. package/tests/utils/linter/fixtures/shell/syntax-error.sh +4 -0
  212. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +3 -0
  213. package/tests/utils/linter/fixtures/shell/unused-variable.sh +4 -0
  214. package/tests/utils/linter/fixtures/shell/valid-code.sh +3 -0
  215. package/tests/utils/linter/fixtures/ts/keyword-error.ts +1 -0
  216. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +1 -0
  217. package/tests/utils/linter/fixtures/ts/syntax-error.ts +1 -0
  218. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +1 -0
  219. package/tests/utils/linter/fixtures/ts/unused-variable.ts +3 -0
  220. package/tests/utils/linter/fixtures/ts/valid-code.ts +3 -0
  221. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +5 -0
  222. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +5 -0
  223. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +5 -0
  224. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +6 -0
  225. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +6 -0
  226. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +5 -0
  227. package/tests/utils/linter/fixtures/vue/keyword-error.vue +6 -0
  228. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +6 -0
  229. package/tests/utils/linter/fixtures/vue/syntax-error.vue +6 -0
  230. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +6 -0
  231. package/tests/utils/linter/fixtures/vue/unused-variable.vue +7 -0
  232. package/tests/utils/linter/fixtures/vue/valid-code.vue +6 -0
  233. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +1 -0
  234. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +2 -0
  235. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +1 -0
  236. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +1 -0
  237. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +2 -0
  238. package/tests/utils/linter/fixtures/yaml/valid-code.yml +3 -0
  239. package/tests/utils/linter/index.test.mjs +440 -0
  240. package/tests/utils/linter/scan-results.mjs +42 -0
  241. package/tests/utils/markdown/index.test.mjs +478 -0
  242. package/tests/utils/mermaid-validator.test.mjs +2 -2
  243. package/tests/utils/utils.test.mjs +3 -1
  244. package/types/document-schema.mjs +54 -0
  245. package/types/document-structure-schema.mjs +244 -0
  246. package/utils/auth-utils.mjs +131 -6
  247. package/utils/conflict-detector.mjs +5 -1
  248. package/utils/{constants.mjs → constants/index.mjs} +109 -0
  249. package/utils/constants/linter.mjs +102 -0
  250. package/utils/d2-utils.mjs +2 -4
  251. package/utils/debug.mjs +3 -0
  252. package/utils/deploy.mjs +81 -385
  253. package/utils/evaluate/report-utils.mjs +131 -0
  254. package/utils/file-utils.mjs +36 -1
  255. package/utils/kroki-utils.mjs +1 -1
  256. package/utils/linter/index.mjs +50 -0
  257. package/utils/markdown/index.mjs +26 -0
  258. package/utils/markdown-checker.mjs +1 -1
  259. package/utils/utils.mjs +19 -7
  260. package/prompts/structure/generate-structure.md +0 -161
@@ -0,0 +1,244 @@
1
+ import { z } from "zod";
2
+ import { zodToJsonSchema } from "zod-to-json-schema";
3
+
4
+ // Document item schema - represents a single document in the structure
5
+ export const documentItemSchema = z.object({
6
+ title: z.string().min(1, "Title is required"),
7
+ description: z.string().min(1, "Description is required"),
8
+ path: z.string().startsWith("/", 'Path must start with "/"'),
9
+ parentId: z.string().nullable(),
10
+ sourceIds: z.array(z.string()).min(1, "At least one source ID is required"),
11
+ });
12
+
13
+ // Document structure schema - represents the entire document structure array
14
+ export const documentStructureSchema = z.array(documentItemSchema);
15
+
16
+ // Add document schemas
17
+ export const addDocumentInputSchema = z.object({
18
+ documentStructure: documentStructureSchema,
19
+ title: z.string().min(1, "Title is required"),
20
+ description: z.string().min(1, "Description is required"),
21
+ path: z.string().startsWith("/", 'Path must start with "/"'),
22
+ parentId: z.string().nullable().optional(),
23
+ sourceIds: z.array(z.string()).min(1, "At least one source ID is required"),
24
+ });
25
+
26
+ export const addDocumentOutputSchema = z.object({
27
+ documentStructure: documentStructureSchema,
28
+ addedDocument: documentItemSchema.optional(),
29
+ });
30
+
31
+ // Delete document schemas
32
+ export const deleteDocumentInputSchema = z.object({
33
+ documentStructure: documentStructureSchema,
34
+ path: z.string().min(1, "Path is required"),
35
+ });
36
+
37
+ export const deleteDocumentOutputSchema = z.object({
38
+ documentStructure: documentStructureSchema,
39
+ deletedDocument: documentItemSchema.optional(),
40
+ });
41
+
42
+ // Move document schemas
43
+ export const moveDocumentInputSchema = z.object({
44
+ documentStructure: documentStructureSchema,
45
+ path: z.string().min(1, "Path is required"),
46
+ newParentId: z.string().nullable().optional(),
47
+ });
48
+
49
+ export const moveDocumentOutputSchema = z.object({
50
+ documentStructure: documentStructureSchema,
51
+ originalDocument: documentItemSchema.optional(),
52
+ updatedDocument: documentItemSchema.optional(),
53
+ });
54
+
55
+ // Update document schemas
56
+ export const updateDocumentInputSchema = z
57
+ .object({
58
+ documentStructure: documentStructureSchema,
59
+ path: z.string().min(1, "Path is required"),
60
+ title: z.string().min(1).optional(),
61
+ description: z.string().min(1).optional(),
62
+ sourceIds: z.array(z.string()).min(1).optional(),
63
+ })
64
+ .refine(
65
+ (data) =>
66
+ data.title !== undefined || data.description !== undefined || data.sourceIds !== undefined,
67
+ {
68
+ message: "At least one field (title, description, or sourceIds) must be provided for update",
69
+ },
70
+ );
71
+
72
+ export const updateDocumentOutputSchema = z.object({
73
+ documentStructure: documentStructureSchema,
74
+ originalDocument: documentItemSchema.optional(),
75
+ updatedDocument: documentItemSchema.optional(),
76
+ });
77
+
78
+ // JSON Schema conversion functions using zodToJsonSchema
79
+ export const getAddDocumentInputJsonSchema = () => {
80
+ const schema = zodToJsonSchema(addDocumentInputSchema);
81
+ // Add custom descriptions
82
+ if (schema.properties) {
83
+ schema.properties.documentStructure.description = "Current document structure array";
84
+ schema.properties.title.description = "Title of the new document";
85
+ schema.properties.description.description = "Description of the new document";
86
+ schema.properties.path.description = "URL path for the new document (must start with '/')";
87
+ schema.properties.parentId.description =
88
+ "Parent document path (leave empty for top-level documents)";
89
+ schema.properties.sourceIds.description =
90
+ "Source references from associated data sources (required)";
91
+ }
92
+ return schema;
93
+ };
94
+
95
+ export const getAddDocumentOutputJsonSchema = () => {
96
+ const schema = zodToJsonSchema(addDocumentOutputSchema);
97
+ if (schema.properties) {
98
+ schema.properties.documentStructure.description =
99
+ "Updated document structure array with the new document added";
100
+ schema.properties.addedDocument.description = "The newly added document object";
101
+ }
102
+ return schema;
103
+ };
104
+
105
+ export const getDeleteDocumentInputJsonSchema = () => {
106
+ const schema = zodToJsonSchema(deleteDocumentInputSchema);
107
+ if (schema.properties) {
108
+ schema.properties.documentStructure.description = "Current document structure array";
109
+ schema.properties.path.description = "URL path of the document to delete";
110
+ }
111
+ return schema;
112
+ };
113
+
114
+ export const getDeleteDocumentOutputJsonSchema = () => {
115
+ const schema = zodToJsonSchema(deleteDocumentOutputSchema);
116
+ if (schema.properties) {
117
+ schema.properties.documentStructure.description =
118
+ "Updated document structure array with the document removed";
119
+ schema.properties.deletedDocument.description = "The deleted document object";
120
+ }
121
+ return schema;
122
+ };
123
+
124
+ export const getMoveDocumentInputJsonSchema = () => {
125
+ const schema = zodToJsonSchema(moveDocumentInputSchema);
126
+ if (schema.properties) {
127
+ schema.properties.documentStructure.description = "Current document structure array";
128
+ schema.properties.path.description = "URL path of the document to move";
129
+ schema.properties.newParentId.description =
130
+ "Path of the new parent document (leave empty for top-level)";
131
+ }
132
+ return schema;
133
+ };
134
+
135
+ export const getMoveDocumentOutputJsonSchema = () => {
136
+ const schema = zodToJsonSchema(moveDocumentOutputSchema);
137
+ if (schema.properties) {
138
+ schema.properties.documentStructure.description =
139
+ "Updated document structure array with the document moved";
140
+ schema.properties.originalDocument.description = "The original document object before moving";
141
+ schema.properties.updatedDocument.description = "The updated document object after moving";
142
+ }
143
+ return schema;
144
+ };
145
+
146
+ export const getUpdateDocumentInputJsonSchema = () => {
147
+ const schema = zodToJsonSchema(updateDocumentInputSchema);
148
+ if (schema.properties) {
149
+ schema.properties.documentStructure.description = "Current document structure array";
150
+ schema.properties.path.description = "URL path of the document to update";
151
+ schema.properties.title.description = "New title for the document (optional)";
152
+ schema.properties.description.description = "New description for the document (optional)";
153
+ schema.properties.sourceIds.description =
154
+ "New source references for the document (optional, cannot be empty if provided)";
155
+ }
156
+ // Add anyOf constraint for at least one update field
157
+ schema.anyOf = [
158
+ { required: ["title"] },
159
+ { required: ["description"] },
160
+ { required: ["sourceIds"] },
161
+ ];
162
+ return schema;
163
+ };
164
+
165
+ export const getUpdateDocumentOutputJsonSchema = () => {
166
+ const schema = zodToJsonSchema(updateDocumentOutputSchema);
167
+ if (schema.properties) {
168
+ schema.properties.documentStructure.description =
169
+ "Updated document structure array with the document modified";
170
+ schema.properties.originalDocument.description = "The original document object before update";
171
+ schema.properties.updatedDocument.description =
172
+ "The updated document object after modification";
173
+ }
174
+ return schema;
175
+ };
176
+
177
+ // Validation helper functions
178
+ export const validateAddDocumentInput = (input) => {
179
+ try {
180
+ return {
181
+ success: true,
182
+ data: addDocumentInputSchema.parse(input),
183
+ };
184
+ } catch (error) {
185
+ return {
186
+ success: false,
187
+ error:
188
+ error.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join(", ") ||
189
+ error.message,
190
+ };
191
+ }
192
+ };
193
+
194
+ export const validateDeleteDocumentInput = (input) => {
195
+ try {
196
+ return {
197
+ success: true,
198
+ data: deleteDocumentInputSchema.parse(input),
199
+ };
200
+ } catch (error) {
201
+ return {
202
+ success: false,
203
+ error:
204
+ error.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join(", ") ||
205
+ error.message,
206
+ };
207
+ }
208
+ };
209
+
210
+ export const validateMoveDocumentInput = (input) => {
211
+ try {
212
+ return {
213
+ success: true,
214
+ data: moveDocumentInputSchema.parse(input),
215
+ };
216
+ } catch (error) {
217
+ return {
218
+ success: false,
219
+ error:
220
+ error.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join(", ") ||
221
+ error.message,
222
+ };
223
+ }
224
+ };
225
+
226
+ export const validateUpdateDocumentInput = (input) => {
227
+ try {
228
+ return {
229
+ success: true,
230
+ data: updateDocumentInputSchema.parse(input),
231
+ };
232
+ } catch (error) {
233
+ return {
234
+ success: false,
235
+ error:
236
+ error.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join(", ") ||
237
+ error.message,
238
+ };
239
+ }
240
+ };
241
+
242
+ // Type inference helpers for better IDE support
243
+ export const createDocumentItem = (data) => documentItemSchema.parse(data);
244
+ export const createDocumentStructure = (data) => documentStructureSchema.parse(data);
@@ -7,6 +7,7 @@ import chalk from "chalk";
7
7
  import open from "open";
8
8
  import { joinURL } from "ufo";
9
9
  import { parse, stringify } from "yaml";
10
+
10
11
  import {
11
12
  ComponentNotFoundError,
12
13
  getComponentMountPoint,
@@ -16,7 +17,8 @@ import {
16
17
  BLOCKLET_ADD_COMPONENT_DOCS,
17
18
  DISCUSS_KIT_DID,
18
19
  DISCUSS_KIT_STORE_URL,
19
- } from "./constants.mjs";
20
+ DOC_OFFICIAL_ACCESS_TOKEN,
21
+ } from "./constants/index.mjs";
20
22
 
21
23
  const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
22
24
 
@@ -37,8 +39,9 @@ export async function getAccessToken(appUrl, ltToken = "") {
37
39
  if (existsSync(DOC_SMITH_ENV_FILE)) {
38
40
  const data = await readFile(DOC_SMITH_ENV_FILE, "utf8");
39
41
  if (data.includes("DOC_DISCUSS_KIT_ACCESS_TOKEN")) {
40
- const envs = parse(data);
41
- if (envs[hostname]?.DOC_DISCUSS_KIT_ACCESS_TOKEN) {
42
+ // Handle empty or invalid YAML files
43
+ const envs = data.trim() ? parse(data) : null;
44
+ if (envs?.[hostname]?.DOC_DISCUSS_KIT_ACCESS_TOKEN) {
42
45
  accessToken = envs[hostname].DOC_DISCUSS_KIT_ACCESS_TOKEN;
43
46
  }
44
47
  }
@@ -111,9 +114,12 @@ export async function getAccessToken(appUrl, ltToken = "") {
111
114
  mkdirSync(aigneDir, { recursive: true });
112
115
  }
113
116
 
114
- const existingConfig = existsSync(DOC_SMITH_ENV_FILE)
115
- ? parse(await readFile(DOC_SMITH_ENV_FILE, "utf8"))
116
- : {};
117
+ let existingConfig = {};
118
+ if (existsSync(DOC_SMITH_ENV_FILE)) {
119
+ const fileContent = await readFile(DOC_SMITH_ENV_FILE, "utf8");
120
+ const parsedConfig = fileContent.trim() ? parse(fileContent) : null;
121
+ existingConfig = parsedConfig || {};
122
+ }
117
123
 
118
124
  await writeFile(
119
125
  DOC_SMITH_ENV_FILE,
@@ -134,3 +140,122 @@ export async function getAccessToken(appUrl, ltToken = "") {
134
140
 
135
141
  return accessToken;
136
142
  }
143
+
144
+ /**
145
+ * Get official access token from environment, config file, or prompt user for authorization.
146
+ * @param {string} baseUrl - The official service URL
147
+ * @returns {Promise<string>} - The access token
148
+ */
149
+ export async function getOfficialAccessToken(baseUrl) {
150
+ // Early parameter validation
151
+ if (!baseUrl) {
152
+ throw new Error("baseUrl parameter is required for getOfficialAccessToken.");
153
+ }
154
+
155
+ // Parse URL once and reuse
156
+ const urlObj = new URL(baseUrl);
157
+ const { hostname, origin } = urlObj;
158
+ const DOC_SMITH_ENV_FILE = join(homedir(), ".aigne", "doc-smith-connected.yaml");
159
+
160
+ // 1. Check environment variable
161
+ let accessToken = process.env[DOC_OFFICIAL_ACCESS_TOKEN];
162
+
163
+ // 2. Check config file if not in env
164
+ if (!accessToken) {
165
+ try {
166
+ if (existsSync(DOC_SMITH_ENV_FILE)) {
167
+ const data = await readFile(DOC_SMITH_ENV_FILE, "utf8");
168
+ // Handle empty or invalid YAML files
169
+ const envs = data.trim() ? parse(data) : null;
170
+ if (envs) {
171
+ accessToken = envs[hostname]?.[DOC_OFFICIAL_ACCESS_TOKEN];
172
+ }
173
+ }
174
+ } catch (_error) {
175
+ // ignore
176
+ }
177
+ }
178
+
179
+ // If token is found, return it
180
+ if (accessToken) {
181
+ return accessToken;
182
+ }
183
+
184
+ // Generate new access token
185
+ const connectUrl = joinURL(origin, WELLKNOWN_SERVICE_PATH_PREFIX);
186
+
187
+ try {
188
+ const result = await createConnect({
189
+ connectUrl,
190
+ connectAction: "gen-simple-access-key",
191
+ source: "AIGNE DocSmith connect to official service",
192
+ closeOnSuccess: true,
193
+ appName: "AIGNE DocSmith",
194
+ appLogo: "https://docsmith.aigne.io/image-bin/uploads/9645caf64b4232699982c4d940b03b90.svg",
195
+ openPage: (pageUrl) => {
196
+ console.log(
197
+ "🔗 Please open this URL in your browser to authorize access: ",
198
+ chalk.cyan(pageUrl),
199
+ "\n",
200
+ );
201
+ open(pageUrl);
202
+ },
203
+ });
204
+
205
+ accessToken = result.accessKeySecret;
206
+ process.env[DOC_OFFICIAL_ACCESS_TOKEN] = accessToken;
207
+
208
+ // Save the access token to config file
209
+ await saveTokenToConfigFile(
210
+ DOC_SMITH_ENV_FILE,
211
+ hostname,
212
+ DOC_OFFICIAL_ACCESS_TOKEN,
213
+ accessToken,
214
+ );
215
+ } catch (error) {
216
+ console.debug(error);
217
+ throw new Error(
218
+ "Failed to obtain official access token. Please check your network connection and try again later.",
219
+ );
220
+ }
221
+
222
+ return accessToken;
223
+ }
224
+
225
+ /**
226
+ * Helper function to save access token to config file
227
+ * @param {string} configFile - Path to config file
228
+ * @param {string} hostname - Hostname key
229
+ * @param {string} tokenKey - Token key name
230
+ * @param {string} tokenValue - Token value
231
+ */
232
+ async function saveTokenToConfigFile(configFile, hostname, tokenKey, tokenValue) {
233
+ try {
234
+ const aigneDir = join(homedir(), ".aigne");
235
+ if (!existsSync(aigneDir)) {
236
+ mkdirSync(aigneDir, { recursive: true });
237
+ }
238
+
239
+ let existingConfig = {};
240
+ if (existsSync(configFile)) {
241
+ const fileContent = await readFile(configFile, "utf8");
242
+ // Handle empty or invalid YAML files
243
+ const parsedConfig = fileContent.trim() ? parse(fileContent) : null;
244
+ existingConfig = parsedConfig || {};
245
+ }
246
+
247
+ await writeFile(
248
+ configFile,
249
+ stringify({
250
+ ...existingConfig,
251
+ [hostname]: {
252
+ ...existingConfig[hostname],
253
+ [tokenKey]: tokenValue,
254
+ },
255
+ }),
256
+ );
257
+ } catch (error) {
258
+ console.warn(`Failed to save token to config file ${configFile}: ${error.message}`, error);
259
+ // Don't throw here, as the token is already obtained and set in env
260
+ }
261
+ }
@@ -1,4 +1,8 @@
1
- import { CONFLICT_RESOLUTION_RULES, CONFLICT_RULES, RESOLUTION_STRATEGIES } from "./constants.mjs";
1
+ import {
2
+ CONFLICT_RESOLUTION_RULES,
3
+ CONFLICT_RULES,
4
+ RESOLUTION_STRATEGIES,
5
+ } from "./constants/index.mjs";
2
6
 
3
7
  /**
4
8
  * Get filtered options based on cross-question conflict rules
@@ -332,6 +332,8 @@ export const DISCUSS_KIT_DID = "z8ia1WEiBZ7hxURf6LwH21Wpg99vophFwSJdu";
332
332
 
333
333
  export const PAYMENT_KIT_DID = "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk";
334
334
 
335
+ export const DOC_OFFICIAL_ACCESS_TOKEN = "DOC_OFFICIAL_ACCESS_TOKEN";
336
+
335
337
  // Discuss Kit related URLs
336
338
  export const DISCUSS_KIT_STORE_URL =
337
339
  "https://store.blocklet.dev/blocklets/z8ia1WEiBZ7hxURf6LwH21Wpg99vophFwSJdu";
@@ -540,3 +542,110 @@ export const TMP_DIR = ".tmp";
540
542
  export const TMP_DOCS_DIR = "docs";
541
543
 
542
544
  export const TMP_ASSETS_DIR = "assets";
545
+
546
+ // Default evaluation scoring weights
547
+ export const DEFAULT_EVALUATION_WEIGHTS = {
548
+ evaluationConfig: {
549
+ accuracy: {
550
+ weight: 0.35,
551
+ description: "Technical correctness of the documentation.",
552
+ subDimensions: {
553
+ signatureConsistency: {
554
+ weight: 0.5,
555
+ description:
556
+ "Function signatures match the source code (e.g., OpenAPI spec, TypeScript types).",
557
+ },
558
+ linkValidity: {
559
+ weight: 0.25,
560
+ description: "No broken internal links or invalid cross-references.",
561
+ },
562
+ codeExampleIntegrity: {
563
+ weight: 0.25,
564
+ description:
565
+ "All code blocks are syntactically valid and labeled with the correct language.",
566
+ },
567
+ },
568
+ },
569
+ coverage: {
570
+ weight: 0.35,
571
+ description: "Completeness of documentation for all public components.",
572
+ subDimensions: {
573
+ apiCoverage: {
574
+ weight: 0.4,
575
+ description: "Percentage of exported functions/classes documented.",
576
+ },
577
+ paramReturnCoverage: {
578
+ weight: 0.3,
579
+ description: "Percentage of function parameters and return values described.",
580
+ },
581
+ changeTracking: {
582
+ weight: 0.3,
583
+ description:
584
+ "All new or modified code since the last commit is reflected in the documentation.",
585
+ },
586
+ },
587
+ },
588
+ readability: {
589
+ weight: 0.15,
590
+ description: "Ease of understanding for human readers.",
591
+ subDimensions: {
592
+ clarityScore: {
593
+ weight: 0.28,
594
+ description:
595
+ "Overall clarity including reading coherence, logical flow and translation quality.",
596
+ },
597
+ consistency: {
598
+ weight: 0.12,
599
+ description: "Terminology, style and formatting are unified and professional.",
600
+ },
601
+ contentQuality: {
602
+ weight: 0.24,
603
+ description:
604
+ "Accurate and complete content that adds value with sufficient detail and examples.",
605
+ },
606
+ purposeAlignment: {
607
+ weight: 0.14,
608
+ description:
609
+ "Content matches the intended purpose such as quick start, API reference or troubleshooting.",
610
+ },
611
+ audienceAlignment: {
612
+ weight: 0.12,
613
+ description:
614
+ "Language and examples match the target audience (e.g., developers, non-technical users).",
615
+ },
616
+ knowledgeLevelAlignment: {
617
+ weight: 0.1,
618
+ description: "Depth and difficulty fit the readers' knowledge level.",
619
+ },
620
+ },
621
+ },
622
+ structure: {
623
+ weight: 0.15,
624
+ description: "Organization and navigability of the documentation.",
625
+ subDimensions: {
626
+ navigability: {
627
+ weight: 0.2,
628
+ description: "Table of contents entries correctly link to headings.",
629
+ },
630
+ informationScent: {
631
+ weight: 0.2,
632
+ description:
633
+ "Key pages such as Quick Start can be reached within three clicks from the homepage.",
634
+ },
635
+ purposeCoverage: {
636
+ weight: 0.25,
637
+ description:
638
+ "Structure covers all selected documentation goals without forcing them into a single page.",
639
+ },
640
+ audienceCoverage: {
641
+ weight: 0.2,
642
+ description: "Structure covers the main intended audience groups.",
643
+ },
644
+ coverageDepthAlignment: {
645
+ weight: 0.15,
646
+ description: "Overall balance of conciseness, depth and breadth meets user expectations.",
647
+ },
648
+ },
649
+ },
650
+ },
651
+ };
@@ -0,0 +1,102 @@
1
+ export const LINTER_API_URL = process.env.LINTER_API_URL || "https://linter.abtnet.io";
2
+
3
+ export const LINTER_SUPPORTED_FILE = {
4
+ biome: [".js", ".jsx", ".ts", ".tsx", ".json"],
5
+ eslint: [".js", ".jsx", ".ts", ".tsx", ".vue"],
6
+ oxlint: [".js", ".jsx", ".ts", ".tsx"],
7
+ prettier: [".js", ".jsx", ".ts", ".tsx", ".json", ".css"],
8
+ pylint: [".py"],
9
+ flake8: [".py"],
10
+ black: [".py"],
11
+ isort: [".py"],
12
+ mypy: [".py"],
13
+ shellcheck: [".sh", ".bash", ".dash", ".ksh"],
14
+ "golangci-lint": [".go"],
15
+ rubocop: [".rb", ".rake", ".gemfile", "Gemfile"],
16
+ hadolint: ["Dockerfile", ".dockerfile"],
17
+ yamllint: [".yml", ".yaml"],
18
+ stylelint: [".css", ".scss", ".sass"],
19
+ };
20
+ export const SUFFIX_TO_CODE_LANGUAGE = {
21
+ ".js": ["js", "javascript", "node"],
22
+ ".jsx": ["jsx"],
23
+ ".ts": ["ts", "typescript"],
24
+ ".tsx": ["tsx"],
25
+ ".json": ["json"],
26
+ ".vue": ["vue"],
27
+ ".css": ["css"],
28
+ ".py": ["python", "python3"],
29
+ ".sh": ["shell", "sh", "shell-script", "bash", "zsh"],
30
+ ".go": ["go", "golang"],
31
+ ".rb": ["ruby", "jruby", "macruby", "rake", "rb", "rbx"],
32
+ ".dockerfile": ["dockerfile"],
33
+ ".yml": ["yaml", "yml"],
34
+ ".sass": ["sass"],
35
+ ".scss": ["scss"],
36
+ };
37
+
38
+ export const CODE_LANGUAGE_MAP_LINTER = {
39
+ js: "biome-lint",
40
+ javascript: "biome-lint",
41
+ node: "biome-lint",
42
+ jsx: "biome-lint",
43
+ ts: "biome-lint",
44
+ typescript: "biome-lint",
45
+ tsx: "biome-lint",
46
+ json: "biome-lint",
47
+ vue: "eslint",
48
+ css: "prettier",
49
+ python: "flake8",
50
+ python3: "flake8",
51
+ shell: "shellcheck",
52
+ sh: "shellcheck",
53
+ "shell-script": "shellcheck",
54
+ bash: "shellcheck",
55
+ zsh: "shellcheck",
56
+ go: "golangci-lint",
57
+ golang: "golangci-lint",
58
+ ruby: "rubocop",
59
+ jruby: "rubocop",
60
+ macruby: "rubocop",
61
+ rake: "rubocop",
62
+ rb: "rubocop",
63
+ rbx: "rubocop",
64
+ dockerfile: "hadolint",
65
+ yaml: "yamllint",
66
+ yml: "yamllint",
67
+ sass: "stylelint",
68
+ scss: "stylelint",
69
+ };
70
+
71
+ export const CODE_LANGUAGE_MAP_SUFFIX = {
72
+ js: ".js",
73
+ javascript: ".js",
74
+ node: ".js",
75
+ jsx: ".jsx",
76
+ ts: ".ts",
77
+ typescript: ".ts",
78
+ tsx: ".tsx",
79
+ json: ".json",
80
+ vue: ".vue",
81
+ css: ".css",
82
+ python: ".py",
83
+ python3: ".py",
84
+ shell: ".sh",
85
+ sh: ".sh",
86
+ "shell-script": ".sh",
87
+ bash: ".sh",
88
+ zsh: ".sh",
89
+ go: ".go",
90
+ golang: ".go",
91
+ ruby: ".rb",
92
+ jruby: ".rb",
93
+ macruby: ".rb",
94
+ rake: ".rb",
95
+ rb: ".rb",
96
+ rbx: ".rb",
97
+ dockerfile: ".dockerfile",
98
+ yaml: ".yml",
99
+ yml: ".yml",
100
+ sass: ".sass",
101
+ scss: ".scss",
102
+ };
@@ -1,7 +1,6 @@
1
1
  import path from "node:path";
2
2
 
3
3
  import { D2 } from "@terrastruct/d2";
4
- import Debug from "debug";
5
4
  import fs from "fs-extra";
6
5
  import { glob } from "glob";
7
6
  import pMap from "p-map";
@@ -13,12 +12,11 @@ import {
13
12
  FILE_CONCURRENCY,
14
13
  TMP_ASSETS_DIR,
15
14
  TMP_DIR,
16
- } from "./constants.mjs";
15
+ } from "./constants/index.mjs";
16
+ import { debug } from "./debug.mjs";
17
17
  import { iconMap } from "./icon-map.mjs";
18
18
  import { getContentHash } from "./utils.mjs";
19
19
 
20
- const debug = Debug("doc-smith");
21
-
22
20
  export async function getChart({ content, strict }) {
23
21
  const d2 = new D2();
24
22
  const iconUrlList = Object.keys(iconMap);
@@ -0,0 +1,3 @@
1
+ import Debug from "debug";
2
+
3
+ export const debug = Debug("doc-smith");