@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.
Files changed (264) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/agents/publish/index.yaml +4 -0
  3. package/agents/publish/publish-docs.mjs +77 -5
  4. package/agents/publish/translate-meta.mjs +103 -0
  5. package/agents/update/generate-document.yaml +30 -28
  6. package/agents/update/update-document-detail.yaml +3 -1
  7. package/agents/utils/update-branding.mjs +69 -0
  8. package/package.json +16 -2
  9. package/prompts/common/document/role-and-personality.md +3 -1
  10. package/prompts/detail/d2-diagram/guide.md +7 -1
  11. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  12. package/prompts/detail/generate/system-prompt.md +6 -7
  13. package/prompts/detail/generate/user-prompt.md +12 -3
  14. package/prompts/detail/update/user-prompt.md +0 -2
  15. package/prompts/structure/update/user-prompt.md +0 -4
  16. package/utils/file-utils.mjs +69 -24
  17. package/utils/markdown-checker.mjs +0 -20
  18. package/utils/request.mjs +7 -0
  19. package/utils/upload-files.mjs +231 -0
  20. package/utils/utils.mjs +11 -1
  21. package/.aigne/doc-smith/config.yaml +0 -77
  22. package/.aigne/doc-smith/history.yaml +0 -37
  23. package/.aigne/doc-smith/media-description.yaml +0 -91
  24. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  25. package/.aigne/doc-smith/preferences.yml +0 -97
  26. package/.aigne/doc-smith/upload-cache.yaml +0 -1830
  27. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  28. package/.github/workflows/ci.yml +0 -54
  29. package/.github/workflows/create-release-pr.yaml +0 -21
  30. package/.github/workflows/publish-docs.yml +0 -65
  31. package/.github/workflows/release.yml +0 -49
  32. package/.github/workflows/reviewer.yml +0 -54
  33. package/.release-please-manifest.json +0 -3
  34. package/RELEASE.md +0 -9
  35. package/assets/screenshots/doc-complete-setup.png +0 -0
  36. package/assets/screenshots/doc-generate-docs.png +0 -0
  37. package/assets/screenshots/doc-generate.png +0 -0
  38. package/assets/screenshots/doc-generated-successfully.png +0 -0
  39. package/assets/screenshots/doc-publish.png +0 -0
  40. package/assets/screenshots/doc-regenerate.png +0 -0
  41. package/assets/screenshots/doc-translate-langs.png +0 -0
  42. package/assets/screenshots/doc-translate.png +0 -0
  43. package/assets/screenshots/doc-update.png +0 -0
  44. package/biome.json +0 -73
  45. package/codecov.yml +0 -15
  46. package/docs/_sidebar.md +0 -15
  47. package/docs/configuration-initial-setup.ja.md +0 -179
  48. package/docs/configuration-initial-setup.md +0 -198
  49. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  50. package/docs/configuration-initial-setup.zh.md +0 -179
  51. package/docs/configuration-managing-preferences.ja.md +0 -100
  52. package/docs/configuration-managing-preferences.md +0 -100
  53. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  54. package/docs/configuration-managing-preferences.zh.md +0 -100
  55. package/docs/configuration.ja.md +0 -69
  56. package/docs/configuration.md +0 -69
  57. package/docs/configuration.zh-TW.md +0 -69
  58. package/docs/configuration.zh.md +0 -69
  59. package/docs/getting-started.ja.md +0 -107
  60. package/docs/getting-started.md +0 -107
  61. package/docs/getting-started.zh-TW.md +0 -107
  62. package/docs/getting-started.zh.md +0 -107
  63. package/docs/guides-cleaning-up.ja.md +0 -51
  64. package/docs/guides-cleaning-up.md +0 -52
  65. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  66. package/docs/guides-cleaning-up.zh.md +0 -51
  67. package/docs/guides-evaluating-documents.ja.md +0 -66
  68. package/docs/guides-evaluating-documents.md +0 -107
  69. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  70. package/docs/guides-evaluating-documents.zh.md +0 -66
  71. package/docs/guides-generating-documentation.ja.md +0 -151
  72. package/docs/guides-generating-documentation.md +0 -89
  73. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  74. package/docs/guides-generating-documentation.zh.md +0 -151
  75. package/docs/guides-interactive-chat.ja.md +0 -85
  76. package/docs/guides-interactive-chat.md +0 -93
  77. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  78. package/docs/guides-interactive-chat.zh.md +0 -85
  79. package/docs/guides-managing-history.ja.md +0 -48
  80. package/docs/guides-managing-history.md +0 -53
  81. package/docs/guides-managing-history.zh-TW.md +0 -48
  82. package/docs/guides-managing-history.zh.md +0 -48
  83. package/docs/guides-publishing-your-docs.ja.md +0 -78
  84. package/docs/guides-publishing-your-docs.md +0 -83
  85. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  86. package/docs/guides-publishing-your-docs.zh.md +0 -78
  87. package/docs/guides-translating-documentation.ja.md +0 -95
  88. package/docs/guides-translating-documentation.md +0 -100
  89. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  90. package/docs/guides-translating-documentation.zh.md +0 -95
  91. package/docs/guides-updating-documentation.ja.md +0 -77
  92. package/docs/guides-updating-documentation.md +0 -79
  93. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  94. package/docs/guides-updating-documentation.zh.md +0 -77
  95. package/docs/guides.ja.md +0 -32
  96. package/docs/guides.md +0 -32
  97. package/docs/guides.zh-TW.md +0 -32
  98. package/docs/guides.zh.md +0 -32
  99. package/docs/overview.ja.md +0 -61
  100. package/docs/overview.md +0 -61
  101. package/docs/overview.zh-TW.md +0 -61
  102. package/docs/overview.zh.md +0 -61
  103. package/docs/release-notes.ja.md +0 -255
  104. package/docs/release-notes.md +0 -288
  105. package/docs/release-notes.zh-TW.md +0 -255
  106. package/docs/release-notes.zh.md +0 -255
  107. package/prompts/common/afs/afs-tools-usage.md +0 -5
  108. package/prompts/common/afs/use-afs-instruction.md +0 -1
  109. package/release-please-config.json +0 -14
  110. package/tests/agents/chat/chat.test.mjs +0 -46
  111. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  112. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  113. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  114. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  115. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  116. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  117. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  118. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  119. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  120. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  121. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  122. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  123. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  124. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  125. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  126. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  127. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  128. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  129. package/tests/agents/history/view.test.mjs +0 -97
  130. package/tests/agents/init/init.test.mjs +0 -1657
  131. package/tests/agents/prefs/prefs.test.mjs +0 -431
  132. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  133. package/tests/agents/translate/choose-language.test.mjs +0 -311
  134. package/tests/agents/translate/translate-document.test.mjs +0 -51
  135. package/tests/agents/update/check-document.test.mjs +0 -463
  136. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  137. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  138. package/tests/agents/update/generate-document.test.mjs +0 -51
  139. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  140. package/tests/agents/update/user-review-document.test.mjs +0 -582
  141. package/tests/agents/utils/action-success.test.mjs +0 -54
  142. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  143. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  144. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  145. package/tests/agents/utils/exit.test.mjs +0 -70
  146. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  147. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  148. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  149. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  150. package/tests/agents/utils/fs.test.mjs +0 -267
  151. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  152. package/tests/agents/utils/save-docs.test.mjs +0 -109
  153. package/tests/agents/utils/save-output.test.mjs +0 -315
  154. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  155. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  156. package/tests/utils/auth-utils.test.mjs +0 -596
  157. package/tests/utils/blocklet.test.mjs +0 -336
  158. package/tests/utils/conflict-detector.test.mjs +0 -355
  159. package/tests/utils/constants.test.mjs +0 -295
  160. package/tests/utils/d2-utils.test.mjs +0 -437
  161. package/tests/utils/deploy.test.mjs +0 -399
  162. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  163. package/tests/utils/file-utils.test.mjs +0 -521
  164. package/tests/utils/history-utils.test.mjs +0 -206
  165. package/tests/utils/kroki-utils.test.mjs +0 -646
  166. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  167. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  168. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  169. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  170. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  171. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  172. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  173. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  174. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  175. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  176. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  177. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  178. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  179. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  180. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  181. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  182. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  183. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  184. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  185. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  186. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  187. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  188. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  189. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  190. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  191. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  192. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  193. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  194. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  195. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  196. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  197. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  198. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  199. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  200. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  201. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  202. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  203. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  204. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  205. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  206. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  207. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  208. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  209. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  210. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  211. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  212. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  213. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  214. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  215. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  216. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  217. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  218. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  219. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  220. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  221. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  222. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  223. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  224. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  225. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  226. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  227. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  228. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  229. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  230. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  231. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  232. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  233. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  234. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  235. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  236. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  237. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  238. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  239. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  240. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  241. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  242. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  243. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  244. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  245. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  246. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  247. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  248. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  249. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  250. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  251. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  252. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  253. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  254. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  255. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  256. package/tests/utils/linter/index.test.mjs +0 -440
  257. package/tests/utils/linter/scan-results.mjs +0 -42
  258. package/tests/utils/load-config.test.mjs +0 -141
  259. package/tests/utils/markdown/index.test.mjs +0 -478
  260. package/tests/utils/mermaid-validator.test.mjs +0 -541
  261. package/tests/utils/mock-chat-model.mjs +0 -12
  262. package/tests/utils/preferences-utils.test.mjs +0 -465
  263. package/tests/utils/save-value-to-config.test.mjs +0 -483
  264. package/tests/utils/utils.test.mjs +0 -941
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.12](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.12-beta.9...v0.8.12) (2025-10-16)
4
+
5
+ ## [0.8.12-beta.9](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.12-beta.8...v0.8.12-beta.9) (2025-10-15)
6
+
7
+
8
+ ### Features
9
+
10
+ * **branding:** support updating branding information during publish doc ([#190](https://github.com/AIGNE-io/aigne-doc-smith/issues/190)) ([1918cae](https://github.com/AIGNE-io/aigne-doc-smith/commit/1918cae6ceefd24d76b6086730b6e0d038057cb6))
11
+ * support translate meta in publish ([#189](https://github.com/AIGNE-io/aigne-doc-smith/issues/189)) ([3a34e38](https://github.com/AIGNE-io/aigne-doc-smith/commit/3a34e38f4283d4b2a19a88e426a8b49f0dd52bb6))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * generate d2 diagram by tool use ([#184](https://github.com/AIGNE-io/aigne-doc-smith/issues/184)) ([0d04349](https://github.com/AIGNE-io/aigne-doc-smith/commit/0d04349d14cde62388467f755dedc10b74d14980))
17
+
3
18
  ## [0.8.12-beta.8](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.12-beta.7...v0.8.12-beta.8) (2025-10-14)
4
19
 
5
20
 
@@ -9,6 +9,7 @@ skills:
9
9
  default_input:
10
10
  skipIfExists: true
11
11
  checkOnly: true
12
+ - translate-meta.mjs
12
13
  - publish-docs.mjs
13
14
  input_schema:
14
15
  type: object
@@ -16,3 +17,6 @@ input_schema:
16
17
  appUrl:
17
18
  type: string
18
19
  description: Website URL where docs will be published (optional - leave empty for interactive setup)
20
+ with-branding:
21
+ type: boolean
22
+ description: Update your website branding (title, description, logo)
@@ -1,10 +1,12 @@
1
- import { basename, join } from "node:path";
2
-
1
+ import { basename, extname, join, relative } from "node:path";
2
+ import slugify from "slugify";
3
3
  import { publishDocs as publishDocsFn } from "@aigne/publish-docs";
4
4
  import { BrokerClient } from "@blocklet/payment-broker-client/node";
5
5
  import chalk from "chalk";
6
6
  import fs from "fs-extra";
7
7
 
8
+ import { getExtnameFromContentType } from "../../utils/file-utils.mjs";
9
+ import { isHttp } from "../../utils/utils.mjs";
8
10
  import { getAccessToken, getOfficialAccessToken } from "../../utils/auth-utils.mjs";
9
11
  import {
10
12
  CLOUD_SERVICE_URL_PROD,
@@ -16,14 +18,25 @@ import {
16
18
  import { beforePublishHook, ensureTmpDir } from "../../utils/d2-utils.mjs";
17
19
  import { deploy } from "../../utils/deploy.mjs";
18
20
  import { getGithubRepoUrl, loadConfigFromFile, saveValueToConfig } from "../../utils/utils.mjs";
21
+ import updateBranding from "../utils/update-branding.mjs";
19
22
 
20
23
  const BASE_URL = process.env.DOC_SMITH_BASE_URL || CLOUD_SERVICE_URL_PROD;
21
24
 
22
25
  export default async function publishDocs(
23
- { docsDir: rawDocsDir, appUrl, boardId, projectName, projectDesc, projectLogo },
26
+ {
27
+ docsDir: rawDocsDir,
28
+ appUrl,
29
+ boardId,
30
+ projectName,
31
+ projectDesc,
32
+ projectLogo,
33
+ translatedMetadata,
34
+ "with-branding": withBrandingOption,
35
+ },
24
36
  options,
25
37
  ) {
26
38
  let message;
39
+ let shouldWithBranding = withBrandingOption || false;
27
40
 
28
41
  try {
29
42
  // move work dir to tmp-dir
@@ -119,6 +132,12 @@ export default async function publishDocs(
119
132
  // Ensure appUrl has protocol
120
133
  appUrl = userInput.includes("://") ? userInput : `https://${userInput}`;
121
134
  } else if (["new-instance", "new-instance-continue"].includes(choice)) {
135
+ if (options?.prompts?.confirm) {
136
+ shouldWithBranding = await options.prompts.confirm({
137
+ message: "Would you like to update the project branding (title, description, logo)?",
138
+ default: true,
139
+ });
140
+ }
122
141
  // Deploy a new Discuss Kit service
123
142
  let id = "";
124
143
  let paymentUrl = "";
@@ -143,6 +162,7 @@ export default async function publishDocs(
143
162
  process.env.DOC_ROOT_DIR = docsDir;
144
163
 
145
164
  const sidebarPath = join(docsDir, "_sidebar.md");
165
+ const publishCacheFilePath = join(DOC_SMITH_DIR, "upload-cache.yaml");
146
166
 
147
167
  // Get project info from config
148
168
  const projectInfo = {
@@ -151,6 +171,39 @@ export default async function publishDocs(
151
171
  icon: projectLogo || config?.projectLogo || "",
152
172
  };
153
173
 
174
+ // Handle project logo download if it's a URL
175
+ if (projectInfo.icon && isHttp(projectInfo.icon)) {
176
+ const tempFilePath = join(docsDir, slugify(basename(projectInfo.icon)));
177
+ const initialExt = extname(projectInfo.icon);
178
+ let ext = initialExt;
179
+
180
+ try {
181
+ const response = await fetch(projectInfo.icon);
182
+ const blob = await response.blob();
183
+ const arrayBuffer = await blob.arrayBuffer();
184
+ const buffer = Buffer.from(arrayBuffer);
185
+
186
+ if (response.ok) {
187
+ if (!ext) {
188
+ const contentType = response.headers.get("content-type");
189
+ ext = getExtnameFromContentType(contentType);
190
+ }
191
+
192
+ const finalPath = ext ? `${tempFilePath}.${ext}` : tempFilePath;
193
+ fs.writeFileSync(finalPath, buffer);
194
+
195
+ // Update to relative path
196
+ projectInfo.icon = relative(join(process.cwd(), DOC_SMITH_DIR), finalPath);
197
+ }
198
+ } catch (error) {
199
+ console.warn(`Failed to download project logo from ${projectInfo.icon}: ${error.message}`);
200
+ }
201
+ }
202
+
203
+ if (shouldWithBranding) {
204
+ updateBranding({ appUrl, projectInfo, accessToken });
205
+ }
206
+
154
207
  // Construct boardMeta object
155
208
  const boardMeta = {
156
209
  category: config?.documentPurpose || [],
@@ -161,6 +214,9 @@ export default async function publishDocs(
161
214
  ...(config?.translateLanguages || []),
162
215
  ].filter((lang, index, arr) => arr.indexOf(lang) === index), // Remove duplicates
163
216
  };
217
+ if (translatedMetadata) {
218
+ boardMeta.translation = translatedMetadata;
219
+ }
164
220
 
165
221
  const {
166
222
  success,
@@ -177,7 +233,7 @@ export default async function publishDocs(
177
233
  boardDesc: projectInfo.description,
178
234
  boardCover: projectInfo.icon,
179
235
  mediaFolder: rawDocsDir,
180
- cacheFilePath: join(DOC_SMITH_DIR, "upload-cache.yaml"),
236
+ cacheFilePath: publishCacheFilePath,
181
237
  boardMeta,
182
238
  });
183
239
 
@@ -193,6 +249,7 @@ export default async function publishDocs(
193
249
  await saveValueToConfig("boardId", newBoardId);
194
250
  }
195
251
  message = `✅ Documentation published successfully!`;
252
+ await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment service");
196
253
  } else {
197
254
  // If the error is 401 or 403, it means the access token is invalid
198
255
  if (error?.includes("401") || error?.includes("403")) {
@@ -214,7 +271,6 @@ export default async function publishDocs(
214
271
  }
215
272
  }
216
273
 
217
- await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment service");
218
274
  return message ? { message } : {};
219
275
  }
220
276
 
@@ -234,6 +290,22 @@ publishDocs.input_schema = {
234
290
  type: "string",
235
291
  description: "The id of the board",
236
292
  },
293
+ "with-branding": {
294
+ type: "boolean",
295
+ description: "Update your website branding (title, description, logo)",
296
+ },
297
+ projectName: {
298
+ type: "string",
299
+ description: "The name of the project",
300
+ },
301
+ projectDesc: {
302
+ type: "string",
303
+ description: "The description of the project",
304
+ },
305
+ projectLogo: {
306
+ type: "string",
307
+ description: "The logo/icon of the project",
308
+ },
237
309
  },
238
310
  };
239
311
 
@@ -0,0 +1,103 @@
1
+ import { join } from "node:path";
2
+
3
+ import { AIAgent } from "@aigne/core";
4
+ import fs from "fs-extra";
5
+ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
6
+ import z from "zod";
7
+
8
+ import { DOC_SMITH_DIR } from "../../utils/constants/index.mjs";
9
+
10
+ export default async function translateMeta(
11
+ { projectName, projectDesc, locale, translateLanguages = [] },
12
+ options,
13
+ ) {
14
+ const languages = [...new Set([...(locale ? [locale] : []), ...(translateLanguages || [])])];
15
+
16
+ const translationCacheFilePath = join(DOC_SMITH_DIR, "translation-cache.yaml");
17
+ await fs.ensureFile(translationCacheFilePath);
18
+ const translationCache = await fs.readFile(translationCacheFilePath, "utf-8");
19
+ const parsedTranslationCache = yamlParse(translationCache || "{}");
20
+
21
+ const titleTranslation = parsedTranslationCache[projectName] || {};
22
+ const descTranslation = parsedTranslationCache[projectDesc] || {};
23
+
24
+ const titleLanguages = languages.filter((lang) => !titleTranslation[lang]);
25
+ const descLanguages = languages.filter((lang) => !descTranslation[lang]);
26
+ const titleTranslationSchema = z.object(
27
+ titleLanguages.reduce((shape, lang) => {
28
+ shape[lang] = z.string();
29
+ return shape;
30
+ }, {}),
31
+ );
32
+ const descTranslationSchema = z.object(
33
+ descLanguages.reduce((shape, lang) => {
34
+ shape[lang] = z.string();
35
+ return shape;
36
+ }, {}),
37
+ );
38
+
39
+ const agent = AIAgent.from({
40
+ name: "translateMeta",
41
+ instructions:
42
+ "You are an **Elite Polyglot Localization and Translation Specialist** with extensive professional experience across multiple domains. Your core mission is to produce translations that are not only **100% accurate** to the source meaning but are also **natively fluent, highly readable, and culturally appropriate** in the target language.",
43
+ inputKey: "message",
44
+ outputSchema: z.object({
45
+ title: titleTranslationSchema.describe("Translated titles with language codes as keys"),
46
+ desc: descTranslationSchema.describe("Translated descriptions with language codes as keys"),
47
+ }),
48
+ });
49
+ if (titleLanguages.length > 0 || descLanguages.length > 0) {
50
+ const translatedMetadata = await options.context.invoke(agent, {
51
+ message: `Translate the following title and description into all target languages except the source language. Provide the translations in a JSON object with the language codes as keys. If the project title or description is empty, return an empty string for that field.
52
+
53
+ Project Title: ${projectName || ""}
54
+ Project Description: ${projectDesc || ""}
55
+
56
+ Target Languages: { title: ${titleLanguages.join(", ")}, desc: ${descLanguages.join(", ")} }
57
+ Source Language: ${locale}
58
+
59
+ Respond with a JSON object in the following format:
60
+ {
61
+ "title": {
62
+ "fr": "Translated Project Title in French",
63
+ "es": "Translated Project Title in Spanish",
64
+ ...
65
+ },
66
+ "desc": {
67
+ "fr": "Translated Project Description in French",
68
+ "es": "Translated Project Description in Spanish",
69
+ ...
70
+ }
71
+ }
72
+
73
+ If no translation is needed, respond with:
74
+ {
75
+ "title": {},
76
+ "desc": {}
77
+ }`,
78
+ });
79
+ Object.keys(translatedMetadata.title || {}).forEach((lang) => {
80
+ if (translatedMetadata.title[lang]) {
81
+ titleTranslation[lang] = translatedMetadata.title[lang];
82
+ }
83
+ });
84
+ Object.keys(translatedMetadata.desc || {}).forEach((lang) => {
85
+ if (translatedMetadata.desc[lang]) {
86
+ descTranslation[lang] = translatedMetadata.desc[lang];
87
+ }
88
+ });
89
+ }
90
+ const saveResult = {
91
+ ...parsedTranslationCache,
92
+ [projectName]: titleTranslation,
93
+ [projectDesc]: descTranslation,
94
+ };
95
+ await fs.writeFile(translationCacheFilePath, yamlStringify(saveResult), { encoding: "utf8" });
96
+
97
+ return {
98
+ translatedMetadata: {
99
+ title: saveResult[projectName] || {},
100
+ desc: saveResult[projectDesc] || {},
101
+ },
102
+ };
103
+ }
@@ -5,6 +5,8 @@ instructions:
5
5
  url: ../../prompts/detail/generate/system-prompt.md
6
6
  - role: user
7
7
  url: ../../prompts/detail/generate/user-prompt.md
8
+ auto_reorder_system_messages: true
9
+ auto_merge_system_messages: true
8
10
  input_schema:
9
11
  type: object
10
12
  properties:
@@ -54,31 +56,31 @@ afs:
54
56
  description: |
55
57
  Codebase of the project to be documented used as context for document generation,
56
58
  should search and read as needed while generating document content
57
- # skills:
58
- # FIXME: @zhanghan temporary disable diagram tool
59
- # - type: team
60
- # task_render_mode: collapse
61
- # name: generateDiagram
62
- # skills:
63
- # - ../generate/draw-diagram.yaml
64
- # - ../generate/wrap-diagram-code.mjs
65
- # reflection:
66
- # reviewer: ../generate/check-diagram.mjs
67
- # is_approved: isValid
68
- # max_iterations: 5
69
- # return_last_on_max_iterations: false
70
- # custom_error_message: "MUST NOT generate any diagram: validation failed after max iterations."
71
- # input_schema:
72
- # type: object
73
- # properties:
74
- # documentContent:
75
- # type: string
76
- # description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any existing diagram source code.)
77
- # required:
78
- # - documentContent
79
- # output_schema:
80
- # type: object
81
- # properties:
82
- # diagramSourceCode:
83
- # type: string
84
- # description: The **diagram source code** generated from the input text.
59
+ keep_text_in_tool_uses: false
60
+ skills:
61
+ - type: team
62
+ task_render_mode: collapse
63
+ name: generateDiagram
64
+ skills:
65
+ - ../generate/draw-diagram.yaml
66
+ - ../generate/wrap-diagram-code.mjs
67
+ reflection:
68
+ reviewer: ../generate/check-diagram.mjs
69
+ is_approved: isValid
70
+ max_iterations: 5
71
+ return_last_on_max_iterations: false
72
+ custom_error_message: "MUST NOT generate any diagram: validation failed after max iterations."
73
+ input_schema:
74
+ type: object
75
+ properties:
76
+ documentContent:
77
+ type: string
78
+ description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any existing diagram source code.)
79
+ required:
80
+ - documentContent
81
+ output_schema:
82
+ type: object
83
+ properties:
84
+ diagramSourceCode:
85
+ type: string
86
+ description: The **diagram source code** generated from the input text.
@@ -6,7 +6,8 @@ instructions:
6
6
  url: ../../prompts/detail/update/system-prompt.md
7
7
  - role: user
8
8
  url: ../../prompts/detail/update/user-prompt.md
9
-
9
+ auto_reorder_system_messages: true
10
+ auto_merge_system_messages: true
10
11
  input_schema:
11
12
  type: object
12
13
  properties:
@@ -53,6 +54,7 @@ afs:
53
54
  description: |
54
55
  Codebase of the project to be documented used as context for document generation,
55
56
  should search and read as needed while generating document content
57
+ keep_text_in_tool_uses: false
56
58
  skills:
57
59
  - ./document-tools/update-document-content.mjs
58
60
  task_render_mode: collapse
@@ -0,0 +1,69 @@
1
+ import { stat } from "node:fs/promises";
2
+ import { resolve } from "node:path";
3
+ import chalk from "chalk";
4
+ import { joinURL } from "ufo";
5
+
6
+ import { getComponentInfoWithMountPoint } from "../../utils/blocklet.mjs";
7
+ import {
8
+ CLOUD_SERVICE_URL_PROD,
9
+ CLOUD_SERVICE_URL_STAGING,
10
+ DISCUSS_KIT_DID,
11
+ DOC_SMITH_DIR,
12
+ } from "../../utils/constants/index.mjs";
13
+ import { requestWithAuthToken } from "../../utils/request.mjs";
14
+ import { uploadFiles } from "../../utils/upload-files.mjs";
15
+
16
+ export default async function updateBranding({ appUrl, projectInfo, accessToken }) {
17
+ try {
18
+ const origin = new URL(appUrl).origin;
19
+ if ([CLOUD_SERVICE_URL_PROD, CLOUD_SERVICE_URL_STAGING].includes(origin)) {
20
+ console.log("Skipped updating branding for official service\n");
21
+ return;
22
+ }
23
+
24
+ console.log(`🔄 Updating branding for ${chalk.cyan(origin)}`);
25
+
26
+ const componentInfo = await getComponentInfoWithMountPoint(origin, DISCUSS_KIT_DID);
27
+ const mountPoint = componentInfo.mountPoint || "/";
28
+
29
+ const res = await requestWithAuthToken(
30
+ joinURL(origin, mountPoint, "/api/branding"),
31
+ {
32
+ method: "PUT",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ },
36
+ body: JSON.stringify({
37
+ appName: projectInfo.name,
38
+ appDescription: projectInfo.description,
39
+ }),
40
+ },
41
+ accessToken,
42
+ );
43
+
44
+ if (res.success) {
45
+ try {
46
+ const projectLogoPath = resolve(process.cwd(), DOC_SMITH_DIR, projectInfo.icon);
47
+ const projectLogoStat = await stat(projectLogoPath);
48
+
49
+ if (projectLogoStat.isFile()) {
50
+ // Upload to blocklet logo endpoint
51
+ await uploadFiles({
52
+ appUrl: origin,
53
+ filePaths: [projectLogoPath],
54
+ accessToken,
55
+ concurrency: 1,
56
+ endpoint: `${origin}/.well-known/service/blocklet/logo/upload/square/${componentInfo.did}`,
57
+ });
58
+ }
59
+ console.log("✅ Updated branding successfully!\n");
60
+ } catch (error) {
61
+ console.warn(`⚠️ Just failed to update logo: ${error.message}\n`);
62
+ }
63
+ } else {
64
+ console.warn(`⚠️ Failed to update branding: ${res.error}\n`);
65
+ }
66
+ } catch (error) {
67
+ console.warn(`⚠️ Failed to update branding: ${error.message}\n`);
68
+ }
69
+ }
package/package.json CHANGED
@@ -1,10 +1,22 @@
1
1
  {
2
2
  "name": "@aigne/doc-smith",
3
- "version": "0.8.12-beta.8",
3
+ "version": "0.8.12",
4
4
  "description": "AI-driven documentation generation tool built on the AIGNE Framework",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
+ "files": [
9
+ "agents",
10
+ "assets/report-template",
11
+ "docs-mcp",
12
+ "prompts",
13
+ "types",
14
+ "utils",
15
+ "aigne.yaml",
16
+ "LICENSE",
17
+ "README.md",
18
+ "CHANGELOG.md"
19
+ ],
8
20
  "main": "index.js",
9
21
  "type": "module",
10
22
  "bin": "aigne.yaml",
@@ -18,7 +30,7 @@
18
30
  "@aigne/core": "^1.61.0",
19
31
  "@aigne/gemini": "^0.14.0",
20
32
  "@aigne/openai": "^0.16.0",
21
- "@aigne/publish-docs": "^0.11.0",
33
+ "@aigne/publish-docs": "^0.12.0",
22
34
  "@blocklet/payment-broker-client": "^1.21.10",
23
35
  "@terrastruct/d2": "^0.1.33",
24
36
  "chalk": "^5.5.0",
@@ -36,11 +48,13 @@
36
48
  "marked-terminal": "^7.3.0",
37
49
  "mermaid": "^11.9.0",
38
50
  "open": "^10.2.0",
51
+ "p-limit": "^7.1.1",
39
52
  "p-map": "^7.0.3",
40
53
  "p-retry": "^7.0.0",
41
54
  "remark-gfm": "^4.0.1",
42
55
  "remark-lint": "^10.0.1",
43
56
  "remark-parse": "^11.0.0",
57
+ "slugify": "^1.6.6",
44
58
  "terminal-link": "^4.0.0",
45
59
  "ufo": "^1.6.1",
46
60
  "unified": "^11.0.5",
@@ -6,10 +6,12 @@ Your key strengths include:
6
6
  - Versatile Writing Style: You're not confined to specific technical domains and can adapt your language style to meet diverse documentation needs—whether technical specifications, user guides, product descriptions, or business process documentation.
7
7
  - Quality-Driven Approach: You consistently pursue top-tier documentation quality, ensuring accuracy, completeness, consistency, readability, and practicality. You pay attention to detail and strive for precision in every expression.
8
8
  - User-Centric Perspective: You think from the target reader's viewpoint, anticipating their potential questions and confusion, addressing them proactively in the documentation to enhance user experience and value.
9
+ - Tool Usage Capability: You can call available tools as needed based on context to query information, gather data, or generate visuals, ensuring the documentation is accurate, complete, and visually clear.
9
10
 
10
11
  **Your process must reflect ISTJ traits:**
11
12
 
12
13
  1. **Fact-Driven:** Adhere strictly to the provided technical specifications. Do not infer or embellish information.
13
14
  2. **Structured and Orderly:** Organize the content logically with clear headings, subheadings, lists, and tables. Present information sequentially where appropriate (e.g., installation steps).
14
15
  3. **Clarity and Precision:** Use precise, unambiguous language. Define technical terms clearly. Avoid marketing jargon or emotionally charged words.
15
- 4. **Practical and Helpful:** Focus on providing practical examples, code snippets, and clear instructions that a user can directly apply.
16
+ 4. **Practical and Helpful:** Focus on providing practical examples, code snippets, and clear instructions that a user can directly apply.
17
+ 5. **Tool Utilization:** Actively call tools as needed, potentially multiple times, to obtain complete information from AFS (AIGNE File System) or generate Diagrams. Do not embed Mermaid or other diagram markup directly; include diagrams only via generateDiagram tool responses.
@@ -1,5 +1,8 @@
1
1
  <diagram_generation_guide>
2
2
  1. Diagram Triggers and Types: Use the following guidelines to determine when to generate a diagram and which type to use.
3
+ - Rule for Skipping Diagrams:
4
+ - Trigger: Do not generate diagrams for purely textual, reference, or short note documents that describe abstract concepts, simple definitions, or FAQs.
5
+ - Action: Skip diagram generation entirely.
3
6
  - Architecture Diagram (High-Level)
4
7
  - Trigger: When generating a document that serves as a high-level overview of a system, project, or the entire documentation set.
5
8
  - Action: Create a system architecture diagram.
@@ -13,7 +16,10 @@
13
16
  - Action: Create the most appropriate diagram type:
14
17
  - Flowchart: Use for step-by-step processes, algorithms, or decision-making logic.
15
18
  - Sequence Diagram: Use for time-ordered interactions between different components or actors (e.g., API calls).
19
+ NOTE: For documents not skipped by the first rule but not clearly fitting the above categories, you should always attempt to generate at least one Diagram whenever possible to visually represent key structures, relationships, or processes in the content.
20
+
16
21
  2. Constraints and Best Practices
17
22
  - Quantity: Generate a maximum of three (3) diagrams per document to ensure the content remains focused and readable.
18
- - Relevance: Ensure every diagram directly illustrates a concept explained in the surrounding text. Avoid generating diagrams for simple concepts that are easily understood through text alone.
23
+ - Relevance: Ensure every diagram directly illustrates a concept explained in the surrounding text. Avoid generating diagrams for concepts that are easily understood via text alone.
24
+ - Priority: For complex modules, workflows, or interactions, generate diagrams for each critical part.
19
25
  </diagram_generation_guide>
@@ -1,4 +1,7 @@
1
1
  Follow the given rules and ISTJ style from your system instructions.
2
2
 
3
3
  Generate a d2-diagram that represents the following document content:
4
+
5
+ <document_content>
4
6
  {{documentContent}}
7
+ </document_content>
@@ -1,6 +1,9 @@
1
1
  <role_and_goal>
2
2
  {% include "../../common/document/role-and-personality.md" %}
3
3
 
4
+
5
+ **Fact Verification Rule:**
6
+ Do not assume or infer any facts on your own. Treat all information as unknown until verified. Whenever possible, actively search and retrieve relevant, real-time information from **AFS (AIGNE File System)** or other available tools. Base your content strictly on the verified results from these searches or tool calls, rather than relying on memory or assumptions.
4
7
  </role_and_goal>
5
8
 
6
9
 
@@ -40,11 +43,7 @@ Custom component generation rules:
40
43
  Custom code block generation rules:
41
44
  {% include "../custom/custom-code-block.md" %}
42
45
 
43
- Diagram generation rules:
44
46
  {% include "../d2-diagram/guide.md" %}
45
- <diagram_generation_rules>
46
- {% include "../d2-diagram/system-prompt.md" %}
47
- </diagram_generation_rules>
48
47
 
49
48
  </content_generation_rules>
50
49
 
@@ -52,8 +51,8 @@ Diagram generation rules:
52
51
 
53
52
  <output_constraints>
54
53
 
55
- 1. Output detailed text content for {{nodeName}}.
56
- 2. Output {{nodeName}} content directly without including other information.
57
- 3. Reference the style from examples only, **output content in {{locale}} language**
54
+ 1. Output the complete Markdown content for {{nodeName}}, only the content itself—no explanations or extra information.
55
+ 2. Follow the format, structure, tone, and level of detail shown in the examples, strictly adhering to <document_rules>, <content_generation_rules>, and <TONE_STYLE>.
56
+ 3. Output in {{locale}} language, ensuring clarity, conciseness, and well-organized structure.
58
57
 
59
58
  </output_constraints>
@@ -53,9 +53,18 @@ User feedback on previous generation:
53
53
  </feedback>
54
54
  {% endif %}
55
55
 
56
- {% include "../../common/afs/afs-tools-usage.md" %}
57
56
 
58
57
  <instructions>
59
- Generate detailed document for the current {{nodeName}} based on user-provided information: current {{nodeName}} details (including title, description, path), DataSources, documentStructure (overall structural planning), and other relevant information.
60
- {% include "../../common/afs/use-afs-instruction.md" %}
58
+ Generate detailed and well-structured document for the current {{nodeName}} based on user-provided information: current {{nodeName}} details (including title, description, path), DataSources, documentStructure (overall structural planning), and other relevant information.
59
+
60
+ YOU SHOULD:
61
+ - Use AFS tools `afs_list` `afs_search` or `afs_read` to gather relevant and accurate information to enhance the content.
62
+ - Follow rules in <diagram_generation_guide>: use `generateDiagram` to create and embed a diagram when appropriate, following the diagram generation guidelines.
63
+
64
+ <steps>
65
+ 1. Analyze the provided document structure and user requirements to plan the content.
66
+ 2. Use AFS tools (`afs_list`/`afs_search`/`afs_read`) to search and gather relevant and accurate information to enhance the content.
67
+ 3. Use `generateDiagram` to create and embed a diagram when appropriate, following the diagram generation guidelines.
68
+ 4. Write clear, concise, and well-structured content for each section based on the planned structure and gathered information.
69
+ </steps>
61
70
  </instructions>
@@ -32,9 +32,7 @@
32
32
  {{feedback}}
33
33
  </user_feedback>
34
34
 
35
- {% include "../../common/afs/afs-tools-usage.md" %}
36
35
 
37
36
  <instructions>
38
37
  Analyze the original document content and user feedback, then use available tools to implement the requested improvements while maintaining the document's integrity and style.
39
- {% include "../../common/afs/use-afs-instruction.md" %}
40
38
  </instructions>
@@ -21,8 +21,6 @@ Initial Documentation Structure:
21
21
  {{ feedback }}
22
22
  </user_feedback>
23
23
 
24
- {% include "../../common/afs/afs-tools-usage.md" %}
25
-
26
24
  <instructions>
27
25
 
28
26
  Objectives:
@@ -41,6 +39,4 @@ Processing workflow:
41
39
  Rules:
42
40
  ** All changes must be made using Tools. **
43
41
  ** Carefully check if the latest version of documentStructure data meets user requirements, must avoid duplicate Tool calls. **
44
-
45
- {% include "../../common/afs/use-afs-instruction.md" %}
46
42
  </instructions>