@aigne/doc-smith 0.8.11-beta → 0.8.11-beta.2

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 (257) 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/publish-docs.yml +67 -0
  5. package/.release-please-manifest.json +1 -1
  6. package/CHANGELOG.md +22 -0
  7. package/README.md +45 -115
  8. package/agents/clear/choose-contents.mjs +170 -0
  9. package/agents/clear/clear-auth-tokens.mjs +111 -0
  10. package/agents/clear/clear-document-config.mjs +39 -0
  11. package/agents/clear/clear-document-structure.mjs +106 -0
  12. package/agents/clear/clear-generated-docs.mjs +51 -0
  13. package/agents/clear/index.yaml +23 -0
  14. package/agents/evaluate/code-snippet.mjs +93 -0
  15. package/agents/evaluate/document-structure.yaml +70 -0
  16. package/agents/evaluate/document.yaml +79 -0
  17. package/agents/evaluate/generate-report.mjs +78 -0
  18. package/agents/evaluate/index.yaml +39 -0
  19. package/agents/generate/document-structure-tools/add-document.mjs +56 -0
  20. package/agents/generate/document-structure-tools/delete-document.mjs +49 -0
  21. package/agents/generate/document-structure-tools/move-document.mjs +82 -0
  22. package/agents/generate/document-structure-tools/update-document.mjs +50 -0
  23. package/agents/generate/generate-structure.yaml +1 -1
  24. package/agents/generate/update-document-structure.yaml +42 -0
  25. package/agents/generate/user-review-document-structure.mjs +6 -4
  26. package/agents/init/index.mjs +1 -1
  27. package/agents/publish/publish-docs.mjs +12 -3
  28. package/agents/translate/choose-language.mjs +1 -1
  29. package/agents/update/batch-update-document.yaml +7 -0
  30. package/agents/update/check-update-is-single.mjs +38 -0
  31. package/agents/update/document-tools/update-document-content.mjs +293 -0
  32. package/agents/update/index.yaml +4 -10
  33. package/agents/update/update-document-detail.yaml +52 -0
  34. package/agents/update/update-single-document.yaml +15 -0
  35. package/agents/update/user-review-document.mjs +248 -0
  36. package/agents/utils/choose-docs.mjs +4 -2
  37. package/agents/utils/format-document-structure.mjs +12 -2
  38. package/agents/utils/load-document-all-content.mjs +84 -0
  39. package/agents/utils/load-sources.mjs +4 -1
  40. package/aigne.yaml +59 -20
  41. package/assets/report-template/report.html +198 -0
  42. package/biome.json +14 -2
  43. package/docs/advanced-how-it-works.ja.md +101 -0
  44. package/docs/advanced-how-it-works.zh-TW.md +101 -0
  45. package/docs/advanced-how-it-works.zh.md +20 -20
  46. package/docs/advanced-quality-assurance.ja.md +96 -0
  47. package/docs/advanced-quality-assurance.zh-TW.md +96 -0
  48. package/docs/advanced-quality-assurance.zh.md +18 -18
  49. package/docs/advanced.ja.md +16 -0
  50. package/docs/advanced.zh-TW.md +16 -0
  51. package/docs/advanced.zh.md +4 -4
  52. package/docs/changelog.ja.md +309 -0
  53. package/docs/changelog.zh-TW.md +309 -0
  54. package/docs/changelog.zh.md +23 -23
  55. package/docs/cli-reference.ja.md +210 -0
  56. package/docs/cli-reference.zh-TW.md +210 -0
  57. package/docs/cli-reference.zh.md +21 -21
  58. package/docs/configuration-interactive-setup.ja.md +135 -0
  59. package/docs/configuration-interactive-setup.zh-TW.md +135 -0
  60. package/docs/configuration-interactive-setup.zh.md +29 -29
  61. package/docs/configuration-language-support.ja.md +94 -0
  62. package/docs/configuration-language-support.zh-TW.md +94 -0
  63. package/docs/configuration-language-support.zh.md +13 -13
  64. package/docs/configuration-llm-setup.ja.md +54 -0
  65. package/docs/configuration-llm-setup.zh-TW.md +54 -0
  66. package/docs/configuration-llm-setup.zh.md +12 -12
  67. package/docs/configuration-preferences.ja.md +129 -0
  68. package/docs/configuration-preferences.zh-TW.md +129 -0
  69. package/docs/configuration-preferences.zh.md +36 -36
  70. package/docs/configuration.ja.md +172 -0
  71. package/docs/configuration.zh-TW.md +172 -0
  72. package/docs/configuration.zh.md +49 -49
  73. package/docs/features-generate-documentation.ja.md +101 -0
  74. package/docs/features-generate-documentation.zh-TW.md +101 -0
  75. package/docs/features-generate-documentation.zh.md +17 -17
  76. package/docs/features-publish-your-docs.ja.md +107 -0
  77. package/docs/features-publish-your-docs.zh-TW.md +107 -0
  78. package/docs/features-publish-your-docs.zh.md +22 -22
  79. package/docs/features-translate-documentation.ja.md +79 -0
  80. package/docs/features-translate-documentation.zh-TW.md +79 -0
  81. package/docs/features-translate-documentation.zh.md +12 -12
  82. package/docs/features-update-and-refine.ja.md +138 -0
  83. package/docs/features-update-and-refine.zh-TW.md +138 -0
  84. package/docs/features-update-and-refine.zh.md +21 -21
  85. package/docs/features.ja.md +52 -0
  86. package/docs/features.zh-TW.md +52 -0
  87. package/docs/features.zh.md +8 -8
  88. package/docs/getting-started.ja.md +123 -0
  89. package/docs/getting-started.zh-TW.md +123 -0
  90. package/docs/getting-started.zh.md +24 -24
  91. package/docs/overview.ja.md +30 -0
  92. package/docs/overview.zh-TW.md +30 -0
  93. package/docs/overview.zh.md +8 -8
  94. package/package.json +19 -11
  95. package/prompts/common/document/content-rules-core.md +19 -0
  96. package/prompts/common/document/media-handling-rules.md +9 -0
  97. package/prompts/common/document/role-and-personality.md +15 -0
  98. package/prompts/common/document/user-preferences.md +9 -0
  99. package/prompts/common/document-structure/conflict-resolution-guidance.md +16 -0
  100. package/prompts/common/document-structure/document-structure-rules.md +45 -0
  101. package/prompts/common/document-structure/glossary.md +7 -0
  102. package/prompts/common/document-structure/intj-traits.md +5 -0
  103. package/prompts/common/document-structure/output-constraints.md +9 -0
  104. package/prompts/common/document-structure/user-locale-rules.md +10 -0
  105. package/prompts/common/document-structure/user-preferences.md +9 -0
  106. package/prompts/detail/custom/custom-components.md +9 -1
  107. package/prompts/detail/document-rules.md +6 -6
  108. package/prompts/detail/generate-document.md +5 -45
  109. package/prompts/detail/update-document.md +145 -0
  110. package/prompts/evaluate/document-structure.md +94 -0
  111. package/prompts/evaluate/document.md +149 -0
  112. package/prompts/structure/document-rules.md +1 -1
  113. package/prompts/structure/generate-structure-system.md +74 -0
  114. package/prompts/structure/generate-structure-user.md +41 -0
  115. package/prompts/structure/update-document-structure.md +118 -0
  116. package/prompts/translate/translate-document.md +1 -1
  117. package/prompts/utils/feedback-refiner.md +3 -3
  118. package/release-please-config.json +1 -7
  119. package/tests/agents/clear/choose-contents.test.mjs +280 -0
  120. package/tests/agents/clear/clear-auth-tokens.test.mjs +268 -0
  121. package/tests/agents/clear/clear-document-config.test.mjs +167 -0
  122. package/tests/agents/clear/clear-document-structure.test.mjs +374 -0
  123. package/tests/agents/clear/clear-generated-docs.test.mjs +222 -0
  124. package/tests/agents/evaluate/code-snippet.test.mjs +163 -0
  125. package/tests/agents/evaluate/fixtures/api-services.md +87 -0
  126. package/tests/agents/evaluate/fixtures/js-sdk.md +94 -0
  127. package/tests/agents/evaluate/generate-report.test.mjs +312 -0
  128. package/tests/agents/generate/check-document-structure.test.mjs +0 -6
  129. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +449 -0
  130. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +410 -0
  131. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +476 -0
  132. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +548 -0
  133. package/tests/agents/generate/generate-structure.test.mjs +0 -6
  134. package/tests/agents/generate/user-review-document-structure.test.mjs +9 -9
  135. package/tests/agents/publish/publish-docs.test.mjs +2 -2
  136. package/tests/agents/update/check-update-is-single.test.mjs +300 -0
  137. package/tests/agents/update/document-tools/update-document-content.test.mjs +326 -0
  138. package/tests/agents/update/user-review-document.test.mjs +561 -0
  139. package/tests/agents/utils/format-document-structure.test.mjs +100 -0
  140. package/tests/utils/auth-utils.test.mjs +239 -1
  141. package/tests/utils/blocklet.test.mjs +9 -7
  142. package/tests/utils/constants.test.mjs +1 -1
  143. package/tests/utils/d2-utils.test.mjs +1 -1
  144. package/tests/utils/deploy.test.mjs +310 -366
  145. package/tests/utils/kroki-utils.test.mjs +2 -15
  146. package/tests/utils/linter/fixtures/css/keyword-error.css +1 -0
  147. package/tests/utils/linter/fixtures/css/missing-semicolon.css +1 -0
  148. package/tests/utils/linter/fixtures/css/syntax-error.css +1 -0
  149. package/tests/utils/linter/fixtures/css/undeclare-variable.css +1 -0
  150. package/tests/utils/linter/fixtures/css/unused-variable.css +2 -0
  151. package/tests/utils/linter/fixtures/css/valid-code.css +1 -0
  152. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +1 -0
  153. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +2 -0
  154. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +2 -0
  155. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +1 -0
  156. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +1 -0
  157. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +2 -0
  158. package/tests/utils/linter/fixtures/go/keyword-error.go +5 -0
  159. package/tests/utils/linter/fixtures/go/missing-semicolon.go +5 -0
  160. package/tests/utils/linter/fixtures/go/syntax-error.go +6 -0
  161. package/tests/utils/linter/fixtures/go/undeclare-variable.go +5 -0
  162. package/tests/utils/linter/fixtures/go/unused-variable.go +5 -0
  163. package/tests/utils/linter/fixtures/go/valid-code.go +7 -0
  164. package/tests/utils/linter/fixtures/js/keyword-error.js +3 -0
  165. package/tests/utils/linter/fixtures/js/missing-semicolon.js +6 -0
  166. package/tests/utils/linter/fixtures/js/syntax-error.js +4 -0
  167. package/tests/utils/linter/fixtures/js/undeclare-variable.js +3 -0
  168. package/tests/utils/linter/fixtures/js/unused-variable.js +7 -0
  169. package/tests/utils/linter/fixtures/js/valid-code.js +15 -0
  170. package/tests/utils/linter/fixtures/json/keyword-error.json +1 -0
  171. package/tests/utils/linter/fixtures/json/missing-semicolon.json +1 -0
  172. package/tests/utils/linter/fixtures/json/syntax-error.json +1 -0
  173. package/tests/utils/linter/fixtures/json/undeclare-variable.json +1 -0
  174. package/tests/utils/linter/fixtures/json/unused-variable.json +1 -0
  175. package/tests/utils/linter/fixtures/json/valid-code.json +1 -0
  176. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +5 -0
  177. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +5 -0
  178. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +5 -0
  179. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +5 -0
  180. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +4 -0
  181. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +5 -0
  182. package/tests/utils/linter/fixtures/python/keyword-error.py +3 -0
  183. package/tests/utils/linter/fixtures/python/missing-semicolon.py +2 -0
  184. package/tests/utils/linter/fixtures/python/syntax-error.py +3 -0
  185. package/tests/utils/linter/fixtures/python/undeclare-variable.py +3 -0
  186. package/tests/utils/linter/fixtures/python/unused-variable.py +6 -0
  187. package/tests/utils/linter/fixtures/python/valid-code.py +12 -0
  188. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +2 -0
  189. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +1 -0
  190. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +2 -0
  191. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +1 -0
  192. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +2 -0
  193. package/tests/utils/linter/fixtures/ruby/valid-code.rb +1 -0
  194. package/tests/utils/linter/fixtures/sass/keyword-error.sass +2 -0
  195. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +3 -0
  196. package/tests/utils/linter/fixtures/sass/syntax-error.sass +3 -0
  197. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +2 -0
  198. package/tests/utils/linter/fixtures/sass/unused-variable.sass +4 -0
  199. package/tests/utils/linter/fixtures/sass/valid-code.sass +2 -0
  200. package/tests/utils/linter/fixtures/scss/keyword-error.scss +1 -0
  201. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +1 -0
  202. package/tests/utils/linter/fixtures/scss/syntax-error.scss +1 -0
  203. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +1 -0
  204. package/tests/utils/linter/fixtures/scss/unused-variable.scss +2 -0
  205. package/tests/utils/linter/fixtures/scss/valid-code.scss +1 -0
  206. package/tests/utils/linter/fixtures/shell/keyword-error.sh +5 -0
  207. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +3 -0
  208. package/tests/utils/linter/fixtures/shell/syntax-error.sh +4 -0
  209. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +3 -0
  210. package/tests/utils/linter/fixtures/shell/unused-variable.sh +4 -0
  211. package/tests/utils/linter/fixtures/shell/valid-code.sh +3 -0
  212. package/tests/utils/linter/fixtures/ts/keyword-error.ts +1 -0
  213. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +1 -0
  214. package/tests/utils/linter/fixtures/ts/syntax-error.ts +1 -0
  215. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +1 -0
  216. package/tests/utils/linter/fixtures/ts/unused-variable.ts +3 -0
  217. package/tests/utils/linter/fixtures/ts/valid-code.ts +3 -0
  218. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +5 -0
  219. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +5 -0
  220. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +5 -0
  221. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +6 -0
  222. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +6 -0
  223. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +5 -0
  224. package/tests/utils/linter/fixtures/vue/keyword-error.vue +6 -0
  225. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +6 -0
  226. package/tests/utils/linter/fixtures/vue/syntax-error.vue +6 -0
  227. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +6 -0
  228. package/tests/utils/linter/fixtures/vue/unused-variable.vue +7 -0
  229. package/tests/utils/linter/fixtures/vue/valid-code.vue +6 -0
  230. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +1 -0
  231. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +2 -0
  232. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +1 -0
  233. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +1 -0
  234. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +2 -0
  235. package/tests/utils/linter/fixtures/yaml/valid-code.yml +3 -0
  236. package/tests/utils/linter/index.test.mjs +440 -0
  237. package/tests/utils/linter/scan-results.mjs +42 -0
  238. package/tests/utils/markdown/index.test.mjs +478 -0
  239. package/tests/utils/mermaid-validator.test.mjs +2 -2
  240. package/tests/utils/utils.test.mjs +3 -1
  241. package/types/document-schema.mjs +54 -0
  242. package/types/document-structure-schema.mjs +244 -0
  243. package/utils/auth-utils.mjs +131 -6
  244. package/utils/conflict-detector.mjs +5 -1
  245. package/utils/{constants.mjs → constants/index.mjs} +109 -0
  246. package/utils/constants/linter.mjs +102 -0
  247. package/utils/d2-utils.mjs +2 -4
  248. package/utils/debug.mjs +3 -0
  249. package/utils/deploy.mjs +81 -385
  250. package/utils/evaluate/report-utils.mjs +131 -0
  251. package/utils/file-utils.mjs +36 -1
  252. package/utils/kroki-utils.mjs +1 -1
  253. package/utils/linter/index.mjs +50 -0
  254. package/utils/markdown/index.mjs +26 -0
  255. package/utils/markdown-checker.mjs +1 -1
  256. package/utils/utils.mjs +19 -7
  257. package/prompts/structure/generate-structure.md +0 -161
