@hasna/skills 0.1.26 → 0.1.29

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 (491) hide show
  1. package/LICENSE +1 -10
  2. package/README.md +141 -39
  3. package/bin/index.js +30122 -27575
  4. package/bin/mcp.js +22112 -18593
  5. package/dist/cli/cli.test-utils.d.ts +15 -0
  6. package/dist/cli/commands/auth.d.ts +2 -0
  7. package/dist/cli/commands/install.d.ts +1 -1
  8. package/dist/cli/commands/runtime-mcp.d.ts +4 -0
  9. package/dist/index.d.ts +9 -4
  10. package/dist/index.js +11607 -597
  11. package/dist/lib/auth-store.d.ts +13 -0
  12. package/dist/lib/installer.d.ts +58 -55
  13. package/dist/lib/mcp-contracts.d.ts +86 -0
  14. package/dist/lib/project-state.d.ts +43 -0
  15. package/dist/lib/registry-data/business-marketing.d.ts +2 -0
  16. package/dist/lib/registry-data/communication.d.ts +2 -0
  17. package/dist/lib/registry-data/content-generation.d.ts +2 -0
  18. package/dist/lib/registry-data/data-analysis.d.ts +2 -0
  19. package/dist/lib/registry-data/design-branding.d.ts +2 -0
  20. package/dist/lib/registry-data/development-tools.d.ts +2 -0
  21. package/dist/lib/registry-data/education-learning.d.ts +2 -0
  22. package/dist/lib/registry-data/event-management.d.ts +2 -0
  23. package/dist/lib/registry-data/finance-compliance.d.ts +2 -0
  24. package/dist/lib/registry-data/health-wellness.d.ts +2 -0
  25. package/dist/lib/registry-data/index.d.ts +2 -0
  26. package/dist/lib/registry-data/media-processing.d.ts +2 -0
  27. package/dist/lib/registry-data/productivity-organization.d.ts +2 -0
  28. package/dist/lib/registry-data/project-management.d.ts +2 -0
  29. package/dist/lib/registry-data/research-writing.d.ts +2 -0
  30. package/dist/lib/registry-data/science-academic.d.ts +2 -0
  31. package/dist/lib/registry-data/travel-lifestyle.d.ts +2 -0
  32. package/dist/lib/registry-data/web-browser.d.ts +2 -0
  33. package/dist/lib/registry-types.d.ts +27 -0
  34. package/dist/lib/registry.d.ts +6 -18
  35. package/dist/lib/remote-registry.d.ts +3 -0
  36. package/dist/lib/run-state.d.ts +60 -0
  37. package/dist/lib/skill-aliases.d.ts +17 -0
  38. package/dist/lib/skillinfo.d.ts +5 -1
  39. package/dist/mcp/discovery-tools.d.ts +2 -0
  40. package/dist/mcp/helpers.d.ts +26 -0
  41. package/dist/mcp/http.d.ts +10 -0
  42. package/dist/mcp/index.d.ts +3 -2
  43. package/dist/mcp/operation-tools.d.ts +2 -0
  44. package/dist/mcp/resource-meta-tools.d.ts +2 -0
  45. package/dist/mcp/schedule-tools.d.ts +2 -0
  46. package/dist/mcp/server.d.ts +4 -0
  47. package/dist/types/api.d.ts +7 -4
  48. package/package.json +23 -10
  49. package/skills/_common/http-client.ts +1 -1
  50. package/skills/_common/index.ts +2 -3
  51. package/skills/_common/install.sh +5 -110
  52. package/skills/_common/installer.ts +31 -282
  53. package/skills/_common/skill-install.ts +14 -181
  54. package/skills/ad-creative-pack/SKILL.md +45 -0
  55. package/skills/ad-creative-pack/package.json +14 -0
  56. package/skills/advanced-math/package.json +3 -1
  57. package/skills/advanced-math/src/calculators.ts +118 -0
  58. package/skills/advanced-math/src/cli.ts +130 -0
  59. package/skills/advanced-math/src/conversion.ts +90 -0
  60. package/skills/advanced-math/src/finance.ts +75 -0
  61. package/skills/advanced-math/src/formatting.ts +95 -0
  62. package/skills/advanced-math/src/index.ts +24 -702
  63. package/skills/advanced-math/src/runtime.ts +49 -0
  64. package/skills/advanced-math/src/symbolic.ts +110 -0
  65. package/skills/advanced-math/src/types.ts +36 -0
  66. package/skills/analyze-data/SKILL.md +2 -2
  67. package/skills/analyze-data/src/analysis.ts +401 -0
  68. package/skills/analyze-data/src/cli.ts +66 -0
  69. package/skills/analyze-data/src/formatters.ts +235 -0
  70. package/skills/analyze-data/src/index.ts +6 -1027
  71. package/skills/analyze-data/src/logger.ts +36 -0
  72. package/skills/analyze-data/src/parsers.ts +57 -0
  73. package/skills/analyze-data/src/stats.ts +151 -0
  74. package/skills/analyze-data/src/types.ts +85 -0
  75. package/skills/api-docs-portal/SKILL.md +46 -0
  76. package/skills/api-docs-portal/package.json +9 -0
  77. package/skills/api-test-suite/src/index.ts +13 -0
  78. package/skills/apidocs/package.json +1 -1
  79. package/skills/apidocs/src/index.ts +3 -0
  80. package/skills/audio/package.json +2 -3
  81. package/skills/audio-cleanup-lab/SKILL.md +2 -2
  82. package/skills/audio-extract/CLAUDE.md +1 -1
  83. package/skills/audio-transcript-pack/SKILL.md +43 -0
  84. package/skills/audio-transcript-pack/package.json +10 -0
  85. package/skills/blog-article/CLAUDE.md +12 -0
  86. package/skills/blog-article/SKILL.md +45 -0
  87. package/skills/{create-blog-article → blog-article}/package.json +3 -3
  88. package/skills/brand-kit/SKILL.md +45 -0
  89. package/skills/brand-kit/package.json +14 -0
  90. package/skills/brand-photo-shoot/SKILL.md +28 -0
  91. package/skills/brand-photo-shoot/package.json +10 -0
  92. package/skills/brand-style-guide/SKILL.md +2 -2
  93. package/skills/brand-style-guide/src/index.ts +0 -0
  94. package/skills/budget-variance-analyzer/SKILL.md +2 -2
  95. package/skills/businessactivity/package.json +1 -1
  96. package/skills/businessactivity/src/index.ts +3 -0
  97. package/skills/calendar-events/src/ai-parser.ts +103 -0
  98. package/skills/calendar-events/src/api.ts +157 -0
  99. package/skills/calendar-events/src/auth.ts +22 -0
  100. package/skills/calendar-events/src/config.ts +6 -0
  101. package/skills/calendar-events/src/format.ts +96 -0
  102. package/skills/calendar-events/src/help.ts +54 -0
  103. package/skills/calendar-events/src/index.ts +21 -524
  104. package/skills/calendar-events/src/logger.ts +34 -0
  105. package/skills/calendar-events/src/types.ts +67 -0
  106. package/skills/compress-video/SKILL.md +2 -2
  107. package/skills/consolelog/package.json +1 -1
  108. package/skills/consolelog/src/index.ts +3 -0
  109. package/skills/contract-review-report/SKILL.md +43 -0
  110. package/skills/contract-review-report/package.json +10 -0
  111. package/skills/convert/SKILL.md +2 -3
  112. package/skills/customer-feedback-report/SKILL.md +44 -0
  113. package/skills/customer-feedback-report/package.json +10 -0
  114. package/skills/dashboard-builder/package.json +3 -1
  115. package/skills/database-explorer/package.json +3 -1
  116. package/skills/deepresearch/README.md +4 -13
  117. package/skills/deploy/src/http-client.ts +1 -1
  118. package/skills/diff-viewer/package.json +4 -1
  119. package/skills/doc-generate/package.json +0 -1
  120. package/skills/doc-generate/src/ai.ts +50 -0
  121. package/skills/doc-generate/src/cli.ts +203 -0
  122. package/skills/doc-generate/src/dependencies.ts +44 -0
  123. package/skills/doc-generate/src/document-builder.ts +299 -0
  124. package/skills/doc-generate/src/index.ts +40 -764
  125. package/skills/doc-generate/src/markdown-parser.ts +125 -0
  126. package/skills/doc-generate/src/types.ts +68 -0
  127. package/skills/domainpurchase/SKILL.md +1 -1
  128. package/skills/domainpurchase/package.json +1 -1
  129. package/skills/domainpurchase/src/index.ts +3 -0
  130. package/skills/domainsearch/SKILL.md +1 -1
  131. package/skills/domainsearch/package.json +1 -1
  132. package/skills/domainsearch/src/index.ts +3 -0
  133. package/skills/email-sequence/SKILL.md +44 -0
  134. package/skills/email-sequence/package.json +14 -0
  135. package/skills/excel/CLAUDE.md +2 -2
  136. package/skills/experiment-power-calculator/package.json +3 -1
  137. package/skills/extract-invoice/src/cli.ts +97 -0
  138. package/skills/extract-invoice/src/extractor.ts +170 -0
  139. package/skills/extract-invoice/src/file-utils.ts +46 -0
  140. package/skills/extract-invoice/src/formatters.ts +144 -0
  141. package/skills/extract-invoice/src/index.ts +44 -629
  142. package/skills/extract-invoice/src/runtime.ts +46 -0
  143. package/skills/extract-invoice/src/types.ts +88 -0
  144. package/skills/folder-tree/package.json +3 -1
  145. package/skills/form-filler/package.json +3 -1
  146. package/skills/generate-api-client/package.json +3 -1
  147. package/skills/generate-api-client/src/generator.ts +47 -0
  148. package/skills/generate-api-client/src/index.ts +3 -777
  149. package/skills/generate-api-client/src/logger.ts +34 -0
  150. package/skills/generate-api-client/src/python-generator.ts +245 -0
  151. package/skills/generate-api-client/src/spec-loader.ts +48 -0
  152. package/skills/generate-api-client/src/type-mappers.ts +79 -0
  153. package/skills/generate-api-client/src/types.ts +76 -0
  154. package/skills/generate-api-client/src/typescript-generator.ts +247 -0
  155. package/skills/generate-book-cover/package.json +3 -1
  156. package/skills/generate-dockerfile/src/cli.ts +78 -0
  157. package/skills/generate-dockerfile/src/dockerfile-templates.ts +392 -0
  158. package/skills/generate-dockerfile/src/index.ts +12 -790
  159. package/skills/generate-dockerfile/src/logger.ts +30 -0
  160. package/skills/generate-dockerfile/src/project-detection.ts +68 -0
  161. package/skills/generate-dockerfile/src/support-files.ts +171 -0
  162. package/skills/generate-dockerfile/src/types.ts +29 -0
  163. package/skills/generate-documentation/src/ai.ts +131 -0
  164. package/skills/generate-documentation/src/cli.ts +71 -0
  165. package/skills/generate-documentation/src/code-parser.ts +300 -0
  166. package/skills/generate-documentation/src/file-processing.ts +182 -0
  167. package/skills/generate-documentation/src/index.ts +13 -753
  168. package/skills/generate-documentation/src/runtime.ts +35 -0
  169. package/skills/generate-documentation/src/types.ts +30 -0
  170. package/skills/generate-env/package.json +3 -1
  171. package/skills/generate-env/src/cli.ts +85 -0
  172. package/skills/generate-env/src/detection.ts +161 -0
  173. package/skills/generate-env/src/env-data.ts +66 -0
  174. package/skills/generate-env/src/generators.ts +240 -0
  175. package/skills/generate-env/src/index.ts +76 -676
  176. package/skills/generate-env/src/runtime.ts +30 -0
  177. package/skills/generate-env/src/types.ts +32 -0
  178. package/skills/generate-favicon/package.json +3 -1
  179. package/skills/generate-mock-data/package.json +3 -1
  180. package/skills/generate-mock-data/src/ai.ts +102 -0
  181. package/skills/generate-mock-data/src/formatters.ts +84 -0
  182. package/skills/generate-mock-data/src/generator.ts +377 -0
  183. package/skills/generate-mock-data/src/index.ts +15 -716
  184. package/skills/generate-mock-data/src/logger.ts +37 -0
  185. package/skills/generate-mock-data/src/presets.ts +110 -0
  186. package/skills/generate-mock-data/src/types.ts +21 -0
  187. package/skills/generate-pr-description/src/ai.ts +144 -0
  188. package/skills/generate-pr-description/src/cli.ts +80 -0
  189. package/skills/generate-pr-description/src/clipboard.ts +30 -0
  190. package/skills/generate-pr-description/src/formatters.ts +231 -0
  191. package/skills/generate-pr-description/src/git.ts +153 -0
  192. package/skills/generate-pr-description/src/index.ts +21 -714
  193. package/skills/generate-pr-description/src/types.ts +49 -0
  194. package/skills/generate-presentation/src/ai-clients.ts +61 -0
  195. package/skills/generate-presentation/src/cli.ts +126 -0
  196. package/skills/generate-presentation/src/index.ts +3 -751
  197. package/skills/generate-presentation/src/logger.ts +67 -0
  198. package/skills/generate-presentation/src/presentation-generator.ts +425 -0
  199. package/skills/generate-presentation/src/runtime.ts +6 -0
  200. package/skills/generate-presentation/src/security.ts +12 -0
  201. package/skills/generate-presentation/src/types.ts +28 -0
  202. package/skills/generate-qrcode/package.json +4 -1
  203. package/skills/generate-regex/package.json +3 -1
  204. package/skills/generate-resume/src/cli.ts +157 -0
  205. package/skills/generate-resume/src/index.ts +13 -917
  206. package/skills/generate-resume/src/parsers.ts +95 -0
  207. package/skills/generate-resume/src/renderers.ts +538 -0
  208. package/skills/generate-resume/src/security.ts +39 -0
  209. package/skills/generate-resume/src/types.ts +86 -0
  210. package/skills/generate-social-posts/src/ai.ts +88 -0
  211. package/skills/generate-social-posts/src/cli.ts +118 -0
  212. package/skills/generate-social-posts/src/exporters.ts +126 -0
  213. package/skills/generate-social-posts/src/generator.ts +130 -0
  214. package/skills/generate-social-posts/src/index.ts +19 -709
  215. package/skills/generate-social-posts/src/platforms.ts +39 -0
  216. package/skills/generate-social-posts/src/runtime.ts +34 -0
  217. package/skills/generate-social-posts/src/source.ts +116 -0
  218. package/skills/generate-social-posts/src/types.ts +58 -0
  219. package/skills/gif-maker/package.json +4 -1
  220. package/skills/github-manager/package.json +3 -1
  221. package/skills/gmail/CLAUDE.md +1 -1
  222. package/skills/highlight-reel-generator/src/index.ts +19 -0
  223. package/skills/hook/src/commands/create.ts +20 -845
  224. package/skills/hook/src/templates/root.ts +196 -0
  225. package/skills/hook/src/templates/source.ts +647 -0
  226. package/skills/http-server/package.json +3 -1
  227. package/skills/icon-pack/README.md +28 -0
  228. package/skills/icon-pack/SKILL.md +23 -0
  229. package/skills/icon-pack/package.json +29 -0
  230. package/skills/{audio → icon-pack}/tsconfig.json +10 -12
  231. package/skills/image/package.json +1 -2
  232. package/skills/implementation-agent/package.json +3 -1
  233. package/skills/implementation-agent/src/ai-generation.ts +225 -0
  234. package/skills/implementation-agent/src/index.ts +3 -960
  235. package/skills/implementation-agent/src/minimist.d.ts +15 -0
  236. package/skills/implementation-agent/src/templates.ts +686 -0
  237. package/skills/implementation-agent/src/types.ts +53 -0
  238. package/skills/implementation-plan/package.json +3 -1
  239. package/skills/implementation-todo/package.json +3 -1
  240. package/skills/invoice/package.json +1 -1
  241. package/skills/invoice/src/index.ts +3 -0
  242. package/skills/invoice-reconciliation/SKILL.md +42 -0
  243. package/skills/invoice-reconciliation/package.json +10 -0
  244. package/skills/landing-page-pack/SKILL.md +47 -0
  245. package/skills/landing-page-pack/package.json +14 -0
  246. package/skills/latex-table-generator/package.json +3 -1
  247. package/skills/logo-design/SKILL.md +25 -44
  248. package/skills/logo-design/package.json +3 -15
  249. package/skills/lorem-generator/package.json +3 -1
  250. package/skills/lorem-generator/src/index.ts +13 -0
  251. package/skills/managehook/package.json +1 -1
  252. package/skills/managehook/src/index.ts +3 -0
  253. package/skills/managemcp/package.json +1 -1
  254. package/skills/managemcp/src/index.ts +3 -0
  255. package/skills/manageskill/package.json +1 -1
  256. package/skills/manageskill/src/index.ts +3 -0
  257. package/skills/markdown-validator/package.json +3 -1
  258. package/skills/markdown-validator/src/index.ts +1 -4
  259. package/skills/market-research-report/SKILL.md +41 -0
  260. package/skills/market-research-report/package.json +10 -0
  261. package/skills/mcp-builder/package.json +4 -1
  262. package/skills/mcp-builder/src/ai-descriptions.ts +37 -0
  263. package/skills/mcp-builder/src/generators.ts +513 -0
  264. package/skills/mcp-builder/src/index.ts +7 -908
  265. package/skills/mcp-builder/src/minimist.d.ts +15 -0
  266. package/skills/mcp-builder/src/naming.ts +12 -0
  267. package/skills/mcp-builder/src/options.ts +170 -0
  268. package/skills/mcp-builder/src/templates.ts +149 -0
  269. package/skills/mcp-builder/src/types.ts +42 -0
  270. package/skills/meeting-pack/SKILL.md +43 -0
  271. package/skills/meeting-pack/package.json +10 -0
  272. package/skills/merge-pdfs/package.json +5 -1
  273. package/skills/migration-plan-pack/SKILL.md +45 -0
  274. package/skills/migration-plan-pack/package.json +10 -0
  275. package/skills/music/package.json +2 -3
  276. package/skills/music-album/SKILL.md +37 -0
  277. package/skills/music-album/package.json +10 -0
  278. package/skills/notion-manager/package.json +3 -1
  279. package/skills/npmpublish/CLAUDE.md +5 -8
  280. package/skills/npmpublish/README.md +5 -26
  281. package/skills/npmpublish/src/index.ts +9 -147
  282. package/skills/one-page-website/SKILL.md +46 -0
  283. package/skills/one-page-website/package.json +10 -0
  284. package/skills/one-page-website/tsconfig.json +8 -0
  285. package/skills/pdf-generate/src/cli.ts +162 -0
  286. package/skills/pdf-generate/src/html.ts +84 -0
  287. package/skills/pdf-generate/src/index.ts +11 -800
  288. package/skills/pdf-generate/src/markdown.ts +27 -0
  289. package/skills/pdf-generate/src/pdf-writer.ts +78 -0
  290. package/skills/pdf-generate/src/runtime.ts +34 -0
  291. package/skills/pdf-generate/src/security.ts +37 -0
  292. package/skills/pdf-generate/src/templates.ts +311 -0
  293. package/skills/pdf-generate/src/types.ts +28 -0
  294. package/skills/pdf-read/SKILL.md +10 -10
  295. package/skills/pdf-to-dataset/SKILL.md +45 -0
  296. package/skills/pdf-to-dataset/package.json +10 -0
  297. package/skills/pdf-to-markdown/SKILL.md +49 -0
  298. package/skills/pdf-to-markdown/package.json +10 -0
  299. package/skills/pdf-to-markdown/tsconfig.json +10 -0
  300. package/skills/performance-audit-report/SKILL.md +42 -0
  301. package/skills/performance-audit-report/package.json +10 -0
  302. package/skills/persona-based-adwriter/src/index.ts +19 -0
  303. package/skills/photo-album/SKILL.md +29 -0
  304. package/skills/photo-album/package.json +9 -0
  305. package/skills/photo-album/tsconfig.json +4 -0
  306. package/skills/pitch-deck/SKILL.md +43 -0
  307. package/skills/pitch-deck/package.json +9 -0
  308. package/skills/playlist-maker/SKILL.md +33 -0
  309. package/skills/playlist-maker/package.json +9 -0
  310. package/skills/playlist-maker/tsconfig.json +4 -0
  311. package/skills/product-mockup/SKILL.md +45 -0
  312. package/skills/product-mockup/package.json +3 -20
  313. package/skills/product-mockup/tsconfig.json +3 -5
  314. package/skills/project-retro-companion/src/index.ts +19 -0
  315. package/skills/proposal-pack/SKILL.md +45 -0
  316. package/skills/proposal-pack/package.json +10 -0
  317. package/skills/read-pdf/SKILL.md +5 -4
  318. package/skills/repo-onboarding-report/SKILL.md +42 -0
  319. package/skills/repo-onboarding-report/package.json +10 -0
  320. package/skills/sales-call-recapper/src/index.ts +20 -0
  321. package/skills/salescopy/package.json +1 -1
  322. package/skills/salescopy/src/index.ts +3 -0
  323. package/skills/scaffold-project/src/ai-detect.ts +136 -0
  324. package/skills/scaffold-project/src/file-generators.ts +292 -0
  325. package/skills/scaffold-project/src/index.ts +8 -991
  326. package/skills/scaffold-project/src/project-config.ts +338 -0
  327. package/skills/scaffold-project/src/templates.ts +173 -0
  328. package/skills/scaffold-project/src/types.ts +58 -0
  329. package/skills/scientific-figure-check/package.json +3 -1
  330. package/skills/sdk-generator/SKILL.md +45 -0
  331. package/skills/sdk-generator/package.json +10 -0
  332. package/skills/sdk-generator/tsconfig.json +8 -0
  333. package/skills/security-audit/src/index.ts +25 -6
  334. package/skills/security-audit-report/SKILL.md +40 -0
  335. package/skills/security-audit-report/package.json +10 -0
  336. package/skills/seo-content-pack/SKILL.md +44 -0
  337. package/skills/seo-content-pack/package.json +9 -0
  338. package/skills/short-video-pack/SKILL.md +30 -0
  339. package/skills/short-video-pack/package.json +10 -0
  340. package/skills/slack-assistant/package.json +3 -1
  341. package/skills/slide-deck-generator/SKILL.md +44 -0
  342. package/skills/slide-deck-generator/package.json +10 -0
  343. package/skills/sms/package.json +1 -1
  344. package/skills/sms/src/index.ts +15 -0
  345. package/skills/social-content-calendar/SKILL.md +45 -0
  346. package/skills/social-content-calendar/package.json +14 -0
  347. package/skills/split-pdf/package.json +4 -1
  348. package/skills/subtitle/package.json +2 -1
  349. package/skills/subtitle/src/index.ts +3 -0
  350. package/skills/terraform-generator/package.json +3 -1
  351. package/skills/test-suite-generator/SKILL.md +41 -0
  352. package/skills/test-suite-generator/package.json +10 -0
  353. package/skills/timesheet/package.json +1 -1
  354. package/skills/timesheet/src/index.ts +3 -0
  355. package/skills/transcript/SKILL.md +1 -8
  356. package/skills/validate-config/package.json +3 -1
  357. package/skills/video/package.json +6 -4
  358. package/skills/video-downloader/package.json +3 -1
  359. package/skills/video-highlight-pack/SKILL.md +44 -0
  360. package/skills/video-highlight-pack/package.json +10 -0
  361. package/skills/voiceover-jingle-pack/SKILL.md +28 -0
  362. package/skills/voiceover-jingle-pack/package.json +10 -0
  363. package/skills/watermark/package.json +6 -1
  364. package/skills/webcrawling/package.json +2 -1
  365. package/skills/write/SKILL.md +6 -6
  366. package/dist/server/serve.d.ts +0 -11
  367. package/skills/apidocs/.claude/settings.json +0 -5
  368. package/skills/audio/.env.example +0 -14
  369. package/skills/audio/QUICKSTART.md +0 -158
  370. package/skills/audio/README.md +0 -256
  371. package/skills/audio/src/index-local.ts +0 -206
  372. package/skills/audio/src/index.ts +0 -95
  373. package/skills/audio/src/providers/elevenlabs.ts +0 -115
  374. package/skills/audio/src/providers/google.ts +0 -116
  375. package/skills/audio/src/providers/minimax.ts +0 -83
  376. package/skills/audio/src/providers/openai.ts +0 -115
  377. package/skills/audio/src/types.ts +0 -79
  378. package/skills/audiobook-chapter-proofer/CLAUDE.md +0 -19
  379. package/skills/audiobook-chapter-proofer/package.json +0 -27
  380. package/skills/audiobook-chapter-proofer/src/index.ts +0 -285
  381. package/skills/browse/src/client.ts +0 -373
  382. package/skills/browse/src/index-local.ts +0 -430
  383. package/skills/browse/src/index.ts +0 -110
  384. package/skills/browse/src/sse-server.ts +0 -919
  385. package/skills/browse/src/types.ts +0 -104
  386. package/skills/consolelog/src/server/index.ts +0 -508
  387. package/skills/create-blog-article/CLAUDE.md +0 -19
  388. package/skills/create-blog-article/src/index.ts +0 -745
  389. package/skills/create-blog-article/tsconfig.json +0 -10
  390. package/skills/deepresearch/src/agents/query-generator.ts +0 -91
  391. package/skills/deepresearch/src/agents/synthesizer.ts +0 -111
  392. package/skills/deepresearch/src/index.ts +0 -224
  393. package/skills/deepresearch/src/research.ts +0 -166
  394. package/skills/deepresearch/src/services/anthropic.ts +0 -69
  395. package/skills/deepresearch/src/services/exa.ts +0 -108
  396. package/skills/deepresearch/src/services/firecrawl.ts +0 -88
  397. package/skills/deepresearch/src/services/openai.ts +0 -81
  398. package/skills/deepresearch/src/types.ts +0 -76
  399. package/skills/deepresearch/src/utils/file.ts +0 -111
  400. package/skills/deepresearch/src/utils/logger.ts +0 -84
  401. package/skills/domainpurchase/src/server/index.ts +0 -332
  402. package/skills/domainsearch/src/server/index.ts +0 -229
  403. package/skills/e2bswarm/README.md +0 -135
  404. package/skills/e2bswarm/SKILL.md +0 -118
  405. package/skills/e2bswarm/examples/tasks-example.json +0 -38
  406. package/skills/e2bswarm/package.json +0 -59
  407. package/skills/e2bswarm/src/commands/collect.ts +0 -135
  408. package/skills/e2bswarm/src/commands/install.ts +0 -164
  409. package/skills/e2bswarm/src/commands/kill.ts +0 -62
  410. package/skills/e2bswarm/src/commands/spawn.ts +0 -134
  411. package/skills/e2bswarm/src/commands/status.ts +0 -90
  412. package/skills/e2bswarm/src/commands/sync.ts +0 -208
  413. package/skills/e2bswarm/src/index.ts +0 -121
  414. package/skills/e2bswarm/src/lib/config.ts +0 -75
  415. package/skills/e2bswarm/src/lib/e2b.ts +0 -490
  416. package/skills/e2bswarm/src/lib/github.ts +0 -253
  417. package/skills/e2bswarm/src/lib/logger.ts +0 -41
  418. package/skills/e2bswarm/src/lib/paths.ts +0 -75
  419. package/skills/e2bswarm/src/lib/tasks.ts +0 -320
  420. package/skills/e2bswarm/src/types/index.ts +0 -107
  421. package/skills/e2bswarm/templates/codebox/e2b.Dockerfile +0 -38
  422. package/skills/e2bswarm/templates/codebox/e2b.toml +0 -3
  423. package/skills/e2bswarm/templates/setup.sh +0 -21
  424. package/skills/e2bswarm/tsconfig.json +0 -19
  425. package/skills/generate-book-cover/src/index.ts +0 -694
  426. package/skills/image/src/index-local.ts +0 -206
  427. package/skills/image/src/index.ts +0 -96
  428. package/skills/image/src/providers/google.ts +0 -79
  429. package/skills/image/src/providers/minimax.ts +0 -94
  430. package/skills/image/src/providers/openai.ts +0 -80
  431. package/skills/image/src/providers/xai.ts +0 -73
  432. package/skills/image/src/types.ts +0 -37
  433. package/skills/logo-design/CLAUDE.md +0 -30
  434. package/skills/logo-design/src/index.ts +0 -322
  435. package/skills/managehook/src/server/index.ts +0 -108
  436. package/skills/managemcp/src/server/index.ts +0 -108
  437. package/skills/manageskill/src/server/index.ts +0 -108
  438. package/skills/music/CLAUDE.md +0 -9
  439. package/skills/music/src/index.ts +0 -94
  440. package/skills/music/tsconfig.json +0 -10
  441. package/skills/pdf-read/src/index.ts +0 -320
  442. package/skills/product-mockup/CLAUDE.md +0 -19
  443. package/skills/product-mockup/src/index.ts +0 -290
  444. package/skills/read-pdf/src/index.ts +0 -388
  445. package/skills/remove-background/src/index.ts +0 -405
  446. package/skills/scaffold-project/my-app/.env.example +0 -2
  447. package/skills/scaffold-project/my-app/README.md +0 -72
  448. package/skills/scaffold-project/my-app/package.json +0 -29
  449. package/skills/scaffold-project/my-app/src/index.ts +0 -23
  450. package/skills/scaffold-project/my-app/tsconfig.json +0 -33
  451. package/skills/sound-effects/SKILL.md +0 -34
  452. package/skills/sound-effects/package.json +0 -21
  453. package/skills/sound-effects/src/index.ts +0 -172
  454. package/skills/sound-effects/tsconfig.json +0 -8
  455. package/skills/transcript/src/chunker.ts +0 -215
  456. package/skills/transcript/src/formatter.ts +0 -134
  457. package/skills/transcript/src/index-local.ts +0 -226
  458. package/skills/transcript/src/index.ts +0 -110
  459. package/skills/transcript/src/providers/elevenlabs.ts +0 -133
  460. package/skills/transcript/src/providers/gemini.ts +0 -192
  461. package/skills/transcript/src/providers/index.ts +0 -54
  462. package/skills/transcript/src/providers/openai.ts +0 -203
  463. package/skills/transcript/src/types.ts +0 -106
  464. package/skills/video/.env.example +0 -14
  465. package/skills/video/EXAMPLES.md +0 -266
  466. package/skills/video/LICENSE +0 -192
  467. package/skills/video/README.md +0 -174
  468. package/skills/video/src/cli.ts +0 -155
  469. package/skills/video/src/index-local.ts +0 -148
  470. package/skills/video/src/index.ts +0 -96
  471. package/skills/video/src/providers/google-veo.ts +0 -126
  472. package/skills/video/src/providers/index.ts +0 -22
  473. package/skills/video/src/providers/minimax.ts +0 -100
  474. package/skills/video/src/providers/openai-sora.ts +0 -164
  475. package/skills/video/src/providers/runway.ts +0 -159
  476. package/skills/video/src/types.ts +0 -35
  477. package/skills/video/tsconfig.json +0 -22
  478. package/skills/voiceover-casting-assistant/CLAUDE.md +0 -19
  479. package/skills/voiceover-casting-assistant/package.json +0 -27
  480. package/skills/voiceover-casting-assistant/src/index.ts +0 -255
  481. package/skills/voiceover-casting-assistant/tsconfig.json +0 -10
  482. package/skills/webcrawling/src/commands/config.ts +0 -34
  483. package/skills/webcrawling/src/commands/crawl.ts +0 -33
  484. package/skills/webcrawling/src/commands/scrape.ts +0 -32
  485. package/skills/webcrawling/src/commands/sessions.ts +0 -42
  486. package/skills/webcrawling/src/lib/crawler.ts +0 -174
  487. package/skills/webcrawling/src/lib/storage.ts +0 -130
  488. package/skills/webcrawling/src/types/index.ts +0 -45
  489. package/skills/webcrawling/src/utils/logger.ts +0 -30
  490. package/skills/webcrawling/src/utils/paths.ts +0 -28
  491. /package/skills/{audiobook-chapter-proofer → blog-article}/tsconfig.json +0 -0
