@tomako/tools-runtime 0.1.0

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 (531) hide show
  1. package/README.md +12 -0
  2. package/package.json +629 -0
  3. package/src/assets/icons/brands/social/bluesky-icon.tsx +9 -0
  4. package/src/assets/icons/brands/social/facebook-icon.tsx +9 -0
  5. package/src/assets/icons/brands/social/index.ts +8 -0
  6. package/src/assets/icons/brands/social/instagram-icon.tsx +9 -0
  7. package/src/assets/icons/brands/social/linkedin-icon.tsx +9 -0
  8. package/src/assets/icons/brands/social/threads-icon.tsx +9 -0
  9. package/src/assets/icons/brands/social/tiktok-icon.tsx +10 -0
  10. package/src/assets/icons/brands/social/x-icon.tsx +9 -0
  11. package/src/assets/icons/brands/social/youtube-icon.tsx +9 -0
  12. package/src/assets/icons/social-profile/facebook-icon.tsx +12 -0
  13. package/src/assets/icons/social-profile/index.ts +29 -0
  14. package/src/assets/icons/social-profile/instagram-icon.tsx +18 -0
  15. package/src/assets/icons/social-profile/linkedin-icon.tsx +12 -0
  16. package/src/assets/icons/social-profile/tiktok-icon.tsx +12 -0
  17. package/src/assets/icons/social-profile/x-icon.tsx +13 -0
  18. package/src/assets/icons/social-profile/youtube-icon.tsx +12 -0
  19. package/src/components/tools/engine/form-builder.tsx +219 -0
  20. package/src/components/tools/engine/package-widget-loader.tsx +38 -0
  21. package/src/components/tools/engine/package-widget-runtime.tsx +409 -0
  22. package/src/components/tools/engine/package-widget.tsx +77 -0
  23. package/src/components/tools/engine/result-view.tsx +596 -0
  24. package/src/components/tools/engine/use-legacy-llm-task.ts +64 -0
  25. package/src/components/tools/engine/use-tool-task.ts +195 -0
  26. package/src/components/tools/market-forecast-report.tsx +1150 -0
  27. package/src/components/tools/registry.ts +13 -0
  28. package/src/components/tools/workspace/index.ts +39 -0
  29. package/src/components/tools/workspace/tool-action-bar.tsx +99 -0
  30. package/src/components/tools/workspace/tool-empty-panel.tsx +32 -0
  31. package/src/components/tools/workspace/tool-error-panel.tsx +40 -0
  32. package/src/components/tools/workspace/tool-field.tsx +124 -0
  33. package/src/components/tools/workspace/tool-file-upload.tsx +112 -0
  34. package/src/components/tools/workspace/tool-form-section.tsx +21 -0
  35. package/src/components/tools/workspace/tool-form-shell.tsx +36 -0
  36. package/src/components/tools/workspace/tool-loading-panel.tsx +269 -0
  37. package/src/components/tools/workspace/tool-option-row.tsx +97 -0
  38. package/src/components/tools/workspace/tool-preview-panel.tsx +31 -0
  39. package/src/components/tools/workspace/tool-result-actions.tsx +67 -0
  40. package/src/components/tools/workspace/tool-result-file-actions.ts +31 -0
  41. package/src/components/tools/workspace/tool-result-header.tsx +39 -0
  42. package/src/components/tools/workspace/tool-status.tsx +13 -0
  43. package/src/components/tools/workspace/tool-workspace-layout.tsx +226 -0
  44. package/src/constants/LKS.ts +29 -0
  45. package/src/constants/related-tools.ts +18 -0
  46. package/src/constants/social-profile-kit.ts +284 -0
  47. package/src/constants/tool-assets.ts +7 -0
  48. package/src/env.d.ts +3 -0
  49. package/src/features/tools/_templates/standard-tool.container.tsx +90 -0
  50. package/src/features/tools/app-icon-resizer/app-icon-resizer.container.tsx +11 -0
  51. package/src/features/tools/app-icon-resizer/app-icon-resizer.spec.ts +15 -0
  52. package/src/features/tools/app-icon-resizer/widget/app-icon-resizer.tsx +444 -0
  53. package/src/features/tools/app-icon-resizer/widget/constants.ts +19 -0
  54. package/src/features/tools/app-icon-resizer/widget/helpers.ts +314 -0
  55. package/src/features/tools/app-icon-resizer/widget/index.ts +7 -0
  56. package/src/features/tools/app-icon-resizer/widget/platform-icons.tsx +59 -0
  57. package/src/features/tools/app-icon-resizer/widget/preview-dialogs.tsx +139 -0
  58. package/src/features/tools/app-icon-resizer/widget/result-shell.tsx +165 -0
  59. package/src/features/tools/app-icon-resizer/widget/types.ts +36 -0
  60. package/src/features/tools/app-store-screenshot-generator/app-store-screenshot-generator.container.tsx +108 -0
  61. package/src/features/tools/app-store-screenshot-generator/app-store-screenshot-generator.spec.ts +14 -0
  62. package/src/features/tools/app-store-screenshot-generator/config.ts +3 -0
  63. package/src/features/tools/app-store-screenshot-generator/widget/app-store-screenshot-generator.tsx +1250 -0
  64. package/src/features/tools/app-store-screenshot-generator/widget/asset-slots.ts +76 -0
  65. package/src/features/tools/app-store-screenshot-generator/widget/constants.ts +43 -0
  66. package/src/features/tools/app-store-screenshot-generator/widget/form-controls.tsx +214 -0
  67. package/src/features/tools/app-store-screenshot-generator/widget/generation.ts +528 -0
  68. package/src/features/tools/app-store-screenshot-generator/widget/index.ts +7 -0
  69. package/src/features/tools/app-store-screenshot-generator/widget/input-media.ts +175 -0
  70. package/src/features/tools/app-store-screenshot-generator/widget/types.ts +60 -0
  71. package/src/features/tools/app-store-screenshot-generator/widget/zip.ts +119 -0
  72. package/src/features/tools/build-in-public-story-generator/build-in-public-story-generator.container.tsx +135 -0
  73. package/src/features/tools/build-in-public-story-generator/build-in-public-story-generator.spec.ts +15 -0
  74. package/src/features/tools/build-in-public-story-generator/widget/build-in-public-story-generator.tsx +314 -0
  75. package/src/features/tools/build-in-public-story-generator/widget/constants.ts +3 -0
  76. package/src/features/tools/build-in-public-story-generator/widget/helpers.ts +25 -0
  77. package/src/features/tools/build-in-public-story-generator/widget/index.ts +7 -0
  78. package/src/features/tools/build-in-public-story-generator/widget/preview-panels.tsx +58 -0
  79. package/src/features/tools/build-in-public-story-generator/widget/result-shell.tsx +164 -0
  80. package/src/features/tools/build-in-public-story-generator/widget/types.ts +6 -0
  81. package/src/features/tools/cold-start-channel-selector/cold-start-channel-selector.container.tsx +30 -0
  82. package/src/features/tools/cold-start-channel-selector/cold-start-channel-selector.spec.ts +15 -0
  83. package/src/features/tools/cold-start-channel-selector/widget/cold-start-channel-selector.tsx +417 -0
  84. package/src/features/tools/cold-start-channel-selector/widget/constants.ts +46 -0
  85. package/src/features/tools/cold-start-channel-selector/widget/form-controls.tsx +41 -0
  86. package/src/features/tools/cold-start-channel-selector/widget/helpers.ts +75 -0
  87. package/src/features/tools/cold-start-channel-selector/widget/index.ts +7 -0
  88. package/src/features/tools/cold-start-channel-selector/widget/preview-panels.tsx +250 -0
  89. package/src/features/tools/cold-start-channel-selector/widget/result-shell.tsx +199 -0
  90. package/src/features/tools/cold-start-channel-selector/widget/types.ts +21 -0
  91. package/src/features/tools/commercial-bp-generator/commercial-bp-generator.container.tsx +102 -0
  92. package/src/features/tools/commercial-bp-generator/commercial-bp-generator.spec.ts +14 -0
  93. package/src/features/tools/commercial-bp-generator/widget/commercial-bp-generator.tsx +676 -0
  94. package/src/features/tools/commercial-bp-generator/widget/constants.ts +32 -0
  95. package/src/features/tools/commercial-bp-generator/widget/helpers.ts +147 -0
  96. package/src/features/tools/commercial-bp-generator/widget/index.ts +7 -0
  97. package/src/features/tools/commercial-bp-generator/widget/result-shell.tsx +271 -0
  98. package/src/features/tools/commercial-bp-generator/widget/style-option.tsx +54 -0
  99. package/src/features/tools/commercial-bp-generator/widget/types.ts +33 -0
  100. package/src/features/tools/community-feedback-inbox/community-feedback-inbox.container.tsx +126 -0
  101. package/src/features/tools/community-feedback-inbox/community-feedback-inbox.spec.ts +15 -0
  102. package/src/features/tools/community-feedback-inbox/widget/community-feedback-inbox.tsx +271 -0
  103. package/src/features/tools/community-feedback-inbox/widget/constants.ts +3 -0
  104. package/src/features/tools/community-feedback-inbox/widget/helpers.ts +28 -0
  105. package/src/features/tools/community-feedback-inbox/widget/index.ts +7 -0
  106. package/src/features/tools/community-feedback-inbox/widget/preview-panels.tsx +92 -0
  107. package/src/features/tools/community-feedback-inbox/widget/result-shell.tsx +266 -0
  108. package/src/features/tools/community-feedback-inbox/widget/types.ts +6 -0
  109. package/src/features/tools/community-pain-point-extractor/community-pain-point-extractor.container.tsx +124 -0
  110. package/src/features/tools/community-pain-point-extractor/community-pain-point-extractor.spec.ts +15 -0
  111. package/src/features/tools/community-pain-point-extractor/widget/community-pain-point-extractor.tsx +404 -0
  112. package/src/features/tools/community-pain-point-extractor/widget/constants.ts +41 -0
  113. package/src/features/tools/community-pain-point-extractor/widget/helpers.ts +76 -0
  114. package/src/features/tools/community-pain-point-extractor/widget/index.ts +8 -0
  115. package/src/features/tools/community-pain-point-extractor/widget/progress-panels.tsx +251 -0
  116. package/src/features/tools/community-pain-point-extractor/widget/result-shell.tsx +478 -0
  117. package/src/features/tools/community-pain-point-extractor/widget/types.ts +33 -0
  118. package/src/features/tools/community-post-risk-checker/community-post-risk-checker.package.ts +792 -0
  119. package/src/features/tools/competitor-analysis/competitor-analysis.container.tsx +136 -0
  120. package/src/features/tools/competitor-analysis/competitor-analysis.spec.ts +15 -0
  121. package/src/features/tools/competitor-analysis/widget/competitor-analysis.tsx +241 -0
  122. package/src/features/tools/competitor-analysis/widget/constants.ts +9 -0
  123. package/src/features/tools/competitor-analysis/widget/index.ts +7 -0
  124. package/src/features/tools/competitor-analysis/widget/preview-panels.tsx +60 -0
  125. package/src/features/tools/competitor-analysis/widget/result-shell.tsx +418 -0
  126. package/src/features/tools/competitor-analysis/widget/types.ts +13 -0
  127. package/src/features/tools/disclaimer-generator/disclaimer-generator.package.ts +339 -0
  128. package/src/features/tools/email-template-generator/email-template-generator.container.tsx +224 -0
  129. package/src/features/tools/email-template-generator/email-template-generator.spec.ts +14 -0
  130. package/src/features/tools/email-template-generator/widget/email-template-generator.tsx +358 -0
  131. package/src/features/tools/email-template-generator/widget/helpers.ts +39 -0
  132. package/src/features/tools/email-template-generator/widget/index.ts +7 -0
  133. package/src/features/tools/email-template-generator/widget/preview-panel.tsx +311 -0
  134. package/src/features/tools/email-template-generator/widget/result-text-block.tsx +7 -0
  135. package/src/features/tools/email-template-generator/widget/types.ts +24 -0
  136. package/src/features/tools/gtm-readiness-checklist/gtm-readiness-checklist.container.tsx +75 -0
  137. package/src/features/tools/gtm-readiness-checklist/gtm-readiness-checklist.spec.ts +15 -0
  138. package/src/features/tools/gtm-readiness-checklist/widget/gtm-readiness-checklist.tsx +122 -0
  139. package/src/features/tools/gtm-readiness-checklist/widget/index.ts +7 -0
  140. package/src/features/tools/investor-matching-planner/investor-matching-planner.package.ts +869 -0
  141. package/src/features/tools/koko-codex-assistant/koko-codex-assistant.container.tsx +151 -0
  142. package/src/features/tools/koko-codex-assistant/koko-codex-assistant.spec.ts +14 -0
  143. package/src/features/tools/koko-codex-assistant/widget/index.ts +7 -0
  144. package/src/features/tools/koko-codex-assistant/widget/koko-codex-assistant-download.tsx +192 -0
  145. package/src/features/tools/logo-generator/logo-generator.container.tsx +112 -0
  146. package/src/features/tools/logo-generator/logo-generator.spec.ts +15 -0
  147. package/src/features/tools/logo-generator/widget/index.ts +7 -0
  148. package/src/features/tools/logo-generator/widget/logo-generator.tsx +1244 -0
  149. package/src/features/tools/market-forecast-report/market-forecast-report.container.tsx +73 -0
  150. package/src/features/tools/market-forecast-report/market-forecast-report.spec.ts +15 -0
  151. package/src/features/tools/million-user-growth-test/million-user-growth-test.container.tsx +123 -0
  152. package/src/features/tools/million-user-growth-test/million-user-growth-test.spec.ts +14 -0
  153. package/src/features/tools/million-user-growth-test/widget/index.ts +7 -0
  154. package/src/features/tools/million-user-growth-test/widget/million-user-growth-test.tsx +433 -0
  155. package/src/features/tools/module-loader.ts +107 -0
  156. package/src/features/tools/og-image-generator/og-image-generator.container.tsx +86 -0
  157. package/src/features/tools/og-image-generator/og-image-generator.spec.ts +14 -0
  158. package/src/features/tools/og-image-generator/widget/constants.ts +38 -0
  159. package/src/features/tools/og-image-generator/widget/form-fields.tsx +240 -0
  160. package/src/features/tools/og-image-generator/widget/index.ts +7 -0
  161. package/src/features/tools/og-image-generator/widget/og-image-generator.tsx +742 -0
  162. package/src/features/tools/og-image-generator/widget/preview-panel.tsx +305 -0
  163. package/src/features/tools/og-image-generator/widget/types.ts +1 -0
  164. package/src/features/tools/package/direct-models.ts +20 -0
  165. package/src/features/tools/package/form.ts +38 -0
  166. package/src/features/tools/package/l10n.ts +22 -0
  167. package/src/features/tools/package/package-container.tsx +285 -0
  168. package/src/features/tools/package/package-loaders.ts +22 -0
  169. package/src/features/tools/package/package-registry.ts +36 -0
  170. package/src/features/tools/package/result-markdown.ts +142 -0
  171. package/src/features/tools/package/schema.ts +379 -0
  172. package/src/features/tools/package/to-tool-module.ts +20 -0
  173. package/src/features/tools/package/to-tool-spec.ts +52 -0
  174. package/src/features/tools/package/types.ts +381 -0
  175. package/src/features/tools/pitch-deck-generator/pitch-deck-generator.container.tsx +175 -0
  176. package/src/features/tools/pitch-deck-generator/pitch-deck-generator.spec.ts +14 -0
  177. package/src/features/tools/pitch-deck-generator/pitch-deck-library-data.ts +476 -0
  178. package/src/features/tools/pitch-deck-generator/pitch-deck-library.tsx +159 -0
  179. package/src/features/tools/pitch-deck-generator/widget/ceremony-line.tsx +27 -0
  180. package/src/features/tools/pitch-deck-generator/widget/constants.ts +27 -0
  181. package/src/features/tools/pitch-deck-generator/widget/index.ts +7 -0
  182. package/src/features/tools/pitch-deck-generator/widget/pitch-deck-generator.tsx +763 -0
  183. package/src/features/tools/pitch-deck-generator/widget/result-helpers.ts +102 -0
  184. package/src/features/tools/pitch-deck-generator/widget/result-shell.tsx +263 -0
  185. package/src/features/tools/pitch-deck-generator/widget/slide-frame.tsx +106 -0
  186. package/src/features/tools/pitch-deck-generator/widget/slide-lightbox.tsx +149 -0
  187. package/src/features/tools/pitch-deck-generator/widget/style-option.tsx +54 -0
  188. package/src/features/tools/pitch-deck-generator/widget/types.ts +44 -0
  189. package/src/features/tools/product-agreement-generator/product-agreement-generator.container.tsx +137 -0
  190. package/src/features/tools/product-agreement-generator/product-agreement-generator.spec.ts +14 -0
  191. package/src/features/tools/product-agreement-generator/widget/constants.ts +27 -0
  192. package/src/features/tools/product-agreement-generator/widget/form-controls.tsx +218 -0
  193. package/src/features/tools/product-agreement-generator/widget/helpers.ts +68 -0
  194. package/src/features/tools/product-agreement-generator/widget/index.ts +7 -0
  195. package/src/features/tools/product-agreement-generator/widget/product-agreement-generator.tsx +671 -0
  196. package/src/features/tools/product-agreement-generator/widget/result-shell.tsx +473 -0
  197. package/src/features/tools/product-agreement-generator/widget/types.ts +89 -0
  198. package/src/features/tools/product-hunt-launch-planner/product-hunt-launch-planner.container.tsx +122 -0
  199. package/src/features/tools/product-hunt-launch-planner/product-hunt-launch-planner.spec.ts +15 -0
  200. package/src/features/tools/product-hunt-launch-planner/widget/constants.ts +5 -0
  201. package/src/features/tools/product-hunt-launch-planner/widget/helpers.ts +44 -0
  202. package/src/features/tools/product-hunt-launch-planner/widget/index.ts +7 -0
  203. package/src/features/tools/product-hunt-launch-planner/widget/preview-panel.tsx +143 -0
  204. package/src/features/tools/product-hunt-launch-planner/widget/product-hunt-launch-planner.tsx +504 -0
  205. package/src/features/tools/product-hunt-launch-planner/widget/result-shell.tsx +176 -0
  206. package/src/features/tools/product-hunt-launch-planner/widget/types.ts +20 -0
  207. package/src/features/tools/product-name-generator/product-name-generator.container.tsx +14 -0
  208. package/src/features/tools/product-name-generator/product-name-generator.spec.ts +15 -0
  209. package/src/features/tools/product-name-generator/widget/candidate-card.tsx +273 -0
  210. package/src/features/tools/product-name-generator/widget/constants.ts +21 -0
  211. package/src/features/tools/product-name-generator/widget/form-controls.tsx +136 -0
  212. package/src/features/tools/product-name-generator/widget/helpers.ts +41 -0
  213. package/src/features/tools/product-name-generator/widget/index.ts +7 -0
  214. package/src/features/tools/product-name-generator/widget/product-name-generator.tsx +776 -0
  215. package/src/features/tools/product-name-generator/widget/types.ts +36 -0
  216. package/src/features/tools/product-positioning-analyzer/product-positioning-analyzer.package.ts +801 -0
  217. package/src/features/tools/product-poster-generator/product-poster-generator.container.tsx +14 -0
  218. package/src/features/tools/product-poster-generator/product-poster-generator.spec.ts +15 -0
  219. package/src/features/tools/product-poster-generator/widget/constants.ts +125 -0
  220. package/src/features/tools/product-poster-generator/widget/form-controls.tsx +204 -0
  221. package/src/features/tools/product-poster-generator/widget/helpers.ts +155 -0
  222. package/src/features/tools/product-poster-generator/widget/index.ts +7 -0
  223. package/src/features/tools/product-poster-generator/widget/product-poster-generator.tsx +663 -0
  224. package/src/features/tools/product-poster-generator/widget/result-shell.tsx +12 -0
  225. package/src/features/tools/product-poster-generator/widget/types.ts +83 -0
  226. package/src/features/tools/product-ui-generator/product-ui-generator.container.tsx +116 -0
  227. package/src/features/tools/product-ui-generator/product-ui-generator.spec.ts +14 -0
  228. package/src/features/tools/product-ui-generator/widget/constants.ts +18 -0
  229. package/src/features/tools/product-ui-generator/widget/helpers.ts +11 -0
  230. package/src/features/tools/product-ui-generator/widget/index.ts +7 -0
  231. package/src/features/tools/product-ui-generator/widget/preview-panels.tsx +73 -0
  232. package/src/features/tools/product-ui-generator/widget/product-ui-generator.tsx +304 -0
  233. package/src/features/tools/product-ui-generator/widget/result-shell.tsx +118 -0
  234. package/src/features/tools/product-ui-generator/widget/types.ts +9 -0
  235. package/src/features/tools/reddit-pain-point-finder/reddit-pain-point-finder.container.tsx +113 -0
  236. package/src/features/tools/reddit-pain-point-finder/reddit-pain-point-finder.spec.ts +15 -0
  237. package/src/features/tools/reddit-pain-point-finder/widget/constants.ts +5 -0
  238. package/src/features/tools/reddit-pain-point-finder/widget/index.ts +7 -0
  239. package/src/features/tools/reddit-pain-point-finder/widget/preview-panels.tsx +73 -0
  240. package/src/features/tools/reddit-pain-point-finder/widget/reddit-pain-point-finder.tsx +281 -0
  241. package/src/features/tools/reddit-pain-point-finder/widget/result-shell.tsx +203 -0
  242. package/src/features/tools/reddit-pain-point-finder/widget/types.ts +15 -0
  243. package/src/features/tools/registry.ts +288 -0
  244. package/src/features/tools/runtime-registry.ts +186 -0
  245. package/src/features/tools/shared/create-guide-stack-container.tsx +176 -0
  246. package/src/features/tools/shared/create-standard-landing-container.tsx +163 -0
  247. package/src/features/tools/shared/tool-content-sections.tsx +659 -0
  248. package/src/features/tools/shared/tool-cta.tsx +66 -0
  249. package/src/features/tools/shared/tool-draft-view.tsx +53 -0
  250. package/src/features/tools/shared/tool-guide-section.tsx +191 -0
  251. package/src/features/tools/shared/tool-handoff.tsx +38 -0
  252. package/src/features/tools/shared/tool-mcp-badge.tsx +23 -0
  253. package/src/features/tools/shared/tool-message-translator.ts +37 -0
  254. package/src/features/tools/shared/tool-page-shell.tsx +348 -0
  255. package/src/features/tools/shared/tool-standard-generation-steps.tsx +52 -0
  256. package/src/features/tools/shared/tool-standard-landing-sections.tsx +447 -0
  257. package/src/features/tools/shared/tool-ui-registry.ts +237 -0
  258. package/src/features/tools/shared/tool-widget-slot.tsx +29 -0
  259. package/src/features/tools/slogan-generator/slogan-generator.package.ts +641 -0
  260. package/src/features/tools/social-listening-research-report/social-listening-research-report.container.tsx +124 -0
  261. package/src/features/tools/social-listening-research-report/social-listening-research-report.spec.ts +15 -0
  262. package/src/features/tools/social-listening-research-report/widget/constants.ts +4 -0
  263. package/src/features/tools/social-listening-research-report/widget/index.ts +7 -0
  264. package/src/features/tools/social-listening-research-report/widget/preview-panels.tsx +73 -0
  265. package/src/features/tools/social-listening-research-report/widget/result-shell.tsx +216 -0
  266. package/src/features/tools/social-listening-research-report/widget/social-listening-research-report.tsx +303 -0
  267. package/src/features/tools/social-listening-research-report/widget/types.ts +15 -0
  268. package/src/features/tools/social-platform-asset-adapter/social-platform-asset-adapter.container.tsx +123 -0
  269. package/src/features/tools/social-platform-asset-adapter/social-platform-asset-adapter.spec.ts +15 -0
  270. package/src/features/tools/social-platform-asset-adapter/widget/constants.ts +43 -0
  271. package/src/features/tools/social-platform-asset-adapter/widget/helpers.ts +249 -0
  272. package/src/features/tools/social-platform-asset-adapter/widget/index.ts +7 -0
  273. package/src/features/tools/social-platform-asset-adapter/widget/result-shell.tsx +350 -0
  274. package/src/features/tools/social-platform-asset-adapter/widget/section-heading.tsx +18 -0
  275. package/src/features/tools/social-platform-asset-adapter/widget/social-platform-asset-adapter.tsx +641 -0
  276. package/src/features/tools/social-platform-asset-adapter/widget/types.ts +40 -0
  277. package/src/features/tools/social-profile-kit/social-profile-kit.container.tsx +177 -0
  278. package/src/features/tools/social-profile-kit/social-profile-kit.spec.ts +15 -0
  279. package/src/features/tools/social-profile-kit/widget/context-editor.tsx +171 -0
  280. package/src/features/tools/social-profile-kit/widget/generation-runtime.ts +281 -0
  281. package/src/features/tools/social-profile-kit/widget/index.ts +7 -0
  282. package/src/features/tools/social-profile-kit/widget/input-panel.tsx +294 -0
  283. package/src/features/tools/social-profile-kit/widget/platform-dock.tsx +115 -0
  284. package/src/features/tools/social-profile-kit/widget/profile-canvas.tsx +318 -0
  285. package/src/features/tools/social-profile-kit/widget/profile-preview/bluesky-preview.tsx +188 -0
  286. package/src/features/tools/social-profile-kit/widget/profile-preview/facebook-preview.tsx +168 -0
  287. package/src/features/tools/social-profile-kit/widget/profile-preview/index.ts +1 -0
  288. package/src/features/tools/social-profile-kit/widget/profile-preview/instagram-preview.tsx +278 -0
  289. package/src/features/tools/social-profile-kit/widget/profile-preview/linkedin-preview.tsx +358 -0
  290. package/src/features/tools/social-profile-kit/widget/profile-preview/profile-preview.tsx +348 -0
  291. package/src/features/tools/social-profile-kit/widget/profile-preview/shared.tsx +391 -0
  292. package/src/features/tools/social-profile-kit/widget/profile-preview/threads-preview.tsx +148 -0
  293. package/src/features/tools/social-profile-kit/widget/profile-preview/tiktok-preview.tsx +319 -0
  294. package/src/features/tools/social-profile-kit/widget/profile-preview/x-preview.tsx +341 -0
  295. package/src/features/tools/social-profile-kit/widget/profile-preview/youtube-preview.tsx +297 -0
  296. package/src/features/tools/social-profile-kit/widget/social-profile-kit-generator.tsx +1059 -0
  297. package/src/features/tools/social-profile-kit/widget/types.ts +104 -0
  298. package/src/features/tools/spec-registry.ts +158 -0
  299. package/src/features/tools/startup-idea-research/startup-idea-research.container.tsx +111 -0
  300. package/src/features/tools/startup-idea-research/startup-idea-research.spec.ts +15 -0
  301. package/src/features/tools/startup-idea-research/widget/constants.ts +11 -0
  302. package/src/features/tools/startup-idea-research/widget/index.ts +7 -0
  303. package/src/features/tools/startup-idea-research/widget/preview-panels.tsx +67 -0
  304. package/src/features/tools/startup-idea-research/widget/result-shell.tsx +323 -0
  305. package/src/features/tools/startup-idea-research/widget/startup-idea-research.tsx +272 -0
  306. package/src/features/tools/startup-idea-research/widget/types.ts +21 -0
  307. package/src/features/tools/tarot-reading/tarot-reading.container.tsx +412 -0
  308. package/src/features/tools/tarot-reading/tarot-reading.spec.ts +15 -0
  309. package/src/features/tools/tarot-reading/widget/cards.tsx +152 -0
  310. package/src/features/tools/tarot-reading/widget/constants.ts +69 -0
  311. package/src/features/tools/tarot-reading/widget/deck-view.tsx +86 -0
  312. package/src/features/tools/tarot-reading/widget/deck.ts +86 -0
  313. package/src/features/tools/tarot-reading/widget/index.ts +7 -0
  314. package/src/features/tools/tarot-reading/widget/landing-view.tsx +209 -0
  315. package/src/features/tools/tarot-reading/widget/reading-copy.tsx +138 -0
  316. package/src/features/tools/tarot-reading/widget/reading-view.tsx +189 -0
  317. package/src/features/tools/tarot-reading/widget/reveal-view.tsx +50 -0
  318. package/src/features/tools/tarot-reading/widget/ritual-view.tsx +276 -0
  319. package/src/features/tools/tarot-reading/widget/tarot-reading.tsx +262 -0
  320. package/src/features/tools/tarot-reading/widget/types.ts +22 -0
  321. package/src/features/tools/twitter-gif-downloader/twitter-gif-downloader.container.tsx +114 -0
  322. package/src/features/tools/twitter-gif-downloader/twitter-gif-downloader.spec.ts +14 -0
  323. package/src/features/tools/twitter-gif-downloader/widget/index.ts +7 -0
  324. package/src/features/tools/twitter-gif-downloader/widget/twitter-gif-downloader.tsx +351 -0
  325. package/src/features/tools/types.ts +68 -0
  326. package/src/features/tools/user-interview-guide-generator/user-interview-guide-generator.package.ts +774 -0
  327. package/src/features/tools/user-interview-insight-report-generator/user-interview-insight-report-generator.container.tsx +23 -0
  328. package/src/features/tools/user-interview-insight-report-generator/user-interview-insight-report-generator.spec.ts +14 -0
  329. package/src/features/tools/user-interview-insight-report-generator/widget/constants.ts +8 -0
  330. package/src/features/tools/user-interview-insight-report-generator/widget/helpers.ts +4 -0
  331. package/src/features/tools/user-interview-insight-report-generator/widget/index.ts +7 -0
  332. package/src/features/tools/user-interview-insight-report-generator/widget/preview-panels.tsx +55 -0
  333. package/src/features/tools/user-interview-insight-report-generator/widget/result-shell.tsx +122 -0
  334. package/src/features/tools/user-interview-insight-report-generator/widget/types.ts +16 -0
  335. package/src/features/tools/user-interview-insight-report-generator/widget/user-interview-insight-report-generator.tsx +293 -0
  336. package/src/features/tools/user-interview-record-generator/user-interview-record-generator.container.tsx +18 -0
  337. package/src/features/tools/user-interview-record-generator/user-interview-record-generator.spec.ts +14 -0
  338. package/src/features/tools/user-interview-record-generator/widget/constants.ts +9 -0
  339. package/src/features/tools/user-interview-record-generator/widget/helpers.ts +4 -0
  340. package/src/features/tools/user-interview-record-generator/widget/index.ts +7 -0
  341. package/src/features/tools/user-interview-record-generator/widget/preview-panels.tsx +48 -0
  342. package/src/features/tools/user-interview-record-generator/widget/result-shell.tsx +128 -0
  343. package/src/features/tools/user-interview-record-generator/widget/types.ts +16 -0
  344. package/src/features/tools/user-interview-record-generator/widget/user-interview-record-generator.tsx +305 -0
  345. package/src/features/tools/utm-builder/utm-builder.package.ts +846 -0
  346. package/src/features/tools/widget-registry.ts +73 -0
  347. package/src/generated/mcp-tools-registry.json +17 -0
  348. package/src/host/client-proxy.test.ts +33 -0
  349. package/src/host/client.ts +678 -0
  350. package/src/host/server.ts +119 -0
  351. package/src/i18n/client.ts +11 -0
  352. package/src/i18n/locale-fallback.ts +38 -0
  353. package/src/i18n/locale.ts +18 -0
  354. package/src/i18n/messages/en/page/tools.ts +124 -0
  355. package/src/i18n/messages/en/tools/app-icon-resizer.ts +244 -0
  356. package/src/i18n/messages/en/tools/app-store-screenshot-generator.ts +145 -0
  357. package/src/i18n/messages/en/tools/build-in-public-story-generator.ts +229 -0
  358. package/src/i18n/messages/en/tools/cold-start-channel-selector.ts +423 -0
  359. package/src/i18n/messages/en/tools/commercial-bp-generator.ts +304 -0
  360. package/src/i18n/messages/en/tools/community-feedback-inbox.ts +218 -0
  361. package/src/i18n/messages/en/tools/community-pain-point-extractor.ts +230 -0
  362. package/src/i18n/messages/en/tools/community-post-risk-checker.ts +209 -0
  363. package/src/i18n/messages/en/tools/competitor-analysis.ts +197 -0
  364. package/src/i18n/messages/en/tools/email-template-generator.ts +302 -0
  365. package/src/i18n/messages/en/tools/engine.ts +69 -0
  366. package/src/i18n/messages/en/tools/gtm-readiness-checklist.ts +166 -0
  367. package/src/i18n/messages/en/tools/index.ts +73 -0
  368. package/src/i18n/messages/en/tools/koko-codex-assistant.ts +171 -0
  369. package/src/i18n/messages/en/tools/logo-generator.ts +173 -0
  370. package/src/i18n/messages/en/tools/market-forecast-report.ts +228 -0
  371. package/src/i18n/messages/en/tools/million-user-growth-test.ts +386 -0
  372. package/src/i18n/messages/en/tools/og-image-generator.ts +172 -0
  373. package/src/i18n/messages/en/tools/pitch-deck-generator.ts +358 -0
  374. package/src/i18n/messages/en/tools/product-agreement-generator.ts +411 -0
  375. package/src/i18n/messages/en/tools/product-hunt-launch-planner.ts +272 -0
  376. package/src/i18n/messages/en/tools/product-name-generator.ts +383 -0
  377. package/src/i18n/messages/en/tools/product-poster-generator.ts +294 -0
  378. package/src/i18n/messages/en/tools/product-ui-generator.ts +234 -0
  379. package/src/i18n/messages/en/tools/reddit-pain-point-finder.ts +163 -0
  380. package/src/i18n/messages/en/tools/shared.ts +24 -0
  381. package/src/i18n/messages/en/tools/social-listening-research-report.ts +185 -0
  382. package/src/i18n/messages/en/tools/social-media-profile-generator.ts +22 -0
  383. package/src/i18n/messages/en/tools/social-platform-asset-adapter.ts +287 -0
  384. package/src/i18n/messages/en/tools/social-profile-kit.ts +150 -0
  385. package/src/i18n/messages/en/tools/startup-idea-research.ts +170 -0
  386. package/src/i18n/messages/en/tools/tarot-reading.ts +230 -0
  387. package/src/i18n/messages/en/tools/twitter-gif-downloader.ts +145 -0
  388. package/src/i18n/messages/en/tools/user-interview-insight-report-generator.ts +242 -0
  389. package/src/i18n/messages/en/tools/user-interview-record-generator.ts +244 -0
  390. package/src/i18n/messages/en/tools-ui.ts +704 -0
  391. package/src/i18n/messages/zh/page/tools.ts +124 -0
  392. package/src/i18n/messages/zh/tools/app-icon-resizer.ts +242 -0
  393. package/src/i18n/messages/zh/tools/app-store-screenshot-generator.ts +145 -0
  394. package/src/i18n/messages/zh/tools/build-in-public-story-generator.ts +230 -0
  395. package/src/i18n/messages/zh/tools/cold-start-channel-selector.ts +422 -0
  396. package/src/i18n/messages/zh/tools/commercial-bp-generator.ts +302 -0
  397. package/src/i18n/messages/zh/tools/community-feedback-inbox.ts +217 -0
  398. package/src/i18n/messages/zh/tools/community-pain-point-extractor.ts +230 -0
  399. package/src/i18n/messages/zh/tools/community-post-risk-checker.ts +200 -0
  400. package/src/i18n/messages/zh/tools/competitor-analysis.ts +192 -0
  401. package/src/i18n/messages/zh/tools/email-template-generator.ts +302 -0
  402. package/src/i18n/messages/zh/tools/engine.ts +68 -0
  403. package/src/i18n/messages/zh/tools/gtm-readiness-checklist.ts +166 -0
  404. package/src/i18n/messages/zh/tools/index.ts +73 -0
  405. package/src/i18n/messages/zh/tools/koko-codex-assistant.ts +170 -0
  406. package/src/i18n/messages/zh/tools/logo-generator.ts +172 -0
  407. package/src/i18n/messages/zh/tools/market-forecast-report.ts +228 -0
  408. package/src/i18n/messages/zh/tools/million-user-growth-test.ts +385 -0
  409. package/src/i18n/messages/zh/tools/og-image-generator.ts +173 -0
  410. package/src/i18n/messages/zh/tools/pitch-deck-generator.ts +358 -0
  411. package/src/i18n/messages/zh/tools/product-agreement-generator.ts +401 -0
  412. package/src/i18n/messages/zh/tools/product-hunt-launch-planner.ts +267 -0
  413. package/src/i18n/messages/zh/tools/product-name-generator.ts +383 -0
  414. package/src/i18n/messages/zh/tools/product-poster-generator.ts +282 -0
  415. package/src/i18n/messages/zh/tools/product-ui-generator.ts +234 -0
  416. package/src/i18n/messages/zh/tools/reddit-pain-point-finder.ts +162 -0
  417. package/src/i18n/messages/zh/tools/shared.ts +24 -0
  418. package/src/i18n/messages/zh/tools/social-listening-research-report.ts +181 -0
  419. package/src/i18n/messages/zh/tools/social-media-profile-generator.ts +22 -0
  420. package/src/i18n/messages/zh/tools/social-platform-asset-adapter.ts +284 -0
  421. package/src/i18n/messages/zh/tools/social-profile-kit.ts +150 -0
  422. package/src/i18n/messages/zh/tools/startup-idea-research.ts +165 -0
  423. package/src/i18n/messages/zh/tools/tarot-reading.ts +228 -0
  424. package/src/i18n/messages/zh/tools/twitter-gif-downloader.ts +138 -0
  425. package/src/i18n/messages/zh/tools/user-interview-insight-report-generator.ts +224 -0
  426. package/src/i18n/messages/zh/tools/user-interview-record-generator.ts +226 -0
  427. package/src/i18n/messages/zh/tools-ui.ts +684 -0
  428. package/src/i18n/messages/zh-tw/page/tools.ts +115 -0
  429. package/src/i18n/messages/zh-tw/tools/app-icon-resizer.ts +242 -0
  430. package/src/i18n/messages/zh-tw/tools/app-store-screenshot-generator.ts +145 -0
  431. package/src/i18n/messages/zh-tw/tools/build-in-public-story-generator.ts +230 -0
  432. package/src/i18n/messages/zh-tw/tools/cold-start-channel-selector.ts +440 -0
  433. package/src/i18n/messages/zh-tw/tools/commercial-bp-generator.ts +302 -0
  434. package/src/i18n/messages/zh-tw/tools/community-feedback-inbox.ts +217 -0
  435. package/src/i18n/messages/zh-tw/tools/community-pain-point-extractor.ts +230 -0
  436. package/src/i18n/messages/zh-tw/tools/community-post-risk-checker.ts +200 -0
  437. package/src/i18n/messages/zh-tw/tools/competitor-analysis.ts +192 -0
  438. package/src/i18n/messages/zh-tw/tools/email-template-generator.ts +302 -0
  439. package/src/i18n/messages/zh-tw/tools/engine.ts +68 -0
  440. package/src/i18n/messages/zh-tw/tools/gtm-readiness-checklist.ts +166 -0
  441. package/src/i18n/messages/zh-tw/tools/index.ts +73 -0
  442. package/src/i18n/messages/zh-tw/tools/koko-codex-assistant.ts +170 -0
  443. package/src/i18n/messages/zh-tw/tools/logo-generator.ts +71 -0
  444. package/src/i18n/messages/zh-tw/tools/market-forecast-report.ts +228 -0
  445. package/src/i18n/messages/zh-tw/tools/million-user-growth-test.ts +385 -0
  446. package/src/i18n/messages/zh-tw/tools/og-image-generator.ts +173 -0
  447. package/src/i18n/messages/zh-tw/tools/pitch-deck-generator.ts +358 -0
  448. package/src/i18n/messages/zh-tw/tools/product-agreement-generator.ts +401 -0
  449. package/src/i18n/messages/zh-tw/tools/product-hunt-launch-planner.ts +267 -0
  450. package/src/i18n/messages/zh-tw/tools/product-name-generator.ts +383 -0
  451. package/src/i18n/messages/zh-tw/tools/product-poster-generator.ts +282 -0
  452. package/src/i18n/messages/zh-tw/tools/product-ui-generator.ts +234 -0
  453. package/src/i18n/messages/zh-tw/tools/reddit-pain-point-finder.ts +162 -0
  454. package/src/i18n/messages/zh-tw/tools/shared.ts +24 -0
  455. package/src/i18n/messages/zh-tw/tools/social-listening-research-report.ts +181 -0
  456. package/src/i18n/messages/zh-tw/tools/social-media-profile-generator.ts +22 -0
  457. package/src/i18n/messages/zh-tw/tools/social-platform-asset-adapter.ts +284 -0
  458. package/src/i18n/messages/zh-tw/tools/social-profile-kit.ts +150 -0
  459. package/src/i18n/messages/zh-tw/tools/startup-idea-research.ts +165 -0
  460. package/src/i18n/messages/zh-tw/tools/tarot-reading.ts +228 -0
  461. package/src/i18n/messages/zh-tw/tools/twitter-gif-downloader.ts +138 -0
  462. package/src/i18n/messages/zh-tw/tools/user-interview-insight-report-generator.ts +224 -0
  463. package/src/i18n/messages/zh-tw/tools/user-interview-record-generator.ts +226 -0
  464. package/src/i18n/messages/zh-tw/tools-ui.ts +525 -0
  465. package/src/index.ts +15 -0
  466. package/src/lib/activity-task-handoff.ts +404 -0
  467. package/src/lib/api/errors.ts +39 -0
  468. package/src/lib/app-origin.ts +30 -0
  469. package/src/lib/fact-claim-contract.ts +68 -0
  470. package/src/lib/fake-delay.ts +3 -0
  471. package/src/lib/file/download.ts +10 -0
  472. package/src/lib/routing/locale-paths.ts +27 -0
  473. package/src/lib/seo-meta.ts +3 -0
  474. package/src/lib/tools/app-icon-resizer-schema.ts +191 -0
  475. package/src/lib/tools/app-store-screenshot-generator-schema.ts +185 -0
  476. package/src/lib/tools/build-in-public-story-generator-schema.ts +67 -0
  477. package/src/lib/tools/build-in-public-story-generator.format.ts +507 -0
  478. package/src/lib/tools/cold-start-channel-selector-schema.ts +147 -0
  479. package/src/lib/tools/commercial-bp-generator-schema.ts +222 -0
  480. package/src/lib/tools/community-feedback-inbox-schema.ts +125 -0
  481. package/src/lib/tools/community-feedback-inbox.format.ts +764 -0
  482. package/src/lib/tools/community-pain-point-extractor-schema.ts +166 -0
  483. package/src/lib/tools/community-post-risk-checker-schema.ts +99 -0
  484. package/src/lib/tools/community-post-risk-checker.format.ts +557 -0
  485. package/src/lib/tools/competitor-analysis-schema.ts +144 -0
  486. package/src/lib/tools/draft-preview-access.ts +3 -0
  487. package/src/lib/tools/draft-store.ts +69 -0
  488. package/src/lib/tools/email-template-generator-schema.ts +124 -0
  489. package/src/lib/tools/gtm-checklist-copy.ts +57 -0
  490. package/src/lib/tools/gtm-checklist-structure.ts +37 -0
  491. package/src/lib/tools/image-download.ts +68 -0
  492. package/src/lib/tools/input-quality.ts +97 -0
  493. package/src/lib/tools/logo-generator-schema.ts +224 -0
  494. package/src/lib/tools/market-forecast-report-schema.ts +299 -0
  495. package/src/lib/tools/mcp-registry.ts +16 -0
  496. package/src/lib/tools/mcp-types.ts +18 -0
  497. package/src/lib/tools/million-user-growth-test-schema.ts +49 -0
  498. package/src/lib/tools/million-user-growth-test.ts +181 -0
  499. package/src/lib/tools/og-image-generator-render.ts +448 -0
  500. package/src/lib/tools/og-image-generator-schema.ts +140 -0
  501. package/src/lib/tools/ops-catalog.ts +102 -0
  502. package/src/lib/tools/pitch-deck-generator-schema.ts +182 -0
  503. package/src/lib/tools/pitch-deck-package.ts +0 -0
  504. package/src/lib/tools/product-agreement-generator-schema.ts +168 -0
  505. package/src/lib/tools/product-hunt-launch-planner-schema.ts +136 -0
  506. package/src/lib/tools/product-hunt-launch-planner.format.ts +72 -0
  507. package/src/lib/tools/product-name-generator-schema.ts +563 -0
  508. package/src/lib/tools/product-poster-generator-schema.ts +215 -0
  509. package/src/lib/tools/product-ui-generator-schema.ts +157 -0
  510. package/src/lib/tools/reddit-pain-point-finder-schema.ts +88 -0
  511. package/src/lib/tools/resolve-tool-locale-copy.ts +75 -0
  512. package/src/lib/tools/slug.ts +60 -0
  513. package/src/lib/tools/social-listening-research-report-schema.ts +105 -0
  514. package/src/lib/tools/social-platform-asset-adapter-schema.ts +152 -0
  515. package/src/lib/tools/social-profile-kit.constants.ts +12 -0
  516. package/src/lib/tools/social-profile-kit.generation.ts +257 -0
  517. package/src/lib/tools/social-profile-kit.input.ts +290 -0
  518. package/src/lib/tools/social-profile-kit.manual.ts +481 -0
  519. package/src/lib/tools/social-profile-kit.package.ts +220 -0
  520. package/src/lib/tools/social-profile-kit.schema.ts +328 -0
  521. package/src/lib/tools/startup-idea-research-schema.ts +107 -0
  522. package/src/lib/tools/tarot-imagery.ts +89 -0
  523. package/src/lib/tools/tarot-reading.ts +1044 -0
  524. package/src/lib/tools/tool-message-keys.ts +18 -0
  525. package/src/lib/tools/types.ts +32 -0
  526. package/src/lib/tools/user-interview.format.ts +147 -0
  527. package/src/lib/tools/user-interview.generation.ts +670 -0
  528. package/src/lib/tools/user-interview.schema.ts +192 -0
  529. package/src/lib/zip.ts +106 -0
  530. package/src/services/tools/handlers/gtm-readiness-checklist.ts +71 -0
  531. package/src/services/tools/handlers/types.ts +7 -0