package/utils/deploy.mjs CHANGED
@@ -1,410 +1,106 @@
1
+ import { BrokerClient, STEPS } from "@blocklet/payment-broker-client/node";
1
2
  import chalk from "chalk";
2
- import { joinURL } from "ufo";
3
- import { getComponentInfo, getComponentInfoWithMountPoint } from "./blocklet.mjs";
4
- import { PAYMENT_KIT_DID } from "./constants.mjs";
3
+ import open from "open";
4
+ import { getOfficialAccessToken } from "./auth-utils.mjs";
5
5
  import { saveValueToConfig } from "./utils.mjs";
6
6
 
7
- // ==================== URL Configuration ====================
7
+ // ==================== Configuration ====================
8
8
  const BASE_URL = process.env.DOC_SMITH_BASE_URL || "";
9
-
10
- // ==================== Timeout Configuration ====================
11
- const INTERVAL_MS = 3000; // 3 seconds between each check
12
- const TIMEOUTS = {
13
- paymentWait: 300, // Step 2: Payment wait timeout (5 minutes)
14
- installation: 300, // Step 3: Installation timeout (5 minutes)
15
- serviceStart: 300, // Step 4: Website startup timeout (5 minutes)
9
+ const SUCCESS_MESSAGE = {
10
+ en: "Congratulations! Your website has been successfully installed. You can return to the command-line tool to continue the next steps.",
11
+ zh: "恭喜您,你的网站已安装成功!可以返回命令行工具继续后续操作!",
16
12
  };
17
13
 
18
- // ==================== Utility Functions ====================
19
-
20
- /**
21
- * Generic polling utility with timeout and retry logic
22
- * @param {Object} options - Polling configuration
23
- * @param {Function} options.checkCondition - Async function that returns result if condition met, null/false if not
24
- * @param {number} options.maxAttempts - Maximum number of attempts
25
- * @param {number} options.intervalMs - Interval between attempts in milliseconds
26
- * @param {string} options.timeoutMessage - Error message for timeout
27
- * @param {string} options.stepName - Name of the step for logging (optional)
28
- * @returns {Promise<any>} Result from checkCondition when successful
29
- */
30
- async function pollWithTimeout({
31
- checkCondition,
32
- maxAttempts,
33
- intervalMs = INTERVAL_MS,
34
- timeoutMessage,
35
- stepName = "Operation",
36
- }) {
37
- let attempts = 0;
38
-
39
- while (attempts < maxAttempts) {
40
- attempts++;
41
-
42
- try {
43
- const result = await checkCondition();
44
- if (result !== null && result !== false) {
45
- return result;
46
- }
47
- } catch (_error) {
48
- // Log error for debugging but continue retrying unless it's the last attempt
49
- if (attempts === maxAttempts) {
50
- throw new Error(`${timeoutMessage} (${stepName} failed after ${maxAttempts} attempts)`);
51
- }
52
- // Continue retrying for non-fatal errors
53
- }
54
-
55
- // If this is the last attempt, don't wait - just exit the loop
56
- if (attempts === maxAttempts) {
57
- break;
58
- }
59
-
60
- // Wait before retry
61
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
62
- }
63
-
64
- // If we reach here, all attempts were exhausted
65
- throw new Error(`${timeoutMessage} (${stepName} timed out after ${maxAttempts} attempts)`);
66
- }
67
-
68
- // ==================== API Endpoints ====================
69
- const API_ENDPOINTS = {
70
- createCheckout: `/api/checkout-sessions/start`,
71
- paymentPage: `/checkout/pay/{id}`,
72
- orderStatus: `/api/vendors/order/{id}/status`,
73
- orderDetail: `/api/vendors/order/{id}/detail`,
74
- };
75
-
76
- let prefix = "";
77
- let paymentLinkId = "";
78
14
  /**
79
15
  * Deploy a new Discuss Kit Website and return the installation URL
80
- * @returns {Promise<string>} - The URL of the deployed Website
16
+ * @param {string} id - Cached checkout ID (optional)
17
+ * @param {string} cachedUrl - Cached payment URL (optional)
18
+ * @returns {Promise<Object>} - The deployment result with URLs
81
19
  */
82
20
  export async function deploy(id, cachedUrl) {
83
- const { mountPoint, PAYMENT_LINK_ID } = await getComponentInfoWithMountPoint(
84
- BASE_URL,
85
- PAYMENT_KIT_DID,
86
- );
87
- prefix = mountPoint;
88
- paymentLinkId = PAYMENT_LINK_ID;
89
-
90
- if (!PAYMENT_LINK_ID) {
91
- const { PAYMENT_LINK_ID: id } = await getComponentInfoWithMountPoint(
92
- joinURL(BASE_URL, mountPoint),
93
- PAYMENT_KIT_DID,
94
- );
95
- paymentLinkId = id;
96
- }
97
-
98
- // Step 1: Create payment link and open
99
- const cachedCheckoutId = await checkCacheCheckoutId(id);
100
- let checkoutId = cachedCheckoutId;
101
- let paymentUrl = cachedUrl;
102
- if (!cachedCheckoutId) {
103
- const { checkoutId: newCheckoutId, paymentUrl: newPaymentUrl } = await createPaymentSession();
104
- checkoutId = newCheckoutId;
105
- paymentUrl = newPaymentUrl;
106
- }
107
-
108
- if (!paymentUrl) {
109
- paymentUrl = joinURL(BASE_URL, prefix, API_ENDPOINTS.paymentPage.replace("{id}", checkoutId));
110
- }
111
- if (cachedCheckoutId !== checkoutId) {
112
- await openBrowser(paymentUrl);
113
- }
114
-
115
- // Step 2: Wait for payment completion
116
- console.log(`⏳ Step 1/4: Waiting for payment...`);
117
- console.log(`🔗 Payment link: ${chalk.cyan(paymentUrl)}\n`);
118
- await pollPaymentStatus(checkoutId);
119
- await saveValueToConfig("checkoutId", checkoutId, "Checkout ID for document deployment website");
120
- await saveValueToConfig("paymentUrl", paymentUrl, "Payment URL for document deployment website");
121
-
122
- // Step 3: Wait for website installation
123
- console.log(`📦 Step 2/4: Installing Website...`);
124
- const readyVendors = await waitInstallation(checkoutId);
125
-
126
- // Step 4: Wait for website startup
127
- console.log(`🚀 Step 3/4: Starting Website...`);
128
- const runningVendors = await waitWebsiteRunning(readyVendors);
129
-
130
- // Step 5: Get final URL
131
- console.log(`🌐 Step 4/4: Getting Website URL...`);
132
- const urlInfo = await getDashboardAndUrl(checkoutId, runningVendors);
133
- const { appUrl, homeUrl, token, subscriptionUrl } = urlInfo || {};
134
-
135
- console.log(`\n🔗 Your website is available at: ${chalk.cyan(homeUrl || appUrl)}`);
136
-
137
- if (subscriptionUrl) {
138
- console.log(`🔗 Your subscription management URL: ${chalk.cyan(subscriptionUrl)}\n`);
139
- } else {
140
- // just log one space line
141
- console.log("");
142
- }
143
-
144
- return {
145
- appUrl,
146
- homeUrl,
147
- token,
148
- };
149
- }
150
-
151
- /**
152
- * Check if there is a cached checkoutId
153
- */
154
- async function checkCacheCheckoutId(checkoutId) {
155
- try {
156
- if (!checkoutId) {
157
- return "";
158
- }
159
-
160
- const orderStatusUrl = joinURL(
161
- BASE_URL,
162
- prefix,
163
- API_ENDPOINTS.orderStatus.replace("{id}", checkoutId),
164
- );
165
- const response = await fetch(orderStatusUrl);
166
-
167
- if (!response.ok) {
168
- throw new Error(`HTTP error! status: ${response.status}`);
169
- }
170
-
171
- const data = await response.json();
172
-
173
- if (data.error) {
174
- throw new Error(data.error);
175
- }
176
-
177
- // Check payment status and vendors status
178
- const isPaid = data.payment_status === "paid";
179
-
180
- return isPaid ? checkoutId : "";
181
- } catch (_error) {
182
- await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment website");
183
- return "";
184
- }
185
- }
186
-
187
- /**
188
- * Create payment session - Step 1
189
- */
190
- async function createPaymentSession() {
191
- // 1. Call payment API
192
- if (!paymentLinkId) {
193
- throw new Error("Payment link ID not found");
194
- }
195
-
196
- const createCheckoutId = joinURL(BASE_URL, prefix, API_ENDPOINTS.createCheckout, paymentLinkId);
197
- try {
198
- const response = await fetch(createCheckoutId, {
199
- method: "POST",
200
- headers: { "Content-Type": "application/json" },
201
- body: JSON.stringify({
202
- needShortUrl: true,
203
- metadata: {
204
- page_info: {
205
- has_vendor: true,
206
- success_message: {
207
- en: "Congratulations! Your website has been successfully installed. You can return to the command-line tool to continue the next steps.",
208
- zh: "恭喜您,你的网站已安装成功!可以返回命令行工具继续后续操作!",
209
- },
210
- },
211
- },
212
- }),
213
- });
214
-
215
- if (!response.ok) {
216
- throw new Error(`HTTP error! status: ${response.status}`);
217
- }
218
-
219
- const data = await response.json();
220
- const checkoutId = data.checkoutSession.id;
221
- const paymentUrl = data.paymentUrl;
21
+ const authToken = await getOfficialAccessToken(BASE_URL);
222
22
 
223
- return { checkoutId, paymentUrl };
224
- } catch (error) {
225
- console.error(
226
- `${chalk.red("❌")} Failed to create payment session:`,
227
- error.message,
228
- createCheckoutId,
229
- );
230
- throw new Error(`Failed to create payment session: ${error.message}`);
23
+ if (!authToken) {
24
+ throw new Error("Failed to get official access token");
231
25
  }
232
- }
233
-
234
- /**
235
- * Open browser with payment URL
236
- */
237
- async function openBrowser(paymentUrl) {
238
- const { default: open } = await import("open");
239
- try {
240
- await open(paymentUrl);
241
- } catch (_error) {
242
- console.log(`${chalk.yellow("⚠️ Could not open browser automatically.")}`);
243
- console.log(`${chalk.blue("Please manually open this URL:")} ${chalk.cyan(paymentUrl)}`);
244
- }
245
- }
246
-
247
- /**
248
- * Wait for payment completion - Step 2 (5 minute timeout)
249
- */
250
- async function pollPaymentStatus(checkoutId) {
251
- return pollWithTimeout({
252
- checkCondition: async () => {
253
- const orderStatusUrl = joinURL(
254
- BASE_URL,
255
- prefix,
256
- API_ENDPOINTS.orderStatus.replace("{id}", checkoutId),
257
- );
258
- const response = await fetch(orderStatusUrl);
259
26
 
260
- if (!response.ok) {
261
- throw new Error(`HTTP error! status: ${response.status}`);
262
- }
263
-
264
- const data = await response.json();
265
-
266
- if (data.error) {
267
- throw new Error(data.error);
268
- }
269
-
270
- // Check payment status and vendors status
271
- const isPaid = data.payment_status === "paid";
272
- if (isPaid) {
273
- return data.vendors;
274
- }
275
-
276
- return null; // Not ready yet, continue polling
27
+ const client = new BrokerClient({
28
+ baseUrl: BASE_URL,
29
+ authToken,
30
+ paymentLinkKey: "PAYMENT_LINK_ID",
31
+ timeout: 300000,
32
+ polling: {
33
+ interval: 3000,
34
+ maxAttempts: 100,
35
+ backoffStrategy: "linear",
277
36
  },
278
- maxAttempts: Math.ceil((TIMEOUTS.paymentWait * 1000) / INTERVAL_MS),
279
- intervalMs: INTERVAL_MS,
280
- timeoutMessage: "Payment timeout - please complete payment within 5 minutes",
281
- stepName: "Payment",
282
37
  });
283
- }
284
-
285
- /**
286
- * Wait for installation completion - Step 3
287
- */
288
- async function waitInstallation(checkoutId) {
289
- return pollWithTimeout({
290
- checkCondition: async () => {
291
- const orderStatusUrl = joinURL(
292
- BASE_URL,
293
- prefix,
294
- API_ENDPOINTS.orderStatus.replace("{id}", checkoutId),
295
- );
296
- const response = await fetch(orderStatusUrl);
297
-
298
- if (!response.ok) {
299
- throw new Error(`HTTP error! status: ${response.status}`);
300
- }
301
38
 
302
- const data = await response.json();
39
+ console.log(`🚀 Starting deployment...`);
303
40
 
304
- if (data.error) {
305
- throw new Error(data.error);
306
- }
307
-
308
- // Check if all vendors meet conditions: progress >= 80 and appUrl exists
309
- const isInstalled = data.vendors?.every((vendor) => vendor.progress >= 80 && vendor.appUrl);
310
- if (isInstalled) {
311
- return data.vendors;
312
- }
313
-
314
- return null; // Not ready yet, continue polling
41
+ const result = await client.deploy({
42
+ cachedCheckoutId: id,
43
+ cachedPaymentUrl: cachedUrl,
44
+ pageInfo: {
45
+ successMessage: SUCCESS_MESSAGE,
315
46
  },
316
- maxAttempts: Math.ceil((TIMEOUTS.installation * 1000) / INTERVAL_MS),
317
- intervalMs: INTERVAL_MS,
318
- timeoutMessage: "Installation timeout - website failed to install within 5 minutes",
319
- stepName: "Installation",
320
- });
321
- }
322
-
323
- /**
324
- * Wait for Website to start running - Step 4
325
- */
326
- async function waitWebsiteRunning(readyVendors) {
327
- return pollWithTimeout({
328
- checkCondition: async () => {
329
- // Check running status of all vendors concurrently
330
- const vendorChecks = readyVendors.map(async (vendor) => {
331
- try {
332
- const blockletInfo = await getComponentInfo(vendor.appUrl);
333
-
334
- if (blockletInfo.status === "running") {
335
- return vendor;
336
- }
337
- return null;
338
- } catch (_error) {
339
- return null;
47
+ hooks: {
48
+ [STEPS.PAYMENT_PENDING]: async ({ sessionId, paymentUrl, isResuming }) => {
49
+ console.log(`⏳ Step 1/4: Waiting for payment...`);
50
+ console.log(`🔗 Payment link: ${chalk.cyan(paymentUrl)}\n`);
51
+
52
+ await saveValueToConfig(
53
+ "checkoutId",
54
+ sessionId,
55
+ "Checkout ID for document deployment website",
56
+ );
57
+ await saveValueToConfig(
58
+ "paymentUrl",
59
+ paymentUrl,
60
+ "Payment URL for document deployment website",
61
+ );
62
+
63
+ if (!isResuming) {
64
+ await open(paymentUrl);
340
65
  }
341
- });
342
-
343
- const results = await Promise.all(vendorChecks);
344
- const runningVendors = results.filter((vendor) => vendor !== null);
345
-
346
- if (runningVendors.length === readyVendors.length) {
347
- return runningVendors;
348
- }
66
+ },
67
+
68
+ [STEPS.INSTALLATION_STARTING]: () => {
69
+ console.log(`📦 Step 2/4: Installing Website...`);
70
+ },
71
+
72
+ [STEPS.SERVICE_STARTING]: () => {
73
+ console.log(`🚀 Step 3/4: Starting Website...`);
74
+ },
75
+
76
+ [STEPS.ACCESS_PREPARING]: () => {
77
+ console.log(`🌐 Step 4/4: Getting Website URL...`);
78
+ },
79
+
80
+ [STEPS.ACCESS_READY]: async ({ appUrl, homeUrl, subscriptionUrl }) => {
81
+ console.log(`\n🔗 Your website is available at: ${chalk.cyan(homeUrl || appUrl)}`);
82
+ if (subscriptionUrl) {
83
+ console.log(`🔗 Your subscription management URL: ${chalk.cyan(subscriptionUrl)}\n`);
84
+ } else {
85
+ console.log("");
86
+ }
87
+ },
88
+ },
349
89
 
350
- return null; // Not ready yet, continue polling
90
+ onError: (error, step) => {
91
+ console.error(`${chalk.red("❌")} Deployment failed at ${step || "unknown step"}:`);
92
+ console.error(` ${error.message}`);
351
93
  },
352
- maxAttempts: Math.ceil((TIMEOUTS.serviceStart * 1000) / INTERVAL_MS),
353
- intervalMs: INTERVAL_MS,
354
- timeoutMessage: "Website start timeout - website failed to start within 5 minutes",
355
- stepName: "Website Start",
356
94
  });
357
- }
358
-
359
- /**
360
- * Get final URL - Step 5
361
- */
362
- async function getDashboardAndUrl(checkoutId, runningVendors) {
363
- try {
364
- // 5. Get order details
365
- const orderDetailUrl = joinURL(
366
- BASE_URL,
367
- prefix,
368
- API_ENDPOINTS.orderDetail.replace("{id}", checkoutId),
369
- );
370
- const response = await fetch(orderDetailUrl);
371
-
372
- if (!response.ok) {
373
- throw new Error(`HTTP error! status: ${response.status}`);
374
- }
375
-
376
- const data = await response.json();
377
95
 
378
- if (data.vendors.length === 0) {
379
- throw new Error("No vendors found in order details");
380
- }
96
+ const { appUrl, homeUrl, subscriptionUrl, dashboardUrl, vendors } = result;
97
+ const token = vendors?.[0]?.token;
381
98
 
382
- // Wait 3 seconds
383
- await new Promise((resolve) => setTimeout(resolve, 3000));
384
-
385
- // Return the appUrl of the first vendor (usually only one)
386
- const appUrl = runningVendors[0]?.appUrl;
387
- if (!appUrl) {
388
- throw new Error("No app URL found in order details");
389
- }
390
-
391
- return {
392
- appUrl,
393
- subscriptionUrl: data.subscriptionUrl,
394
- dashboardUrl: data.vendors[0]?.dashboardUrl,
395
- homeUrl: data.vendors[0]?.homeUrl,
396
- token: data.vendors[0]?.token,
397
- };
398
- } catch (error) {
399
- console.error(`${chalk.red("❌")} Failed to get order details:`, error.message);
400
- // If getting details fails, use the appUrl of running vendor
401
- return {
402
- appUrl: runningVendors[0]?.appUrl || null,
403
- dashboardUrl: runningVendors[0]?.dashboardUrl || null,
404
- homeUrl: runningVendors[0]?.homeUrl || null,
405
- token: runningVendors[0]?.token || null,
406
- };
407
- }
99
+ return {
100
+ appUrl,
101
+ homeUrl,
102
+ dashboardUrl,
103
+ subscriptionUrl,
104
+ token,
105
+ };
408
106
  }
409
-
410
- export default deploy;
@@ -0,0 +1,131 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { toRelativePath } from "../utils.mjs";
6
+
7
+ /**
8
+ * Create report structure with evaluation data
9
+ * @param {Object} params - Parameters for creating the report
10
+ * @param {string} params.timestamp - Report generation timestamp
11
+ * @param {Object} params.metadata - Additional metadata for the report
12
+ * @param {Object} params.structureEvaluation - Structure evaluation results
13
+ * @param {Array} params.documentEvaluations - Individual document evaluations
14
+ * @param {string} params.projectName - Name of the project
15
+ * @param {string} params.projectDesc - Project description
16
+ * @param {string} params.projectLogo - Project logo URL
17
+ * @param {string} params.documentPurpose - Purpose of the documentation
18
+ * @param {Array} params.targetAudienceTypes - Types of target audience
19
+ * @param {string} params.readerKnowledgeLevel - Expected reader knowledge level
20
+ * @param {string} params.documentationDepth - Depth of documentation
21
+ * @param {string} params.targetAudience - Target audience description
22
+ * @returns {Object} Complete report structure
23
+ */
24
+ export function createReportStructure({
25
+ timestamp,
26
+ metadata,
27
+ structureEvaluation,
28
+ documentEvaluations,
29
+ projectName,
30
+ projectDesc,
31
+ projectLogo,
32
+ documentPurpose,
33
+ targetAudienceTypes,
34
+ readerKnowledgeLevel,
35
+ documentationDepth,
36
+ targetAudience,
37
+ }) {
38
+ return {
39
+ documentInfo: {
40
+ projectName,
41
+ projectDesc,
42
+ projectLogo,
43
+ documentPurpose,
44
+ targetAudienceTypes,
45
+ readerKnowledgeLevel,
46
+ documentationDepth,
47
+ targetAudience,
48
+ },
49
+ metadata: {
50
+ version: "0.1.0",
51
+ generatedBy: "AIGNE Doc Smith",
52
+ generatedAt: timestamp,
53
+ documentCount: documentEvaluations.length,
54
+ ...metadata,
55
+ },
56
+ structureEvaluation: {
57
+ type: "document-structure",
58
+ results: structureEvaluation,
59
+ },
60
+ documentEvaluations: {
61
+ type: "document-content",
62
+ results: documentEvaluations,
63
+ },
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Ensure directory exists, create if it doesn't
69
+ * @param {string} dirPath - Directory path to ensure exists
70
+ */
71
+ export async function ensureDirectoryExists(dirPath) {
72
+ if (!existsSync(dirPath)) {
73
+ await mkdir(dirPath, { recursive: true });
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Generate timestamp formatted for folder names
79
+ * @param {Date} [date] - Date object, defaults to current date
80
+ * @returns {string} Formatted timestamp string
81
+ */
82
+ export function generateTimestampForFolder(date = new Date()) {
83
+ const year = date.getFullYear();
84
+ const month = String(date.getMonth() + 1).padStart(2, "0");
85
+ const day = String(date.getDate()).padStart(2, "0");
86
+ const hours = String(date.getHours()).padStart(2, "0");
87
+ const minutes = String(date.getMinutes()).padStart(2, "0");
88
+
89
+ return `${year}-${month}-${day}_${hours}-${minutes}`;
90
+ }
91
+
92
+ /**
93
+ * Copy HTML report template to the report directory
94
+ * @param {string} targetDir - Target directory for the HTML report
95
+ * @returns {Promise<string>} Path to the copied HTML file
96
+ */
97
+ export async function copyHtmlReportTemplate(targetDir, data) {
98
+ const __filename = fileURLToPath(import.meta.url);
99
+ const __dirname = dirname(__filename);
100
+
101
+ // Path to the HTML template
102
+ const templatePath = join(__dirname, "../../", "assets", "report-template", "report.html");
103
+ const targetPath = join(targetDir, "integrity-report.html");
104
+
105
+ const templateReport = await readFile(templatePath, "utf-8");
106
+ const templateData = templateReport.replace("window.__REPORT_DATA__", JSON.stringify(data));
107
+ await writeFile(targetPath, templateData);
108
+ return toRelativePath(targetPath);
109
+ }
110
+
111
+ /**
112
+ * Generate success message with report links
113
+ * @param {string} jsonReportPath - Path to the JSON report
114
+ * @param {string} htmlReportPath - Path to the HTML report
115
+ * @returns {string} Success message with links
116
+ */
117
+ export function generateReportSuccessMessage(jsonReportPath, htmlReportPath) {
118
+ return `# ✅ Documentation Evaluation Report Generated Successfully!
119
+
120
+ Generated evaluation report and saved to:
121
+
122
+ \`${jsonReportPath}\`
123
+
124
+ ## 📊 View HTML Report
125
+
126
+ Open in your browser to view detailed analysis:
127
+
128
+ \`${htmlReportPath}\`
129
+
130
+ `;
131
+ }
@@ -1,5 +1,5 @@
1
1
  import { execSync } from "node:child_process";
2
- import { access, readFile } from "node:fs/promises";
2
+ import { access, readFile, stat } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { glob } from "glob";
5
5
 
@@ -208,3 +208,38 @@ export async function getFilesWithGlob(dir, includePatterns, excludePatterns, gi
208
208
  return [];
209
209
  }
210
210
  }
211
+
212
+ /**
213
+ * Check if a path exists
214
+ * @param {string} targetPath - Path to check
215
+ * @returns {Promise<boolean>} True if path exists
216
+ */
217
+ export async function pathExists(targetPath) {
218
+ try {
219
+ await stat(targetPath);
220
+ return true;
221
+ } catch (error) {
222
+ if (error.code === "ENOENT") return false;
223
+ throw error;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Convert absolute path to display path relative to current working directory
229
+ * @param {string} targetPath - Absolute path to convert
230
+ * @returns {string} Display path (relative or absolute)
231
+ */
232
+ export function toDisplayPath(targetPath) {
233
+ const rel = path.relative(process.cwd(), targetPath);
234
+ return rel.startsWith("..") ? targetPath : rel || ".";
235
+ }
236
+
237
+ /**
238
+ * Resolve path to absolute path
239
+ * @param {string} value - Path to resolve
240
+ * @returns {string|undefined} Absolute path or undefined if no value provided
241
+ */
242
+ export function resolveToAbsolute(value) {
243
+ if (!value) return undefined;
244
+ return path.isAbsolute(value) ? value : path.resolve(process.cwd(), value);
245
+ }
@@ -12,7 +12,7 @@ import {
12
12
  KROKI_CONCURRENCY,
13
13
  TMP_ASSETS_DIR,
14
14
  TMP_DIR,
15
- } from "./constants.mjs";
15
+ } from "./constants/index.mjs";
16
16
  import { getContentHash } from "./utils.mjs";
17
17
 
18
18
  const debug = Debug("doc-smith");