@@ -1,745 +0,0 @@
1
- #!/usr/bin/env bun
2
- /**
3
- * Create Blog Article Skill
4
- * Generates complete blog articles with AI-generated images
5
- */
6
-
7
- import { parseArgs } from "util";
8
- import { mkdirSync, writeFileSync, appendFileSync, existsSync } from "fs";
9
- import { join, dirname } from "path";
10
- import { randomUUID } from "crypto";
11
-
12
- // Types
13
- interface ArticleOptions {
14
- topic: string;
15
- tone: "professional" | "casual" | "technical" | "friendly";
16
- length: "short" | "medium" | "long";
17
- images: number;
18
- style: "photorealistic" | "illustration" | "minimalist";
19
- seo: boolean;
20
- outlineOnly: boolean;
21
- output?: string;
22
- }
23
-
24
- interface ArticleOutline {
25
- title: string;
26
- metaDescription: string;
27
- introduction: string;
28
- sections: Array<{
29
- heading: string;
30
- subheadings?: string[];
31
- imagePrompt?: string;
32
- }>;
33
- conclusion: string;
34
- keywords: string[];
35
- }
36
-
37
- interface ArticleContent {
38
- title: string;
39
- metaDescription: string;
40
- featuredImageUrl?: string;
41
- introduction: string;
42
- sections: Array<{
43
- heading: string;
44
- content: string;
45
- imageUrl?: string;
46
- }>;
47
- conclusion: string;
48
- keywords: string[];
49
- tags: string[];
50
- wordCount: number;
51
- readingTime: number;
52
- }
53
-
54
- interface OpenAIChatResponse {
55
- choices: Array<{
56
- message: {
57
- content: string;
58
- };
59
- }>;
60
- usage?: {
61
- total_tokens: number;
62
- };
63
- }
64
-
65
- interface OpenAIImageResponse {
66
- data: Array<{
67
- url?: string;
68
- revised_prompt?: string;
69
- }>;
70
- }
71
-
72
- // =============================================================================
73
- // Security: HTML Escaping to prevent XSS
74
- // =============================================================================
75
-
76
- /**
77
- * Escape HTML special characters to prevent XSS attacks
78
- */
79
- function escapeHtml(str: string | undefined | null): string {
80
- if (str === undefined || str === null) return "";
81
- return String(str)
82
- .replace(/&/g, "&amp;")
83
- .replace(/</g, "&lt;")
84
- .replace(/>/g, "&gt;")
85
- .replace(/"/g, "&quot;")
86
- .replace(/'/g, "&#x27;");
87
- }
88
-
89
- // Constants
90
- const SKILL_NAME = "create-blog-article";
91
- const SESSION_ID = randomUUID().slice(0, 8);
92
-
93
- // Use SKILLS_OUTPUT_DIR from CLI if available, otherwise fall back to cwd
94
- const SKILLS_OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || join(process.cwd(), ".skills");
95
- const EXPORTS_DIR = join(SKILLS_OUTPUT_DIR, "exports", SKILL_NAME);
96
- const LOGS_DIR = join(SKILLS_OUTPUT_DIR, "logs", SKILL_NAME);
97
-
98
- // Ensure directories exist
99
- function ensureDir(dir: string) {
100
- if (!existsSync(dir)) {
101
- mkdirSync(dir, { recursive: true });
102
- }
103
- }
104
-
105
- // Session timestamp for log filename
106
- const SESSION_TIMESTAMP = new Date().toISOString().replace(/[:.]/g, "_").replace(/-/g, "_").slice(0, 19).toLowerCase();
107
-
108
- // Logger
109
- function log(message: string, level: "info" | "error" | "success" = "info") {
110
- const timestamp = new Date().toISOString();
111
- const logFile = join(LOGS_DIR, `log_${SESSION_TIMESTAMP}_${SESSION_ID}.log`);
112
-
113
- ensureDir(LOGS_DIR);
114
-
115
- const logEntry = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
116
- appendFileSync(logFile, logEntry);
117
-
118
- const prefix = level === "error" ? "āŒ" : level === "success" ? "āœ…" : "ā„¹ļø";
119
- if (level === "error") {
120
- console.error(`${prefix} ${message}`);
121
- } else {
122
- console.log(`${prefix} ${message}`);
123
- }
124
- }
125
-
126
- // Generate slug from text
127
- function slugify(text: string): string {
128
- return text
129
- .toLowerCase()
130
- .replace(/[^a-z0-9]+/g, "-")
131
- .replace(/^-|-$/g, "")
132
- .slice(0, 60);
133
- }
134
-
135
- // Calculate reading time (assuming 200 words per minute)
136
- function calculateReadingTime(wordCount: number): number {
137
- return Math.ceil(wordCount / 200);
138
- }
139
-
140
- // Count words in text
141
- function countWords(text: string): number {
142
- return text.split(/\s+/).filter(word => word.length > 0).length;
143
- }
144
-
145
- // Call OpenAI Chat API
146
- async function callOpenAI(prompt: string, systemPrompt: string): Promise<string> {
147
- const apiKey = process.env.OPENAI_API_KEY;
148
-
149
- if (!apiKey) {
150
- throw new Error("OPENAI_API_KEY environment variable is not set");
151
- }
152
-
153
- const response = await fetch("https://api.openai.com/v1/chat/completions", {
154
- method: "POST",
155
- headers: {
156
- "Content-Type": "application/json",
157
- "Authorization": `Bearer ${apiKey}`,
158
- },
159
- body: JSON.stringify({
160
- model: "gpt-4o-mini",
161
- messages: [
162
- { role: "system", content: systemPrompt },
163
- { role: "user", content: prompt },
164
- ],
165
- temperature: 0.7,
166
- max_tokens: 4000,
167
- }),
168
- });
169
-
170
- if (!response.ok) {
171
- const error = await response.json();
172
- throw new Error(`OpenAI API error: ${error.error?.message || response.statusText}`);
173
- }
174
-
175
- const data: OpenAIChatResponse = await response.json();
176
-
177
- if (!data.choices?.[0]?.message?.content) {
178
- throw new Error("No content returned from OpenAI");
179
- }
180
-
181
- return data.choices[0].message.content;
182
- }
183
-
184
- // Generate article outline
185
- async function generateOutline(options: ArticleOptions): Promise<ArticleOutline> {
186
- log(`Generating article outline for: "${options.topic}"`);
187
-
188
- const lengthGuide = {
189
- short: "3-4 sections, ~500 words total",
190
- medium: "5-6 sections, ~1000 words total",
191
- long: "7-9 sections, ~2000 words total",
192
- };
193
-
194
- const systemPrompt = `You are an expert content writer and SEO specialist. Generate a detailed article outline in JSON format. The outline should be engaging, well-structured, and optimized for readability.`;
195
-
196
- const userPrompt = `Create a detailed outline for a blog article with the following requirements:
197
-
198
- Topic: ${options.topic}
199
- Tone: ${options.tone}
200
- Length: ${options.length} (${lengthGuide[options.length]})
201
- Images: ${options.images} images will be generated
202
- ${options.seo ? "SEO: Include keywords and meta description optimized for search engines" : ""}
203
-
204
- Return a JSON object with this exact structure:
205
- {
206
- "title": "Compelling article title",
207
- "metaDescription": "SEO-optimized meta description (150-160 characters)",
208
- "introduction": "Brief outline of introduction paragraph",
209
- "sections": [
210
- {
211
- "heading": "Section heading",
212
- "subheadings": ["Optional subheading 1", "Optional subheading 2"],
213
- "imagePrompt": "Optional DALL-E prompt for section image"
214
- }
215
- ],
216
- "conclusion": "Brief outline of conclusion",
217
- "keywords": ["keyword1", "keyword2", "keyword3"]
218
- }
219
-
220
- Make the outline engaging and informative. ${options.images > 1 ? `Include imagePrompt for ${options.images - 1} sections (featured image will be generated separately).` : "No section images needed."}`;
221
-
222
- const response = await callOpenAI(userPrompt, systemPrompt);
223
-
224
- // Parse JSON response
225
- const jsonMatch = response.match(/\{[\s\S]*\}/);
226
- if (!jsonMatch) {
227
- throw new Error("Could not parse outline JSON from response");
228
- }
229
-
230
- const outline = JSON.parse(jsonMatch[0]);
231
- log(`Outline generated with ${outline.sections.length} sections`, "success");
232
-
233
- return outline;
234
- }
235
-
236
- // Generate full article content from outline
237
- async function generateArticleContent(outline: ArticleOutline, options: ArticleOptions): Promise<ArticleContent> {
238
- log(`Generating full article content`);
239
-
240
- const lengthGuide = {
241
- short: "500 words",
242
- medium: "1000 words",
243
- long: "2000 words",
244
- };
245
-
246
- const systemPrompt = `You are an expert content writer. Write engaging, informative blog articles with a ${options.tone} tone. Focus on providing value to readers with clear, well-structured content.`;
247
-
248
- const userPrompt = `Write a complete blog article based on this outline:
249
-
250
- Title: ${outline.title}
251
- Topic: ${options.topic}
252
- Tone: ${options.tone}
253
- Target Length: ${lengthGuide[options.length]}
254
-
255
- Introduction: ${outline.introduction}
256
-
257
- Sections:
258
- ${outline.sections.map((s, i) => `${i + 1}. ${s.heading}${s.subheadings ? "\n - " + s.subheadings.join("\n - ") : ""}`).join("\n")}
259
-
260
- Conclusion: ${outline.conclusion}
261
-
262
- Return a JSON object with this structure:
263
- {
264
- "introduction": "Full introduction paragraph(s)",
265
- "sections": [
266
- {
267
- "heading": "Section heading",
268
- "content": "Full section content with multiple paragraphs"
269
- }
270
- ],
271
- "conclusion": "Full conclusion paragraph(s)",
272
- "tags": ["tag1", "tag2", "tag3"]
273
- }
274
-
275
- Write naturally and engagingly. Each section should be substantial and informative.`;
276
-
277
- const response = await callOpenAI(userPrompt, systemPrompt);
278
-
279
- // Parse JSON response
280
- const jsonMatch = response.match(/\{[\s\S]*\}/);
281
- if (!jsonMatch) {
282
- throw new Error("Could not parse article JSON from response");
283
- }
284
-
285
- const content = JSON.parse(jsonMatch[0]);
286
-
287
- // Calculate word count
288
- const allText = [
289
- content.introduction,
290
- ...content.sections.map((s: { content: string }) => s.content),
291
- content.conclusion,
292
- ].join(" ");
293
-
294
- const wordCount = countWords(allText);
295
- const readingTime = calculateReadingTime(wordCount);
296
-
297
- log(`Article generated: ${wordCount} words, ${readingTime} min read`, "success");
298
-
299
- return {
300
- title: outline.title,
301
- metaDescription: outline.metaDescription,
302
- introduction: content.introduction,
303
- sections: content.sections.map((s: { heading: string; content: string }, i: number) => ({
304
- heading: s.heading,
305
- content: s.content,
306
- imageUrl: outline.sections[i]?.imagePrompt ? undefined : undefined, // Will be filled later
307
- })),
308
- conclusion: content.conclusion,
309
- keywords: outline.keywords,
310
- tags: content.tags || [],
311
- wordCount,
312
- readingTime,
313
- };
314
- }
315
-
316
- // Generate image using DALL-E
317
- async function generateImage(prompt: string, style: string): Promise<string> {
318
- const apiKey = process.env.OPENAI_API_KEY;
319
-
320
- if (!apiKey) {
321
- throw new Error("OPENAI_API_KEY environment variable is not set");
322
- }
323
-
324
- log(`Generating image: "${prompt.slice(0, 50)}..."`);
325
-
326
- const styleMap: Record<string, string> = {
327
- photorealistic: "photorealistic, professional photography, high quality",
328
- illustration: "digital illustration, clean lines, artistic",
329
- minimalist: "minimalist design, simple, clean, modern",
330
- };
331
-
332
- const enhancedPrompt = `${prompt}, ${styleMap[style] || styleMap.photorealistic}`;
333
-
334
- const response = await fetch("https://api.openai.com/v1/images/generations", {
335
- method: "POST",
336
- headers: {
337
- "Content-Type": "application/json",
338
- "Authorization": `Bearer ${apiKey}`,
339
- },
340
- body: JSON.stringify({
341
- model: "dall-e-3",
342
- prompt: enhancedPrompt,
343
- n: 1,
344
- size: "1792x1024",
345
- quality: "standard",
346
- response_format: "url",
347
- }),
348
- });
349
-
350
- if (!response.ok) {
351
- const error = await response.json();
352
- throw new Error(`OpenAI API error: ${error.error?.message || response.statusText}`);
353
- }
354
-
355
- const data: OpenAIImageResponse = await response.json();
356
-
357
- if (!data.data?.[0]?.url) {
358
- throw new Error("No image URL returned from OpenAI");
359
- }
360
-
361
- log(`Image generated successfully`, "success");
362
-
363
- return data.data[0].url;
364
- }
365
-
366
- // Download image from URL
367
- async function downloadImage(url: string, outputPath: string): Promise<void> {
368
- const response = await fetch(url);
369
-
370
- if (!response.ok) {
371
- throw new Error(`Failed to download image: ${response.statusText}`);
372
- }
373
-
374
- const buffer = await response.arrayBuffer();
375
- const dir = dirname(outputPath);
376
-
377
- ensureDir(dir);
378
- writeFileSync(outputPath, Buffer.from(buffer));
379
-
380
- log(`Image saved to: ${outputPath}`);
381
- }
382
-
383
- // Generate all images for article
384
- async function generateArticleImages(
385
- outline: ArticleOutline,
386
- content: ArticleContent,
387
- options: ArticleOptions,
388
- outputDir: string
389
- ): Promise<ArticleContent> {
390
- if (options.images === 0) {
391
- log("Skipping image generation (--images 0)");
392
- return content;
393
- }
394
-
395
- const imagesDir = join(outputDir, "images");
396
- ensureDir(imagesDir);
397
-
398
- // Generate featured image
399
- log("Generating featured image...");
400
- const featuredPrompt = `Blog article featured image for: ${content.title}`;
401
- const featuredUrl = await generateImage(featuredPrompt, options.style);
402
- const featuredPath = join(imagesDir, "featured.png");
403
- await downloadImage(featuredUrl, featuredPath);
404
- content.featuredImageUrl = featuredPath;
405
-
406
- // Generate section images if requested
407
- if (options.images > 1) {
408
- log(`Generating ${options.images - 1} section images...`);
409
-
410
- let imageCount = 0;
411
- for (let i = 0; i < outline.sections.length && imageCount < options.images - 1; i++) {
412
- const section = outline.sections[i];
413
- if (section.imagePrompt) {
414
- try {
415
- const imageUrl = await generateImage(section.imagePrompt, options.style);
416
- const imagePath = join(imagesDir, `section-${i + 1}.png`);
417
- await downloadImage(imageUrl, imagePath);
418
- content.sections[i].imageUrl = imagePath;
419
- imageCount++;
420
- } catch (error) {
421
- log(`Failed to generate image for section ${i + 1}: ${error}`, "error");
422
- }
423
- }
424
- }
425
- }
426
-
427
- log(`Generated ${options.images} image(s) successfully`, "success");
428
- return content;
429
- }
430
-
431
- // Export article as Markdown
432
- function exportMarkdown(content: ArticleContent, outputPath: string): void {
433
- let markdown = `---
434
- title: ${content.title}
435
- description: ${content.metaDescription}
436
- keywords: ${content.keywords.join(", ")}
437
- tags: ${content.tags.join(", ")}
438
- readingTime: ${content.readingTime} min
439
- wordCount: ${content.wordCount}
440
- ---
441
-
442
- # ${content.title}
443
-
444
- `;
445
-
446
- if (content.featuredImageUrl) {
447
- markdown += `![Featured Image](./images/featured.png)\n\n`;
448
- }
449
-
450
- markdown += `${content.introduction}\n\n`;
451
-
452
- for (const section of content.sections) {
453
- markdown += `## ${section.heading}\n\n`;
454
- markdown += `${section.content}\n\n`;
455
- if (section.imageUrl) {
456
- const imageName = section.imageUrl.split("/").pop();
457
- markdown += `![${section.heading}](./images/${imageName})\n\n`;
458
- }
459
- }
460
-
461
- markdown += `## Conclusion\n\n${content.conclusion}\n\n`;
462
-
463
- markdown += `---\n\n`;
464
- markdown += `**Keywords:** ${content.keywords.join(", ")}\n\n`;
465
- markdown += `**Tags:** ${content.tags.join(", ")}\n`;
466
-
467
- writeFileSync(outputPath, markdown);
468
- log(`Markdown exported to: ${outputPath}`);
469
- }
470
-
471
- // Export article as HTML
472
- function exportHTML(content: ArticleContent, outputPath: string): void {
473
- let html = `<!DOCTYPE html>
474
- <html lang="en">
475
- <head>
476
- <meta charset="UTF-8">
477
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
478
- <meta name="description" content="${escapeHtml(content.metaDescription)}">
479
- <meta name="keywords" content="${escapeHtml(content.keywords.join(", "))}">
480
- <title>${escapeHtml(content.title)}</title>
481
- <style>
482
- body {
483
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
484
- line-height: 1.6;
485
- max-width: 800px;
486
- margin: 0 auto;
487
- padding: 2rem;
488
- color: #333;
489
- }
490
- img {
491
- max-width: 100%;
492
- height: auto;
493
- border-radius: 8px;
494
- margin: 2rem 0;
495
- }
496
- h1 {
497
- font-size: 2.5rem;
498
- margin-bottom: 1rem;
499
- }
500
- h2 {
501
- font-size: 1.75rem;
502
- margin-top: 2rem;
503
- margin-bottom: 1rem;
504
- }
505
- .meta {
506
- color: #666;
507
- font-size: 0.9rem;
508
- margin-bottom: 2rem;
509
- }
510
- .tags {
511
- margin-top: 3rem;
512
- padding-top: 2rem;
513
- border-top: 1px solid #eee;
514
- }
515
- .tags span {
516
- display: inline-block;
517
- background: #f0f0f0;
518
- padding: 0.25rem 0.75rem;
519
- margin: 0.25rem;
520
- border-radius: 4px;
521
- font-size: 0.9rem;
522
- }
523
- </style>
524
- </head>
525
- <body>
526
- <article>
527
- <header>
528
- <h1>${escapeHtml(content.title)}</h1>
529
- <div class="meta">
530
- ${content.readingTime} min read • ${content.wordCount} words
531
- </div>
532
- </header>
533
-
534
- `;
535
-
536
- if (content.featuredImageUrl) {
537
- html += ` <img src="./images/featured.png" alt="Featured Image">\n\n`;
538
- }
539
-
540
- html += ` <p>${escapeHtml(content.introduction).replace(/\n/g, "</p>\n <p>")}</p>\n\n`;
541
-
542
- for (const section of content.sections) {
543
- html += ` <section>
544
- <h2>${escapeHtml(section.heading)}</h2>
545
- <p>${escapeHtml(section.content).replace(/\n/g, "</p>\n <p>")}</p>
546
- `;
547
- if (section.imageUrl) {
548
- const imageName = section.imageUrl.split("/").pop();
549
- html += ` <img src="./images/${imageName}" alt="${escapeHtml(section.heading)}">\n`;
550
- }
551
- html += ` </section>\n\n`;
552
- }
553
-
554
- html += ` <section>
555
- <h2>Conclusion</h2>
556
- <p>${escapeHtml(content.conclusion).replace(/\n/g, "</p>\n <p>")}</p>
557
- </section>
558
-
559
- <div class="tags">
560
- <strong>Tags:</strong>
561
- `;
562
-
563
- for (const tag of content.tags) {
564
- html += ` <span>${escapeHtml(tag)}</span>\n`;
565
- }
566
-
567
- html += ` </div>
568
- </article>
569
- </body>
570
- </html>`;
571
-
572
- writeFileSync(outputPath, html);
573
- log(`HTML exported to: ${outputPath}`);
574
- }
575
-
576
- // Export article as JSON
577
- function exportJSON(content: ArticleContent, outputPath: string): void {
578
- const json = JSON.stringify(content, null, 2);
579
- writeFileSync(outputPath, json);
580
- log(`JSON exported to: ${outputPath}`);
581
- }
582
-
583
- // Main function
584
- async function main() {
585
- const { values, positionals } = parseArgs({
586
- args: Bun.argv.slice(2),
587
- options: {
588
- tone: { type: "string", default: "professional" },
589
- length: { type: "string", default: "medium" },
590
- images: { type: "string", default: "1" },
591
- style: { type: "string", default: "photorealistic" },
592
- seo: { type: "boolean", default: false },
593
- "outline-only": { type: "boolean", default: false },
594
- output: { type: "string", short: "o" },
595
- help: { type: "boolean", short: "h" },
596
- },
597
- allowPositionals: true,
598
- });
599
-
600
- // Show help
601
- if (values.help || positionals.length === 0) {
602
- console.log(`
603
- Create Blog Article - Generate complete blog articles with AI-generated images
604
-
605
- Usage:
606
- bun run src/index.ts <topic> [options]
607
-
608
- Options:
609
- --tone <tone> Writing tone (professional, casual, technical, friendly) [default: professional]
610
- --length <length> Article length (short ~500w, medium ~1000w, long ~2000w) [default: medium]
611
- --images <number> Number of images (0, 1, 3, 5) [default: 1]
612
- --style <style> Image style (photorealistic, illustration, minimalist) [default: photorealistic]
613
- --seo Include SEO metadata and keywords [default: false]
614
- --outline-only Generate outline only, no full article [default: false]
615
- --output, -o <path> Custom output path
616
- --help, -h Show this help
617
-
618
- Examples:
619
- bun run src/index.ts "The Future of AI Development"
620
- bun run src/index.ts "How to Build REST APIs" --tone technical --length long
621
- bun run src/index.ts "Travel Tips" --seo --images 3 --style photorealistic
622
- bun run src/index.ts "Code Reviews" --outline-only
623
- `);
624
- process.exit(0);
625
- }
626
-
627
- const topic = positionals.join(" ");
628
-
629
- if (!topic) {
630
- log("Please provide a topic/title for the article", "error");
631
- process.exit(1);
632
- }
633
-
634
- // Validate options
635
- const validTones = ["professional", "casual", "technical", "friendly"];
636
- const validLengths = ["short", "medium", "long"];
637
- const validStyles = ["photorealistic", "illustration", "minimalist"];
638
- const validImageCounts = [0, 1, 3, 5];
639
-
640
- const tone = values.tone as string;
641
- const length = values.length as string;
642
- const style = values.style as string;
643
- const images = parseInt(values.images as string);
644
-
645
- if (!validTones.includes(tone)) {
646
- log(`Invalid tone: ${tone}. Must be one of: ${validTones.join(", ")}`, "error");
647
- process.exit(1);
648
- }
649
-
650
- if (!validLengths.includes(length)) {
651
- log(`Invalid length: ${length}. Must be one of: ${validLengths.join(", ")}`, "error");
652
- process.exit(1);
653
- }
654
-
655
- if (!validStyles.includes(style)) {
656
- log(`Invalid style: ${style}. Must be one of: ${validStyles.join(", ")}`, "error");
657
- process.exit(1);
658
- }
659
-
660
- if (!validImageCounts.includes(images)) {
661
- log(`Invalid images count: ${images}. Must be one of: ${validImageCounts.join(", ")}`, "error");
662
- process.exit(1);
663
- }
664
-
665
- const options: ArticleOptions = {
666
- topic,
667
- tone: tone as ArticleOptions["tone"],
668
- length: length as ArticleOptions["length"],
669
- images,
670
- style: style as ArticleOptions["style"],
671
- seo: values.seo as boolean,
672
- outlineOnly: values["outline-only"] as boolean,
673
- output: values.output as string | undefined,
674
- };
675
-
676
- try {
677
- log(`Session ID: ${SESSION_ID}`);
678
- log(`Topic: "${topic}"`);
679
- log(`Options: ${tone} tone, ${length} length, ${images} images, ${style} style`);
680
-
681
- // Determine output directory
682
- const timestamp = new Date().toISOString().replace(/[:.]/g, "_").replace(/-/g, "_").slice(0, 19).toLowerCase();
683
- const titleSlug = slugify(topic);
684
- const outputDir = options.output || join(EXPORTS_DIR, `export_${timestamp}_${titleSlug}`);
685
- ensureDir(outputDir);
686
-
687
- log(`Output directory: ${outputDir}`);
688
-
689
- // Step 1: Generate outline
690
- const outline = await generateOutline(options);
691
-
692
- if (options.outlineOnly) {
693
- // Export outline only
694
- const outlineJson = JSON.stringify(outline, null, 2);
695
- const outlinePath = join(outputDir, "outline.json");
696
- writeFileSync(outlinePath, outlineJson);
697
-
698
- console.log(`\n✨ Outline generated successfully!`);
699
- console.log(` šŸ“ Output: ${outlinePath}`);
700
- console.log(` šŸ“‹ Log: ${join(LOGS_DIR, `log_${SESSION_TIMESTAMP}_${SESSION_ID}.log`)}`);
701
- console.log(`\nšŸ“ Outline:`);
702
- console.log(` Title: ${outline.title}`);
703
- console.log(` Sections: ${outline.sections.length}`);
704
- console.log(` Keywords: ${outline.keywords.join(", ")}`);
705
-
706
- return;
707
- }
708
-
709
- // Step 2: Generate full article content
710
- let content = await generateArticleContent(outline, options);
711
-
712
- // Step 3: Generate images
713
- content = await generateArticleImages(outline, content, options, outputDir);
714
-
715
- // Step 4: Export in all formats
716
- log("Exporting article in multiple formats...");
717
-
718
- exportMarkdown(content, join(outputDir, "article.md"));
719
- exportHTML(content, join(outputDir, "article.html"));
720
- exportJSON(content, join(outputDir, "article.json"));
721
-
722
- console.log(`\n✨ Blog article generated successfully!`);
723
- console.log(` šŸ“ Output: ${outputDir}`);
724
- console.log(` šŸ“„ Formats: article.md, article.html, article.json`);
725
- if (options.images > 0) {
726
- console.log(` šŸ–¼ļø Images: ${options.images} image(s) in images/`);
727
- }
728
- console.log(` šŸ“‹ Log: ${join(LOGS_DIR, `log_${SESSION_TIMESTAMP}_${SESSION_ID}.log`)}`);
729
- console.log(`\nšŸ“Š Article Stats:`);
730
- console.log(` Title: ${content.title}`);
731
- console.log(` Words: ${content.wordCount}`);
732
- console.log(` Reading Time: ${content.readingTime} min`);
733
- console.log(` Sections: ${content.sections.length}`);
734
- console.log(` Tags: ${content.tags.join(", ")}`);
735
-
736
- } catch (error) {
737
- log(`Error: ${error instanceof Error ? error.message : "Unknown error"}`, "error");
738
- if (error instanceof Error && error.stack) {
739
- log(`Stack trace: ${error.stack}`, "error");
740
- }
741
- process.exit(1);
742
- }
743
- }
744
-
745
- main();