@@ -0,0 +1,339 @@
1
+ import { z } from "zod";
2
+
3
+ import type { ToolPackage } from "../package/types";
4
+
5
+ const t = (en: string, zh: string, zhTw: string) => ({ en, zh, "zh-tw": zhTw });
6
+ const list = (en: string[], zh: string[], zhTw: string[]) => ({ en, zh, "zh-tw": zhTw });
7
+
8
+ const resultSchema = z.object({
9
+ summary: z.string().min(1),
10
+ disclaimerTitle: z.string().min(1),
11
+ disclaimerMarkdown: z.string().min(80),
12
+ coverageSummary: z.array(z.string()).min(2).max(8),
13
+ suggestedPlacements: z.array(z.string()).min(1).max(5),
14
+ riskFlags: z
15
+ .array(
16
+ z.object({
17
+ level: z.enum(["info", "warning", "critical"]),
18
+ label: z.string().min(1),
19
+ detail: z.string().min(1),
20
+ }),
21
+ )
22
+ .min(1),
23
+ missingInfo: z.array(z.string()),
24
+ reviewChecklist: z.array(z.string()).min(2),
25
+ disclaimer: z.string().min(1),
26
+ generatedAt: z.string().min(1),
27
+ promptVersion: z.string().min(1),
28
+ });
29
+
30
+ export const disclaimerGeneratorPackage: ToolPackage = {
31
+ meta: {
32
+ slug: "disclaimer-generator",
33
+ toolType: "generator",
34
+ riskLevel: "high",
35
+ keywordEvidence: "docs/seo-keyword-briefs/disclaimer-generator.md",
36
+ seo: {
37
+ updatedAt: "2026-07-10",
38
+ readingTime: "6 min",
39
+ ogImage: "/tools/disclaimer-generator-section-primary.webp",
40
+ },
41
+ },
42
+ copy: {
43
+ title: t("Disclaimer Generator", "免责声明生成器", "免責聲明產生器"),
44
+ description: t(
45
+ "Create a tailored website, affiliate, review, or professional-information disclaimer draft with placement guidance, missing facts, risk flags, and a human review checklist.",
46
+ "根据业务和发布场景生成网站、联盟、评测或专业信息免责声明草案,并提供放置建议、缺失信息、风险提示与人工复核清单。",
47
+ "依照業務與發布情境產生網站、聯盟、評測或專業資訊免責聲明草案,並提供放置建議、缺漏資訊、風險提示與人工複核清單。",
48
+ ),
49
+ intro: t(
50
+ "Describe what you publish and where it appears. Get a clear draft you can copy, plus the facts and review steps needed before you publish it.",
51
+ "描述你发布的内容和使用位置,获得一份可复制的清晰草案,以及发布前仍需确认的事实和复核步骤。",
52
+ "描述你發布的內容與使用位置,取得可複製的清楚草案,以及發布前仍須確認的事實與複核步驟。",
53
+ ),
54
+ category: t("Legal and compliance tools", "法律与合规工具", "法律與合規工具"),
55
+ keywords: list(
56
+ ["disclaimer generator", "website disclaimer", "affiliate disclaimer generator", "copyright disclaimer generator"],
57
+ ["免责声明生成器", "网站免责声明", "联盟披露声明", "版权免责声明生成器"],
58
+ ["免責聲明產生器", "網站免責聲明", "聯盟揭露聲明", "版權免責聲明產生器"],
59
+ ),
60
+ inputSignal: t(
61
+ "Your content, publication surface, and the disclosure you need",
62
+ "内容、发布位置与所需披露类型",
63
+ "內容、發布位置與所需揭露類型",
64
+ ),
65
+ outputSignal: t(
66
+ "Copyable draft, placement guidance, risks, and review steps",
67
+ "可复制草案、放置建议、风险与复核步骤",
68
+ "可複製草案、放置建議、風險與複核步驟",
69
+ ),
70
+ boundarySignal: t(
71
+ "Drafting support only — review with qualified counsel before publication",
72
+ "仅供草案辅助,发布前请由合格专业人士复核",
73
+ "僅供草案輔助,發布前請由合格專業人士複核",
74
+ ),
75
+ },
76
+ form: [
77
+ {
78
+ kind: "textarea",
79
+ id: "businessDescription",
80
+ required: true,
81
+ fullWidth: true,
82
+ rows: 4,
83
+ minLength: 16,
84
+ label: t("What are you publishing?", "你要发布什么内容?", "你要發布什麼內容?"),
85
+ hint: t(
86
+ "Say what you offer, who it is for, and any claims, relationships, or advice involved.",
87
+ "写清你提供什么、面向谁,以及其中涉及的承诺、关系或建议。",
88
+ "寫清你提供什麼、面向誰,以及其中涉及的承諾、關係或建議。",
89
+ ),
90
+ placeholder: t(
91
+ "e.g. A wellness blog that reviews supplements and earns commission through affiliate links.",
92
+ "例如:一个评测营养补充剂并通过联盟链接获得佣金的健康博客。",
93
+ "例如:一個評測營養補充品並透過聯盟連結取得佣金的健康部落格。",
94
+ ),
95
+ invalidMessage: t(
96
+ "Describe the content, audience, and any claims or relationships. A product name alone is not enough.",
97
+ "请描述内容、受众以及涉及的承诺或关系;只填写名称还不够。",
98
+ "請描述內容、受眾以及涉及的承諾或關係;只填寫名稱還不夠。",
99
+ ),
100
+ },
101
+ {
102
+ kind: "select",
103
+ id: "publicationSurface",
104
+ defaultValue: "website",
105
+ label: t("Where will it appear?", "将发布在哪里?", "將發布在哪裡?"),
106
+ options: [
107
+ { value: "website", label: t("Website or landing page", "网站或落地页", "網站或 Landing page") },
108
+ { value: "blog", label: t("Blog or article", "博客或文章", "部落格或文章") },
109
+ { value: "app", label: t("App or product interface", "应用或产品界面", "應用程式或產品介面") },
110
+ { value: "video", label: t("Video or social post", "视频或社媒帖子", "影片或社群貼文") },
111
+ { value: "email", label: t("Newsletter or marketing email", "订阅通讯或营销邮件", "電子報或行銷郵件") },
112
+ ],
113
+ },
114
+ {
115
+ kind: "select",
116
+ id: "disclaimerFocus",
117
+ defaultValue: "general",
118
+ label: t("What needs to be disclosed?", "主要需要披露什么?", "主要需要揭露什麼?"),
119
+ options: [
120
+ { value: "general", label: t("General information and external links", "一般信息与外部链接", "一般資訊與外部連結") },
121
+ { value: "affiliate", label: t("Affiliate links or sponsorships", "联盟链接或赞助关系", "聯盟連結或贊助關係") },
122
+ { value: "review", label: t("Reviews, endorsements, or testimonials", "评测、背书或推荐", "評測、背書或推薦") },
123
+ { value: "professional", label: t("Professional, legal, or financial information", "专业、法律或金融信息", "專業、法律或金融資訊") },
124
+ { value: "health", label: t("Health, wellness, or fitness information", "健康、养生或健身信息", "健康、養生或健身資訊") },
125
+ { value: "copyright", label: t("Copyright, fair use, or third-party material", "版权、合理使用或第三方素材", "版權、合理使用或第三方素材") },
126
+ ],
127
+ },
128
+ {
129
+ kind: "select",
130
+ id: "audienceMarket",
131
+ defaultValue: "global",
132
+ label: t("Main audience market", "主要受众市场", "主要受眾市場"),
133
+ hint: t(
134
+ "Context only: this review MVP returns an English, non-jurisdiction-specific draft — not localized legal advice.",
135
+ "仅作背景参考:当前 review 版只返回英文、非特定法域草案,不提供本地化法律建议。",
136
+ "僅作背景參考:目前 review 版只會提供英文、非特定法域草案,不提供在地化法律建議。",
137
+ ),
138
+ options: [
139
+ { value: "global", label: t("Global / mixed audience", "全球 / 混合受众", "全球/混合受眾") },
140
+ { value: "us", label: t("United States", "美国", "美國") },
141
+ ],
142
+ },
143
+ {
144
+ kind: "textarea",
145
+ id: "additionalContext",
146
+ rows: 3,
147
+ label: t("Details to include (optional)", "需补充的细节(选填)", "需補充的細節(選填)"),
148
+ hint: t(
149
+ "Add your business name, affiliate program, paid relationship, product claim, or a fact that must not be invented.",
150
+ "可补充企业名称、联盟计划、付费关系、产品宣称或任何不可虚构的事实。",
151
+ "可補充公司名稱、聯盟計畫、付費關係、產品宣稱或任何不可虛構的事實。",
152
+ ),
153
+ placeholder: t(
154
+ "e.g. We earn commission from Amazon links; do not claim that supplements treat or cure any condition.",
155
+ "例如:我们会从 Amazon 链接获得佣金;不要声称补充剂能够治疗或治愈任何疾病。",
156
+ "例如:我們會從 Amazon 連結取得佣金;不要聲稱補充品能治療或治癒任何疾病。",
157
+ ),
158
+ },
159
+ ],
160
+ runtime: {
161
+ lane: "agent",
162
+ scene: "disclaimer_generator",
163
+ resultType: "disclaimer_draft",
164
+ skillId: "$disclaimer-generator",
165
+ writebackScript: "disclaimer-generator.mjs",
166
+ outputContract: [
167
+ "summary: string",
168
+ "disclaimerTitle: string",
169
+ "disclaimerMarkdown: string",
170
+ "coverageSummary: string[]",
171
+ "suggestedPlacements: string[]",
172
+ "riskFlags: [{ level: info|warning|critical, label: string, detail: string }]",
173
+ "missingInfo: string[]",
174
+ "reviewChecklist: string[]",
175
+ "disclaimer: string",
176
+ "generatedAt: ISO timestamp",
177
+ "promptVersion: string",
178
+ ],
179
+ rules: [
180
+ "Write only a tailored first-draft disclaimer from the current brief; never present it as legal advice, legal compliance, or a final policy.",
181
+ "Do not invent business names, legal entities, affiliate relationships, qualifications, product claims, jurisdictional rules, or third-party terms. Put unknown facts in missingInfo and reviewChecklist.",
182
+ "For this review MVP, write the legal draft fields in English even when the UI locale is Chinese; audienceMarket supports only global or United States context and does not imply a translated or jurisdiction-localized legal opinion.",
183
+ "For medical, health, legal, financial, investment, professional, or children-related content, add a high-risk flag and require review by qualified counsel or the responsible professional before publication.",
184
+ "The final user-visible result must be written through the named Skill script as resultType disclaimer_draft; do not return a local template or raw chat output.",
185
+ ],
186
+ watch: { pollIntervalMs: 1200, graceWindowMs: 90000 },
187
+ },
188
+ resultSchema,
189
+ resultView: [
190
+ {
191
+ block: "keyValues",
192
+ title: t("Your draft", "你的草案", "你的草案"),
193
+ items: [
194
+ { label: t("Summary", "摘要", "摘要"), path: "summary" },
195
+ { label: t("Title", "标题", "標題"), path: "disclaimerTitle" },
196
+ { label: t("Copyable disclaimer", "可复制免责声明", "可複製免責聲明"), path: "disclaimerMarkdown", copyable: true },
197
+ ],
198
+ },
199
+ {
200
+ block: "bulletGroups",
201
+ title: t("What it covers and where to use it", "覆盖内容与建议放置位置", "涵蓋內容與建議放置位置"),
202
+ columns: [
203
+ { label: t("Coverage", "覆盖内容", "涵蓋內容"), path: "coverageSummary", tone: "positive" },
204
+ { label: t("Suggested placement", "建议放置位置", "建議放置位置"), path: "suggestedPlacements" },
205
+ ],
206
+ },
207
+ {
208
+ block: "cardList",
209
+ title: t("Review before publishing", "发布前请复核", "發布前請複核"),
210
+ path: "riskFlags",
211
+ layout: "stack",
212
+ card: {
213
+ titleField: "label",
214
+ metaField: "level",
215
+ body: { field: "detail", label: t("Why it matters", "为什么重要", "為什麼重要") },
216
+ },
217
+ },
218
+ {
219
+ block: "bulletGroups",
220
+ title: t("Details to confirm", "仍需确认的细节", "仍須確認的細節"),
221
+ columns: [
222
+ { label: t("Missing facts", "缺失事实", "缺漏事實"), path: "missingInfo", tone: "risk" },
223
+ { label: t("Review checklist", "复核清单", "複核清單"), path: "reviewChecklist", tone: "risk" },
224
+ ],
225
+ },
226
+ ],
227
+ widget: {
228
+ formTitle: t("Generate a tailored disclaimer draft", "生成贴合场景的免责声明草案", "產生符合情境的免責聲明草案"),
229
+ formHint: t(
230
+ "Start with the content and the disclosure you need. You will get a draft plus the facts to confirm before it goes live.",
231
+ "先说明内容和需要披露的事项。你会获得草案,以及上线前仍需确认的事实。",
232
+ "先說明內容與需要揭露的事項。你會取得草案,以及上線前仍須確認的事實。",
233
+ ),
234
+ submitLabel: t("Generate disclaimer draft", "生成免责声明草案", "產生免責聲明草案"),
235
+ resultTitle: t("Review your disclaimer draft", "复核你的免责声明草案", "複核你的免責聲明草案"),
236
+ pendingTitle: t("Preparing your disclaimer draft", "正在生成免责声明草案", "正在產生免責聲明草案"),
237
+ pendingHint: t(
238
+ "This usually takes a short moment. Your draft will include review points, not a claim of legal compliance.",
239
+ "通常只需片刻。结果会包含复核要点,不会宣称已经符合法律要求。",
240
+ "通常只需片刻。結果會包含複核要點,不會宣稱已符合法律要求。",
241
+ ),
242
+ errorOverrides: {
243
+ validation: {
244
+ title: t("Describe the content first", "请先描述发布内容", "請先描述發布內容"),
245
+ body: t(
246
+ "Add a real sentence about what you publish, who it is for, and any claims or relationships involved.",
247
+ "请用完整的话描述发布什么、面向谁,以及涉及的承诺或关系。",
248
+ "請用完整的話描述發布什麼、面向誰,以及涉及的承諾或關係。",
249
+ ),
250
+ },
251
+ },
252
+ },
253
+ page: {
254
+ workspace: {
255
+ heading: t("Create a disclaimer you can review", "生成一份便于复核的免责声明", "產生一份便於複核的免責聲明"),
256
+ hint: t(
257
+ "Describe your content and where it appears. Get a copyable draft, suggested placement, gaps to confirm, and a review checklist before you publish.",
258
+ "描述你的内容和发布位置,获得可复制草案、建议放置位置、待确认缺口和发布前复核清单。",
259
+ "描述你的內容與發布位置,取得可複製草案、建議放置位置、待確認缺口與發布前複核清單。",
260
+ ),
261
+ badge: t("Draft only — human review required", "仅为草案,需人工复核", "僅為草案,須人工複核"),
262
+ },
263
+ standard: {
264
+ benefits: {
265
+ title: t("Turn a rough publishing plan into a review-ready draft", "把粗略发布计划整理成可复核草案", "把粗略發布計畫整理成可複核草案"),
266
+ cards: [
267
+ {
268
+ title: t("Describe the content", "描述发布内容", "描述發布內容"),
269
+ body: t("Add your audience, claims, links, sponsorships, or advice in plain language.", "用日常语言写清受众、宣称、链接、赞助或建议。", "用日常語言寫清受眾、宣稱、連結、贊助或建議。"),
270
+ },
271
+ {
272
+ title: t("Choose the disclosure", "选择披露场景", "選擇揭露情境"),
273
+ body: t("Select the place and the main relationship or risk the statement needs to address.", "选择发布位置,以及声明需要处理的主要关系或风险。", "選擇發布位置,以及聲明需要處理的主要關係或風險。"),
274
+ },
275
+ {
276
+ title: t("Copy, confirm, and publish", "复制、确认后再发布", "複製、確認後再發布"),
277
+ body: t("Use the draft with its placement guidance, then resolve missing facts with the responsible reviewer.", "参考放置建议使用草案,再与负责人确认缺失事实。", "參考放置建議使用草案,再與負責人確認缺漏事實。"),
278
+ },
279
+ ],
280
+ },
281
+ imageTextSections: [
282
+ {
283
+ id: "section-primary",
284
+ title: t("Get more than a generic disclaimer template", "得到的不只是通用免责声明模板", "得到的不只是通用免責聲明範本"),
285
+ body: list(
286
+ ["The draft is based on your publishing surface and disclosure focus, not a blank one-size-fits-all paragraph.", "You also get a coverage summary and suggested placements, so the statement can be reviewed in the context where readers will actually see it."],
287
+ ["草案会结合发布位置和披露重点,而不是套用一段空泛的通用文本。", "你还会获得覆盖摘要和建议放置位置,便于在读者实际看到的语境中复核声明。"],
288
+ ["草案會結合發布位置與揭露重點,而不是套用一段空泛的通用文字。", "你還會取得涵蓋摘要與建議放置位置,方便在讀者實際看到的情境中複核聲明。"],
289
+ ),
290
+ image: { src: "/tools/disclaimer-generator-section-primary.webp", alt: t("A clear disclaimer draft beside a publishing checklist.", "清晰的免责声明草案与发布检查清单。", "清楚的免責聲明草案與發布檢查清單。"), side: "left" },
291
+ imageFirst: true,
292
+ },
293
+ {
294
+ id: "section-variation",
295
+ title: t("Match the disclosure to the publishing moment", "让披露与发布场景匹配", "讓揭露與發布情境相符"),
296
+ body: list(
297
+ ["Use an affiliate disclosure where readers see a recommendation or link, not buried on an unrelated page.", "For reviews, health, professional, or financial content, the result calls out the facts and higher-risk claims that need a qualified review before publication."],
298
+ ["联盟披露应出现在读者看到推荐或链接的位置,而不是埋在无关页面里。", "评测、健康、专业或金融内容会标出发布前需要由合格人员确认的事实与高风险宣称。"],
299
+ ["聯盟揭露應出現在讀者看到推薦或連結的位置,而不是藏在無關頁面裡。", "評測、健康、專業或金融內容會標出發布前需要由合格人員確認的事實與高風險宣稱。"],
300
+ ),
301
+ image: { src: "/tools/disclaimer-generator-section-variation.webp", alt: t("Different disclosure contexts for a blog, video, and website.", "博客、视频和网站的不同披露场景。", "部落格、影片與網站的不同揭露情境。"), side: "right" },
302
+ },
303
+ {
304
+ id: "section-support",
305
+ title: t("Use risk flags as a publishing stop sign", "把风险提示当作发布前的停下信号", "把風險提示當作發布前的暫停訊號"),
306
+ body: list(
307
+ ["The tool does not decide whether your content is compliant. It separates a useful first draft from unknown facts and review work.", "High-risk health, legal, financial, investment, and children-related content should be reviewed by the appropriate qualified professional before it is published."],
308
+ ["工具不会判断你的内容是否合规,而是把可用的一稿与未知事实、复核工作区分开。", "健康、法律、金融、投资及儿童相关的高风险内容,发布前应由合适的专业人士复核。"],
309
+ ["工具不會判定你的內容是否合規,而是把可用的初稿與未知事實、複核工作區分開。", "健康、法律、金融、投資及兒童相關的高風險內容,發布前應由適當的專業人士複核。"],
310
+ ),
311
+ image: { src: "/tools/disclaimer-generator-section-support.webp", alt: t("A publishing checklist highlighting facts and review before release.", "突出事实确认与复核的发布检查清单。", "突顯事實確認與複核的發布檢查清單。"), side: "left" },
312
+ imageFirst: true,
313
+ },
314
+ ],
315
+ generation: {
316
+ title: t("Use the draft in the right place", "把草案用在合适的位置", "把草案用在合適的位置"),
317
+ image: { src: "/tools/disclaimer-generator-section-steps.webp", alt: t("A creator placing a reviewed disclosure alongside a published article.", "创作者将已复核的披露声明放在发布文章旁。", "創作者將已複核的揭露聲明放在發布文章旁。"), side: "left" },
318
+ steps: [
319
+ { title: t("Read the draft against the real content", "结合真实内容阅读草案", "結合真實內容閱讀草案"), body: t("Check every claim, link, relationship, and named party against what will be published.", "逐项检查宣称、链接、关系和主体名称是否与实际发布内容一致。", "逐項檢查宣稱、連結、關係與主體名稱是否和實際發布內容一致。") },
320
+ { title: t("Resolve the missing facts", "补齐缺失事实", "補齊缺漏事實"), body: t("Replace placeholders and confirm the details that cannot be safely guessed.", "替换占位信息,并确认任何不能安全猜测的细节。", "替換預留資訊,並確認任何不能安全猜測的細節。") },
321
+ { title: t("Place it where the reader needs it", "放到读者需要看到的位置", "放在讀者需要看到的位置"), body: t("Use the suggested placement as a starting point, then have the responsible reviewer approve it before launch.", "把建议位置作为起点,并在上线前请负责人完成确认。", "把建議位置作為起點,並在上線前請負責人完成確認。") },
322
+ ],
323
+ ctaLabel: t("Generate a disclaimer draft", "生成免责声明草案", "產生免責聲明草案"),
324
+ },
325
+ faq: {
326
+ title: t("Disclaimer generator FAQs", "免责声明生成器常见问题", "免責聲明產生器常見問題"),
327
+ intro: t("Use the result as a practical starting point, then confirm the facts and review it before publication.", "把结果作为实用起点,再补齐事实并在发布前复核。", "把結果作為實用起點,再補齊事實並在發布前複核。"),
328
+ ctaLabel: t("Create a disclaimer draft", "生成免责声明草案", "產生免責聲明草案"),
329
+ },
330
+ },
331
+ faq: [
332
+ { question: t("What should an affiliate disclaimer say?", "联盟披露声明应该写什么?", "聯盟揭露聲明應該寫什麼?"), answer: t("It should plainly disclose the relationship that matters to a reader, such as a paid link, commission, sponsorship, or provided product. Confirm the real program terms and where the disclosure must appear before publishing.", "它应清楚披露读者需要知道的关系,例如付费链接、佣金、赞助或获赠产品。发布前请确认真实计划条款和披露位置要求。", "它應清楚揭露讀者需要知道的關係,例如付費連結、佣金、贊助或獲贈產品。發布前請確認真實計畫條款和揭露位置要求。") },
333
+ { question: t("Can I use this for health, financial, or legal content?", "可以用于健康、金融或法律内容吗?", "可以用於健康、金融或法律內容嗎?"), answer: t("You can use it to organize a draft and the facts that need review. It does not provide legal, medical, financial, or investment advice, and high-risk content needs review by the appropriate qualified professional before publication.", "你可以用它整理草案和待复核事实。它不提供法律、医疗、金融或投资建议;高风险内容发布前需要由相应专业人士复核。", "你可以用它整理草案和待複核事實。它不提供法律、醫療、金融或投資建議;高風險內容發布前需要由相應專業人士複核。") },
334
+ { question: t("Where should I put a website disclaimer?", "网站免责声明应该放在哪里?", "網站免責聲明應該放在哪裡?"), answer: t("Put it where the related reader decision happens: near an affiliate link or review, before relying on professional information, or on a clearly linked website page. The result suggests placement, but the final choice depends on your content and applicable requirements.", "应放在读者作出相关决定的位置:联盟链接或评测附近、依赖专业信息之前,或网站中清晰可访问的页面。结果会给出建议,但最终位置取决于你的内容和适用要求。", "應放在讀者做出相關決定的位置:聯盟連結或評測附近、依賴專業資訊之前,或網站中清楚可存取的頁面。結果會給出建議,但最終位置取決於你的內容和適用要求。") },
335
+ { question: t("Does a generated disclaimer make my website compliant?", "生成免责声明就代表网站合规吗?", "產生免責聲明就代表網站合規嗎?"), answer: t("No. This is drafting support, not a compliance conclusion or legal advice. Confirm the facts, the applicable requirements, and the final wording with the responsible reviewer or qualified counsel.", "不代表。这是草案辅助,不是合规结论或法律建议。请与负责人或合格法律顾问确认事实、适用要求和最终措辞。", "不代表。這是草案輔助,不是合規結論或法律建議。請與負責人或合格法律顧問確認事實、適用要求與最終措辭。") },
336
+ ],
337
+ },
338
+ assets: {},
339
+ };
@@ -0,0 +1,224 @@
1
+ import { createToolGuideTranslator } from "../shared/tool-message-translator";
2
+
3
+ import { EmailTemplateGenerator } from "./widget";
4
+
5
+ import {
6
+ ToolCardGrid,
7
+ ToolFaqSection,
8
+ } from "../shared/tool-content-sections";
9
+ import { ToolCta } from "../shared/tool-cta";
10
+ import { ToolImageVisual, ToolWorkspaceSection } from "../shared/tool-guide-section";
11
+ import { ToolPageShell } from "../shared/tool-page-shell";
12
+ import type { ToolPageProps } from "../types";
13
+
14
+ type TextCard = {
15
+ title: string;
16
+ body: string;
17
+ };
18
+
19
+ type BoundaryGroup = {
20
+ title: string;
21
+ items: readonly string[];
22
+ };
23
+
24
+ type FaqItem = {
25
+ question: string;
26
+ answer: string;
27
+ };
28
+
29
+ function OutputSection({
30
+ heading,
31
+ intro,
32
+ items,
33
+ visualAlt,
34
+ }: {
35
+ heading: string;
36
+ intro: string;
37
+ items: readonly TextCard[];
38
+ visualAlt: string;
39
+ }) {
40
+ return (
41
+ <section className="border-t border-[#E1DDD3] py-14 md:py-16">
42
+ <div className="grid gap-8 md:grid-cols-[0.92fr_1.08fr] md:items-center">
43
+ <div>
44
+ <h2 className="text-3xl font-semibold leading-tight text-[#111111] md:text-4xl">
45
+ {heading}
46
+ </h2>
47
+ <p className="mt-4 text-base leading-7 text-[#555555]">{intro}</p>
48
+ </div>
49
+ <ToolImageVisual src="/tools/email-template-generator-value.webp" alt={visualAlt} wide />
50
+ </div>
51
+ <div className="mt-8">
52
+ <ToolCardGrid items={items} />
53
+ </div>
54
+ </section>
55
+ );
56
+ }
57
+
58
+ function StandardsSection({
59
+ heading,
60
+ intro,
61
+ items,
62
+ }: {
63
+ heading: string;
64
+ intro: string;
65
+ items: readonly TextCard[];
66
+ }) {
67
+ return (
68
+ <section className="border-t border-[#E1DDD3] py-14 md:py-16">
69
+ <div className="max-w-3xl">
70
+ <h2 className="text-3xl font-semibold leading-tight text-[#111111] md:text-4xl">
71
+ {heading}
72
+ </h2>
73
+ <p className="mt-4 text-base leading-7 text-[#555555]">{intro}</p>
74
+ </div>
75
+ <div className="mt-7">
76
+ <ToolCardGrid items={items} />
77
+ </div>
78
+ </section>
79
+ );
80
+ }
81
+
82
+ function BoundarySection({
83
+ heading,
84
+ intro,
85
+ groups,
86
+ visualAlt,
87
+ }: {
88
+ heading: string;
89
+ intro: string;
90
+ groups: readonly BoundaryGroup[];
91
+ visualAlt: string;
92
+ }) {
93
+ return (
94
+ <section className="grid gap-8 border-t border-[#E1DDD3] py-14 md:grid-cols-[0.98fr_1.02fr] md:items-center md:py-16">
95
+ <ToolImageVisual src="/tools/email-template-generator-support.webp" alt={visualAlt} />
96
+ <div>
97
+ <h2 className="text-3xl font-semibold leading-tight text-[#111111] md:text-4xl">
98
+ {heading}
99
+ </h2>
100
+ <p className="mt-4 text-base leading-7 text-[#555555]">{intro}</p>
101
+ <div className="mt-6 grid gap-3">
102
+ {groups.map((group) => (
103
+ <article
104
+ key={group.title}
105
+ className="rounded-[1.25rem] border border-[#D8D4CA] bg-white p-5 shadow-[0_12px_28px_rgba(17,17,17,0.05)]"
106
+ >
107
+ <h3 className="text-base font-semibold leading-tight text-[#111111]">
108
+ {group.title}
109
+ </h3>
110
+ <ul className="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-[#555555]">
111
+ {group.items.map((item) => (
112
+ <li key={item}>{item}</li>
113
+ ))}
114
+ </ul>
115
+ </article>
116
+ ))}
117
+ </div>
118
+ </div>
119
+ </section>
120
+ );
121
+ }
122
+
123
+ function GuidanceSection({
124
+ heading,
125
+ intro,
126
+ items,
127
+ visualAlt,
128
+ }: {
129
+ heading: string;
130
+ intro: string;
131
+ items: readonly string[];
132
+ visualAlt: string;
133
+ }) {
134
+ return (
135
+ <section className="grid gap-8 border-t border-[#E1DDD3] py-14 md:grid-cols-[1fr_1fr] md:items-center md:py-16">
136
+ <div>
137
+ <h2 className="text-3xl font-semibold leading-tight text-[#111111] md:text-4xl">
138
+ {heading}
139
+ </h2>
140
+ <p className="mt-4 text-base leading-7 text-[#555555]">{intro}</p>
141
+ <div className="mt-6 space-y-4">
142
+ {items.map((item) => (
143
+ <p key={item} className="text-base leading-7 text-[#3D3D3D]">
144
+ {item}
145
+ </p>
146
+ ))}
147
+ </div>
148
+ </div>
149
+ <ToolImageVisual src="/tools/email-template-generator-export.webp" alt={visualAlt} />
150
+ </section>
151
+ );
152
+ }
153
+
154
+ export async function EmailTemplateGeneratorContainer({ locale, spec }: ToolPageProps) {
155
+ const t = await createToolGuideTranslator(locale, "toolsPages.emailTemplateGenerator.guide");
156
+ const outputItems = t.raw("outputItems") as readonly TextCard[];
157
+ const standardsItems = t.raw("standardsItems") as readonly TextCard[];
158
+ const boundaryGroups = t.raw("boundaryGroups") as readonly BoundaryGroup[];
159
+ const guidance = t.raw("guidanceItems") as readonly string[];
160
+ const useCases = t.raw("useCaseItems") as readonly TextCard[];
161
+ const faqItems = t.raw("faqItems") as readonly FaqItem[];
162
+
163
+ return (
164
+ <ToolPageShell
165
+ locale={locale}
166
+ spec={spec}
167
+ heroVariant="immersive"
168
+ heroBackgroundImage="/tools/email-template-generator-hero.webp"
169
+ heroBackgroundAlt={t("heroImageAlt")}
170
+ >
171
+ <ToolWorkspaceSection
172
+ heading={t("workspaceHeading")}
173
+ hint={t("workspaceHint")}
174
+ >
175
+ <EmailTemplateGenerator />
176
+ </ToolWorkspaceSection>
177
+
178
+ <OutputSection
179
+ heading={t("outputs")}
180
+ intro={t("outputsIntro")}
181
+ items={outputItems}
182
+ visualAlt={t("valueVisualAlt")}
183
+ />
184
+
185
+ <StandardsSection
186
+ heading={t("standards")}
187
+ intro={t("standardsIntro")}
188
+ items={standardsItems}
189
+ />
190
+
191
+ <BoundarySection
192
+ heading={t("boundary")}
193
+ intro={t("boundaryIntro")}
194
+ groups={boundaryGroups}
195
+ visualAlt={t("supportVisualAlt")}
196
+ />
197
+
198
+ <GuidanceSection
199
+ heading={t("guidance")}
200
+ intro={t("guidanceIntro")}
201
+ items={guidance}
202
+ visualAlt={t("exportVisualAlt")}
203
+ />
204
+
205
+ <section className="border-t border-[#E1DDD3] py-14 md:py-16">
206
+ <h2 className="text-3xl font-semibold leading-tight text-[#111111] md:text-4xl">
207
+ {t("useCases")}
208
+ </h2>
209
+ <div className="mt-7">
210
+ <ToolCardGrid items={useCases} />
211
+ </div>
212
+ </section>
213
+
214
+ <ToolFaqSection heading={t("faq")} items={faqItems} />
215
+
216
+ <ToolCta
217
+ heading={t("ctaTitle")}
218
+ hint={t("ctaHint")}
219
+ primary={{ href: "/tools/product-name-generator", label: t("ctaPrimary") }}
220
+ secondary={{ href: "/tools", label: t("ctaSecondary") }}
221
+ />
222
+ </ToolPageShell>
223
+ );
224
+ }
@@ -0,0 +1,14 @@
1
+ import type { ToolSpec } from "../types";
2
+
3
+ export const emailTemplateGeneratorSpec: ToolSpec = {
4
+ slug: "email-template-generator",
5
+ toolType: "generator",
6
+ seo: {
7
+ "publishedAt": "2026-06-29",
8
+ "updatedAt": "2026-06-29",
9
+ "readingTime": "6 min",
10
+ "featured": false,
11
+ "ogImage": "/tools/email-template-generator-hero.webp"
12
+ },
13
+ widget: {"id":"email-template-generator","mode":"custom"},
14
+ };