@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
@@ -7,1034 +7,13 @@
7
7
  * quality checks, correlation detection, and trend analysis.
8
8
  */
9
9
 
10
- import { readFileSync, writeFileSync, statSync, appendFileSync, mkdirSync, existsSync } from 'fs';
11
- import { basename, resolve, extname, join } from 'path';
12
- import { parseArgs } from 'util';
13
- import { randomUUID } from 'crypto';
10
+ import { statSync, writeFileSync } from 'fs';
11
+ import { resolve } from 'path';
14
12
 
15
- // ============================================================================
16
- // Constants & Logging
17
- // ============================================================================
18
-
19
- const SKILL_NAME = "analyze-data";
20
- const SESSION_ID = randomUUID().slice(0, 8);
21
- const SKILLS_OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || join(process.cwd(), ".skills");
22
- const LOGS_DIR = join(SKILLS_OUTPUT_DIR, "logs", SKILL_NAME);
23
- const LOG_FILE = join(LOGS_DIR, `${new Date().toISOString().replace(/[:.]/g, "_").slice(0, 19)}_${SESSION_ID}.log`);
24
-
25
- function ensureDir(dir: string) {
26
- if (!existsSync(dir)) {
27
- mkdirSync(dir, { recursive: true });
28
- }
29
- }
30
-
31
- function log(message: string, level: "info" | "error" | "success" = "info") {
32
- ensureDir(LOGS_DIR);
33
- const timestamp = new Date().toISOString();
34
- const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
35
- appendFileSync(LOG_FILE, logMessage);
36
-
37
- const prefixes = {
38
- info: "ℹ️ ",
39
- error: "❌ ",
40
- success: "✅ "
41
- };
42
-
43
- if (level === "error") {
44
- console.error(`${prefixes[level]} ${message}`);
45
- } else {
46
- console.log(`${prefixes[level]} ${message}`);
47
- }
48
- }
49
-
50
- // ============================================================================
51
- // Types and Interfaces
52
- // ============================================================================
53
-
54
- interface AnalysisOptions {
55
- format: 'markdown' | 'json' | 'html';
56
- output?: string;
57
- correlations: boolean;
58
- outliers: boolean;
59
- trends: boolean;
60
- sample?: number;
61
- percentiles: number[];
62
- verbose: boolean;
63
- }
64
-
65
- interface ColumnStats {
66
- name: string;
67
- dataType: 'numeric' | 'string' | 'date' | 'boolean' | 'mixed';
68
- count: number;
69
- nullCount: number;
70
- nullPercentage: number;
71
- uniqueCount: number;
72
- uniquePercentage: number;
73
- sampleValues: any[];
74
-
75
- // Numeric stats
76
- mean?: number;
77
- median?: number;
78
- mode?: number | number[];
79
- stdDev?: number;
80
- variance?: number;
81
- min?: number;
82
- max?: number;
83
- range?: number;
84
- q1?: number;
85
- q2?: number;
86
- q3?: number;
87
- percentiles?: Record<number, number>;
88
- skewness?: number;
89
- kurtosis?: number;
90
- outliers?: number[];
91
-
92
- // String stats
93
- avgLength?: number;
94
- minLength?: number;
95
- maxLength?: number;
96
-
97
- // Distribution
98
- distribution?: Record<string, number>;
99
- topValues?: Array<{ value: any; count: number; percentage: number }>;
100
- }
101
-
102
- interface AnalysisReport {
103
- overview: {
104
- fileName: string;
105
- fileSize: string;
106
- fileType: string;
107
- rowCount: number;
108
- columnCount: number;
109
- memoryUsage: string;
110
- processingTime: number;
111
- timestamp: string;
112
- };
113
- columns: ColumnStats[];
114
- correlations?: number[][];
115
- correlationPairs?: Array<{ col1: string; col2: string; correlation: number }>;
116
- quality: {
117
- totalCells: number;
118
- missingCells: number;
119
- missingPercentage: number;
120
- duplicateRows: number;
121
- duplicatePercentage: number;
122
- dataQualityScore: number;
123
- issues: string[];
124
- };
125
- trends?: {
126
- detected: boolean;
127
- patterns: string[];
128
- insights: string[];
129
- };
130
- visualizationRecommendations: Array<{
131
- column: string;
132
- chartType: string;
133
- reason: string;
134
- }>;
135
- insights: string[];
136
- }
137
-
138
- // ============================================================================
139
- // Utility Functions
140
- // ============================================================================
141
-
142
- function parseArguments(): { filePath: string; options: AnalysisOptions } {
143
- const { values, positionals } = parseArgs({
144
- args: process.argv.slice(2),
145
- options: {
146
- format: { type: 'string', default: 'markdown' },
147
- output: { type: 'string' },
148
- correlations: { type: 'boolean', default: false },
149
- outliers: { type: 'boolean', default: false },
150
- trends: { type: 'boolean', default: false },
151
- sample: { type: 'string' },
152
- percentiles: { type: 'string', default: '25,50,75,90,95' },
153
- verbose: { type: 'boolean', default: false },
154
- help: { type: 'boolean', short: 'h' },
155
- },
156
- allowPositionals: true,
157
- });
158
-
159
- if (values.help) {
160
- console.log(`
161
- Analyze Data - Comprehensive data analysis for CSV and JSON files
162
-
163
- Usage:
164
- skills run analyze-data -- <file-path> [options]
165
-
166
- Options:
167
- --format <fmt> Output format: markdown, json, html (default: markdown)
168
- --output <path> Save report to file
169
- --correlations Calculate correlations
170
- --outliers Detect outliers
171
- --trends Detect trends
172
- --sample <n> Analyze only first n rows
173
- --percentiles <list> Comma-separated percentiles (default: 25,50,75,90,95)
174
- --verbose Show detailed progress
175
- --help, -h Show this help
176
- `);
177
- process.exit(0);
178
- }
179
-
180
- if (positionals.length === 0) {
181
- log('Error: File path is required', 'error');
182
- console.log('Usage: skills run analyze-data -- <file-path> [options]');
183
- process.exit(1);
184
- }
185
-
186
- const filePath = resolve(process.cwd(), positionals[0]);
187
-
188
- return {
189
- filePath,
190
- options: {
191
- format: values.format as 'markdown' | 'json' | 'html',
192
- output: values.output as string,
193
- correlations: values.correlations as boolean,
194
- outliers: values.outliers as boolean,
195
- trends: values.trends as boolean,
196
- sample: values.sample ? parseInt(values.sample as string) : undefined,
197
- percentiles: (values.percentiles as string).split(',').map(Number),
198
- verbose: values.verbose as boolean,
199
- }
200
- };
201
- }
202
-
203
- function parseCSV(content: string): any[] {
204
- const lines = content.split('\n').filter(line => line.trim());
205
- if (lines.length === 0) return [];
206
-
207
- const headers = lines[0].split(',').map(h => h.trim().replace(/^"|"$/g, ''));
208
- const data: any[] = [];
209
-
210
- for (let i = 1; i < lines.length; i++) {
211
- const values = parseCSVLine(lines[i]);
212
- if (values.length === headers.length) {
213
- const row: any = {};
214
- headers.forEach((header, idx) => {
215
- row[header] = values[idx];
216
- });
217
- data.push(row);
218
- }
219
- }
220
-
221
- return data;
222
- }
223
-
224
- function parseCSVLine(line: string): string[] {
225
- const values: string[] = [];
226
- let current = '';
227
- let inQuotes = false;
228
-
229
- for (let i = 0; i < line.length; i++) {
230
- const char = line[i];
231
-
232
- if (char === '"') {
233
- inQuotes = !inQuotes;
234
- } else if (char === ',' && !inQuotes) {
235
- values.push(current.trim());
236
- current = '';
237
- } else {
238
- current += char;
239
- }
240
- }
241
-
242
- values.push(current.trim());
243
- return values.map(v => v.replace(/^"|"$/g, ''));
244
- }
245
-
246
- function parseJSON(content: string): any[] {
247
- const parsed = JSON.parse(content);
248
-
249
- if (Array.isArray(parsed)) {
250
- return parsed;
251
- } else if (parsed.data && Array.isArray(parsed.data)) {
252
- return parsed.data;
253
- } else if (typeof parsed === 'object') {
254
- // Convert object to array of key-value pairs
255
- return Object.entries(parsed).map(([key, value]) => ({ key, value }));
256
- }
257
-
258
- throw new Error('Unsupported JSON structure');
259
- }
260
-
261
- function detectDataType(values: any[]): ColumnStats['dataType'] {
262
- const nonNullValues = values.filter(v => v !== null && v !== undefined && v !== '');
263
- if (nonNullValues.length === 0) return 'string';
264
-
265
- let numericCount = 0;
266
- let dateCount = 0;
267
- let booleanCount = 0;
268
-
269
- for (const value of nonNullValues.slice(0, 100)) {
270
- if (typeof value === 'number' || !isNaN(Number(value))) {
271
- numericCount++;
272
- }
273
- if (value === true || value === false || value === 'true' || value === 'false') {
274
- booleanCount++;
275
- }
276
- if (!isNaN(Date.parse(String(value)))) {
277
- dateCount++;
278
- }
279
- }
280
-
281
- const total = Math.min(nonNullValues.length, 100);
282
-
283
- if (numericCount / total > 0.8) return 'numeric';
284
- if (booleanCount / total > 0.8) return 'boolean';
285
- if (dateCount / total > 0.8) return 'date';
286
- if (numericCount > 0 && numericCount < total * 0.8) return 'mixed';
287
-
288
- return 'string';
289
- }
290
-
291
- function calculateStats(values: number[]): Partial<ColumnStats> {
292
- if (values.length === 0) return {};
293
-
294
- const sorted = [...values].sort((a, b) => a - b);
295
- const n = sorted.length;
296
-
297
- // Basic stats
298
- const sum = sorted.reduce((acc, val) => acc + val, 0);
299
- const mean = sum / n;
300
-
301
- const median = n % 2 === 0
302
- ? (sorted[n / 2 - 1] + sorted[n / 2]) / 2
303
- : sorted[Math.floor(n / 2)];
304
-
305
- // Mode
306
- const frequency: Record<number, number> = {};
307
- sorted.forEach(val => {
308
- frequency[val] = (frequency[val] || 0) + 1;
309
- });
310
- const maxFreq = Math.max(...Object.values(frequency));
311
- const modes = Object.keys(frequency)
312
- .filter(key => frequency[Number(key)] === maxFreq)
313
- .map(Number);
314
- const mode = modes.length === sorted.length ? undefined : (modes.length === 1 ? modes[0] : modes);
315
-
316
- // Variance and standard deviation
317
- const squaredDiffs = sorted.map(val => Math.pow(val - mean, 2));
318
- const variance = squaredDiffs.reduce((acc, val) => acc + val, 0) / n;
319
- const stdDev = Math.sqrt(variance);
320
-
321
- // Quartiles
322
- const q1 = sorted[Math.floor(n * 0.25)];
323
- const q2 = median;
324
- const q3 = sorted[Math.floor(n * 0.75)];
325
-
326
- // Skewness and kurtosis
327
- const cubedDiffs = sorted.map(val => Math.pow((val - mean) / stdDev, 3));
328
- const skewness = cubedDiffs.reduce((acc, val) => acc + val, 0) / n;
329
-
330
- const fourthDiffs = sorted.map(val => Math.pow((val - mean) / stdDev, 4));
331
- const kurtosis = fourthDiffs.reduce((acc, val) => acc + val, 0) / n - 3;
332
-
333
- return {
334
- mean: roundTo(mean, 4),
335
- median: roundTo(median, 4),
336
- mode,
337
- stdDev: roundTo(stdDev, 4),
338
- variance: roundTo(variance, 4),
339
- min: sorted[0],
340
- max: sorted[n - 1],
341
- range: sorted[n - 1] - sorted[0],
342
- q1: roundTo(q1, 4),
343
- q2: roundTo(q2, 4),
344
- q3: roundTo(q3, 4),
345
- skewness: roundTo(skewness, 4),
346
- kurtosis: roundTo(kurtosis, 4),
347
- };
348
- }
349
-
350
- function calculatePercentiles(values: number[], percentiles: number[]): Record<number, number> {
351
- const sorted = [...values].sort((a, b) => a - b);
352
- const result: Record<number, number> = {};
353
-
354
- percentiles.forEach(p => {
355
- const index = (p / 100) * (sorted.length - 1);
356
- const lower = Math.floor(index);
357
- const upper = Math.ceil(index);
358
- const fraction = index - lower;
359
-
360
- result[p] = sorted[lower] + fraction * (sorted[upper] - sorted[lower]);
361
- });
362
-
363
- return result;
364
- }
365
-
366
- function detectOutliers(values: number[], q1: number, q3: number): number[] {
367
- const iqr = q3 - q1;
368
- const lowerBound = q1 - 1.5 * iqr;
369
- const upperBound = q3 + 1.5 * iqr;
370
-
371
- return values.filter(val => val < lowerBound || val > upperBound);
372
- }
373
-
374
- function calculateCorrelation(x: number[], y: number[]): number {
375
- const n = Math.min(x.length, y.length);
376
- if (n === 0) return 0;
377
-
378
- const meanX = x.reduce((acc, val) => acc + val, 0) / n;
379
- const meanY = y.reduce((acc, val) => acc + val, 0) / n;
380
-
381
- let numerator = 0;
382
- let sumXSquared = 0;
383
- let sumYSquared = 0;
384
-
385
- for (let i = 0; i < n; i++) {
386
- const dx = x[i] - meanX;
387
- const dy = y[i] - meanY;
388
- numerator += dx * dy;
389
- sumXSquared += dx * dx;
390
- sumYSquared += dy * dy;
391
- }
392
-
393
- const denominator = Math.sqrt(sumXSquared * sumYSquared);
394
- return denominator === 0 ? 0 : numerator / denominator;
395
- }
396
-
397
- function roundTo(value: number, decimals: number): number {
398
- const factor = Math.pow(10, decimals);
399
- return Math.round(value * factor) / factor;
400
- }
401
-
402
- function formatBytes(bytes: number): string {
403
- if (bytes < 1024) return bytes + ' B';
404
- if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
405
- if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
406
- return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
407
- }
408
-
409
- // ============================================================================
410
- // Analysis Functions
411
- // ============================================================================
412
-
413
- function analyzeColumn(columnName: string, values: any[], options: AnalysisOptions): ColumnStats {
414
- const dataType = detectDataType(values);
415
- const nonNullValues = values.filter(v => v !== null && v !== undefined && v !== '');
416
- const nullCount = values.length - nonNullValues.length;
417
-
418
- const uniqueValues = new Set(nonNullValues);
419
- const stats: ColumnStats = {
420
- name: columnName,
421
- dataType,
422
- count: values.length,
423
- nullCount,
424
- nullPercentage: roundTo((nullCount / values.length) * 100, 2),
425
- uniqueCount: uniqueValues.size,
426
- uniquePercentage: roundTo((uniqueValues.size / nonNullValues.length) * 100, 2),
427
- sampleValues: nonNullValues.slice(0, 5),
428
- };
429
-
430
- // Numeric analysis
431
- if (dataType === 'numeric') {
432
- const numericValues = nonNullValues.map(Number).filter(v => !isNaN(v));
433
- Object.assign(stats, calculateStats(numericValues));
434
-
435
- if (options.percentiles.length > 0) {
436
- stats.percentiles = calculatePercentiles(numericValues, options.percentiles);
437
- }
438
-
439
- if (options.outliers && stats.q1 !== undefined && stats.q3 !== undefined) {
440
- stats.outliers = detectOutliers(numericValues, stats.q1, stats.q3);
441
- }
442
- }
443
-
444
- // String analysis
445
- if (dataType === 'string') {
446
- const lengths = nonNullValues.map(v => String(v).length);
447
- stats.avgLength = roundTo(lengths.reduce((a, b) => a + b, 0) / lengths.length, 2);
448
- stats.minLength = Math.min(...lengths);
449
- stats.maxLength = Math.max(...lengths);
450
- }
451
-
452
- // Distribution (for categorical data)
453
- if (uniqueValues.size <= 50) {
454
- const distribution: Record<string, number> = {};
455
- nonNullValues.forEach(val => {
456
- const key = String(val);
457
- distribution[key] = (distribution[key] || 0) + 1;
458
- });
459
- stats.distribution = distribution;
460
-
461
- const topValues = Object.entries(distribution)
462
- .map(([value, count]) => ({
463
- value,
464
- count,
465
- percentage: roundTo((count / nonNullValues.length) * 100, 2),
466
- }))
467
- .sort((a, b) => b.count - a.count)
468
- .slice(0, 10);
469
-
470
- stats.topValues = topValues;
471
- }
472
-
473
- return stats;
474
- }
475
-
476
- function analyzeCorrelations(data: any[], numericColumns: string[]): {
477
- matrix: number[][];
478
- pairs: Array<{ col1: string; col2: string; correlation: number }>;
479
- } {
480
- const n = numericColumns.length;
481
- const matrix: number[][] = Array(n).fill(0).map(() => Array(n).fill(0));
482
- const pairs: Array<{ col1: string; col2: string; correlation: number }> = [];
483
-
484
- for (let i = 0; i < n; i++) {
485
- for (let j = i; j < n; j++) {
486
- if (i === j) {
487
- matrix[i][j] = 1;
488
- } else {
489
- const col1Values = data.map(row => Number(row[numericColumns[i]])).filter(v => !isNaN(v));
490
- const col2Values = data.map(row => Number(row[numericColumns[j]])).filter(v => !isNaN(v));
491
-
492
- const correlation = calculateCorrelation(col1Values, col2Values);
493
- matrix[i][j] = roundTo(correlation, 4);
494
- matrix[j][i] = roundTo(correlation, 4);
495
-
496
- if (Math.abs(correlation) > 0.5) {
497
- pairs.push({
498
- col1: numericColumns[i],
499
- col2: numericColumns[j],
500
- correlation: roundTo(correlation, 4),
501
- });
502
- }
503
- }
504
- }
505
- }
506
-
507
- pairs.sort((a, b) => Math.abs(b.correlation) - Math.abs(a.correlation));
508
-
509
- return { matrix, pairs };
510
- }
511
-
512
- function detectTrends(data: any[], columnStats: ColumnStats[]): {
513
- detected: boolean;
514
- patterns: string[];
515
- insights: string[];
516
- } {
517
- const patterns: string[] = [];
518
- const insights: string[] = [];
519
-
520
- // Check for time-series columns
521
- const dateColumns = columnStats.filter(col => col.dataType === 'date');
522
- const numericColumns = columnStats.filter(col => col.dataType === 'numeric');
523
-
524
- if (dateColumns.length > 0 && numericColumns.length > 0) {
525
- patterns.push('Time-series data detected');
526
- insights.push('Consider visualizing trends over time');
527
- }
528
-
529
- // Check for monotonic trends
530
- numericColumns.forEach(col => {
531
- if (col.skewness && Math.abs(col.skewness) > 1) {
532
- patterns.push(`${col.name} shows ${col.skewness > 0 ? 'positive' : 'negative'} skew`);
533
- }
534
- });
535
-
536
- return {
537
- detected: patterns.length > 0,
538
- patterns,
539
- insights,
540
- };
541
- }
542
-
543
- function generateVisualizationRecommendations(columnStats: ColumnStats[]): Array<{
544
- column: string;
545
- chartType: string;
546
- reason: string;
547
- }> {
548
- const recommendations: Array<{ column: string; chartType: string; reason: string }> = [];
549
-
550
- columnStats.forEach(col => {
551
- if (col.dataType === 'numeric') {
552
- if (col.uniqueCount > 20) {
553
- recommendations.push({
554
- column: col.name,
555
- chartType: 'Histogram',
556
- reason: 'Shows distribution of continuous numeric values',
557
- });
558
- } else {
559
- recommendations.push({
560
- column: col.name,
561
- chartType: 'Bar Chart',
562
- reason: 'Shows distribution of discrete numeric values',
563
- });
564
- }
565
- } else if (col.dataType === 'string' && col.uniqueCount <= 20) {
566
- recommendations.push({
567
- column: col.name,
568
- chartType: 'Pie Chart / Bar Chart',
569
- reason: 'Shows category distribution',
570
- });
571
- } else if (col.dataType === 'date') {
572
- recommendations.push({
573
- column: col.name,
574
- chartType: 'Line Chart',
575
- reason: 'Shows trends over time',
576
- });
577
- }
578
- });
579
-
580
- return recommendations;
581
- }
582
-
583
- function calculateDataQuality(columnStats: ColumnStats[], data: any[]): {
584
- totalCells: number;
585
- missingCells: number;
586
- missingPercentage: number;
587
- duplicateRows: number;
588
- duplicatePercentage: number;
589
- dataQualityScore: number;
590
- issues: string[];
591
- } {
592
- const totalCells = data.length * columnStats.length;
593
- const missingCells = columnStats.reduce((sum, col) => sum + col.nullCount, 0);
594
- const missingPercentage = roundTo((missingCells / totalCells) * 100, 2);
595
-
596
- // Detect duplicates
597
- const rowStrings = data.map(row => JSON.stringify(row));
598
- const uniqueRows = new Set(rowStrings);
599
- const duplicateRows = data.length - uniqueRows.size;
600
- const duplicatePercentage = roundTo((duplicateRows / data.length) * 100, 2);
601
-
602
- // Quality issues
603
- const issues: string[] = [];
604
-
605
- if (missingPercentage > 10) {
606
- issues.push(`High missing data rate: ${missingPercentage}%`);
607
- }
608
-
609
- if (duplicateRows > 0) {
610
- issues.push(`${duplicateRows} duplicate rows found`);
611
- }
612
-
613
- columnStats.forEach(col => {
614
- if (col.dataType === 'mixed') {
615
- issues.push(`Column "${col.name}" has mixed data types`);
616
- }
617
- if (col.nullPercentage > 50) {
618
- issues.push(`Column "${col.name}" has ${col.nullPercentage}% missing values`);
619
- }
620
- });
621
-
622
- // Calculate quality score (0-100)
623
- let score = 100;
624
- score -= Math.min(missingPercentage * 2, 30);
625
- score -= Math.min(duplicatePercentage * 1.5, 20);
626
- score -= Math.min(issues.length * 5, 30);
627
-
628
- return {
629
- totalCells,
630
- missingCells,
631
- missingPercentage,
632
- duplicateRows,
633
- duplicatePercentage,
634
- dataQualityScore: Math.max(0, Math.round(score)),
635
- issues,
636
- };
637
- }
638
-
639
- function generateInsights(report: AnalysisReport): string[] {
640
- const insights: string[] = [];
641
-
642
- // Dataset size insights
643
- if (report.overview.rowCount < 100) {
644
- insights.push('Small dataset - consider collecting more data for robust analysis');
645
- } else if (report.overview.rowCount > 10000) {
646
- insights.push('Large dataset - suitable for machine learning applications');
647
- }
648
-
649
- // Data quality insights
650
- if (report.quality.dataQualityScore >= 90) {
651
- insights.push('Excellent data quality - ready for analysis');
652
- } else if (report.quality.dataQualityScore >= 70) {
653
- insights.push('Good data quality - minor cleaning recommended');
654
- } else {
655
- insights.push('Data quality issues detected - cleaning required before analysis');
656
- }
657
-
658
- // Column insights
659
- const numericCols = report.columns.filter(col => col.dataType === 'numeric');
660
- const categoricalCols = report.columns.filter(col => col.dataType === 'string' && (col.uniqueCount || 0) <= 20);
661
-
662
- if (numericCols.length > 3) {
663
- insights.push(`${numericCols.length} numeric columns - suitable for correlation and regression analysis`);
664
- }
665
-
666
- if (categoricalCols.length > 0) {
667
- insights.push(`${categoricalCols.length} categorical columns - consider segmentation analysis`);
668
- }
669
-
670
- // Correlation insights
671
- if (report.correlationPairs && report.correlationPairs.length > 0) {
672
- const strongPairs = report.correlationPairs.filter(p => Math.abs(p.correlation) > 0.7);
673
- if (strongPairs.length > 0) {
674
- insights.push(`${strongPairs.length} strong correlations found - potential feature engineering opportunities`);
675
- }
676
- }
677
-
678
- // Outlier insights
679
- const colsWithOutliers = report.columns.filter(col => col.outliers && col.outliers.length > 0);
680
- if (colsWithOutliers.length > 0) {
681
- insights.push(`Outliers detected in ${colsWithOutliers.length} columns - review for data errors or special cases`);
682
- }
683
-
684
- return insights;
685
- }
686
-
687
- // ============================================================================
688
- // Output Formatters
689
- // ============================================================================
690
-
691
- function formatMarkdown(report: AnalysisReport): string {
692
- let md = '# Data Analysis Report\n\n';
693
-
694
- md += `**Generated**: ${report.overview.timestamp} \n`;
695
- md += `**Processing Time**: ${report.overview.processingTime}ms\n\n`;
696
-
697
- // Overview
698
- md += '## Dataset Overview\n\n';
699
- md += `- **File**: ${report.overview.fileName}\n`;
700
- md += `- **Size**: ${report.overview.fileSize}\n`;
701
- md += `- **Type**: ${report.overview.fileType}\n`;
702
- md += `- **Rows**: ${report.overview.rowCount.toLocaleString()}\n`;
703
- md += `- **Columns**: ${report.overview.columnCount}\n`;
704
- md += `- **Memory Usage**: ${report.overview.memoryUsage}\n\n`;
705
-
706
- // Column Analysis
707
- md += '## Column Analysis\n\n';
708
-
709
- report.columns.forEach(col => {
710
- md += `### ${col.name}\n\n`;
711
- md += `- **Type**: ${col.dataType}\n`;
712
- md += `- **Count**: ${col.count.toLocaleString()}\n`;
713
- md += `- **Null**: ${col.nullCount} (${col.nullPercentage}%)\n`;
714
- md += `- **Unique**: ${col.uniqueCount} (${col.uniquePercentage}%)\n`;
715
- md += `- **Sample**: ${col.sampleValues.join(', ')}\n`;
716
-
717
- if (col.dataType === 'numeric') {
718
- md += '\n**Statistics**:\n\n';
719
- md += `| Metric | Value |\n`;
720
- md += `|--------|-------|\n`;
721
- md += `| Mean | ${col.mean} |\n`;
722
- md += `| Median | ${col.median} |\n`;
723
- md += `| Std Dev | ${col.stdDev} |\n`;
724
- md += `| Min | ${col.min} |\n`;
725
- md += `| Max | ${col.max} |\n`;
726
- md += `| Q1 | ${col.q1} |\n`;
727
- md += `| Q3 | ${col.q3} |\n`;
728
-
729
- if (col.outliers && col.outliers.length > 0) {
730
- md += `\n**Outliers**: ${col.outliers.length} detected\n`;
731
- }
732
- }
733
-
734
- if (col.topValues && col.topValues.length > 0) {
735
- md += '\n**Top Values**:\n\n';
736
- md += `| Value | Count | Percentage |\n`;
737
- md += `|-------|-------|------------|\n`;
738
- col.topValues.forEach(tv => {
739
- md += `| ${tv.value} | ${tv.count} | ${tv.percentage}% |\n`;
740
- });
741
- }
742
-
743
- md += '\n';
744
- });
745
-
746
- // Correlations
747
- if (report.correlationPairs && report.correlationPairs.length > 0) {
748
- md += '## Correlation Analysis\n\n';
749
- md += '**Strong Correlations** (|r| > 0.5):\n\n';
750
- md += `| Column 1 | Column 2 | Correlation |\n`;
751
- md += `|----------|----------|-------------|\n`;
752
- report.correlationPairs.forEach(pair => {
753
- md += `| ${pair.col1} | ${pair.col2} | ${pair.correlation} |\n`;
754
- });
755
- md += '\n';
756
- }
757
-
758
- // Data Quality
759
- md += '## Data Quality\n\n';
760
- md += `- **Quality Score**: ${report.quality.dataQualityScore}/100\n`;
761
- md += `- **Missing Cells**: ${report.quality.missingCells} (${report.quality.missingPercentage}%)\n`;
762
- md += `- **Duplicate Rows**: ${report.quality.duplicateRows} (${report.quality.duplicatePercentage}%)\n\n`;
763
-
764
- if (report.quality.issues.length > 0) {
765
- md += '**Issues Found**:\n\n';
766
- report.quality.issues.forEach(issue => {
767
- md += `- ${issue}\n`;
768
- });
769
- md += '\n';
770
- }
771
-
772
- // Visualization Recommendations
773
- if (report.visualizationRecommendations.length > 0) {
774
- md += '## Visualization Recommendations\n\n';
775
- md += `| Column | Chart Type | Reason |\n`;
776
- md += `|--------|------------|--------|\n`;
777
- report.visualizationRecommendations.forEach(rec => {
778
- md += `| ${rec.column} | ${rec.chartType} | ${rec.reason} |\n`;
779
- });
780
- md += '\n';
781
- }
782
-
783
- // Insights
784
- if (report.insights.length > 0) {
785
- md += '## Key Insights\n\n';
786
- report.insights.forEach((insight, idx) => {
787
- md += `${idx + 1}. ${insight}\n`;
788
- });
789
- md += '\n';
790
- }
791
-
792
- md += '---\n\n';
793
- md += '*Generated by skills.md/analyze-data*\n';
794
-
795
- return md;
796
- }
797
-
798
- function formatHTML(report: AnalysisReport): string {
799
- return `<!DOCTYPE html>
800
- <html lang="en">
801
- <head>
802
- <meta charset="UTF-8">
803
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
804
- <title>Data Analysis Report - ${report.overview.fileName}</title>
805
- <style>
806
- * { margin: 0; padding: 0; box-sizing: border-box; }
807
- body {
808
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
809
- line-height: 1.6;
810
- color: #333;
811
- background: #f5f5f5;
812
- padding: 20px;
813
- }
814
- .container { max-width: 1200px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
815
- h1 { color: #2563eb; border-bottom: 3px solid #2563eb; padding-bottom: 10px; margin-bottom: 20px; }
816
- h2 { color: #1e40af; margin-top: 30px; margin-bottom: 15px; border-left: 4px solid #2563eb; padding-left: 10px; }
817
- h3 { color: #3b82f6; margin-top: 20px; margin-bottom: 10px; }
818
- .meta { color: #666; font-size: 14px; margin-bottom: 30px; }
819
- .overview { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; }
820
- .overview-item { background: #f8fafc; padding: 15px; border-radius: 6px; border-left: 3px solid #2563eb; }
821
- .overview-item strong { display: block; color: #1e40af; margin-bottom: 5px; }
822
- table { width: 100%; border-collapse: collapse; margin: 15px 0; }
823
- th, td { padding: 12px; text-align: left; border-bottom: 1px solid #e5e7eb; }
824
- th { background: #f8fafc; color: #1e40af; font-weight: 600; }
825
- tr:hover { background: #f8fafc; }
826
- .quality-score { font-size: 48px; font-weight: bold; color: #10b981; text-align: center; margin: 20px 0; }
827
- .quality-score.medium { color: #f59e0b; }
828
- .quality-score.low { color: #ef4444; }
829
- .issue { background: #fef2f2; border-left: 3px solid #ef4444; padding: 10px; margin: 5px 0; border-radius: 4px; }
830
- .insight { background: #f0f9ff; border-left: 3px solid #3b82f6; padding: 10px; margin: 5px 0; border-radius: 4px; }
831
- .column-card { background: #fafafa; padding: 20px; margin: 15px 0; border-radius: 6px; border: 1px solid #e5e7eb; }
832
- .badge { display: inline-block; padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; margin-right: 5px; }
833
- .badge.numeric { background: #dbeafe; color: #1e40af; }
834
- .badge.string { background: #fce7f3; color: #9f1239; }
835
- .badge.date { background: #d1fae5; color: #065f46; }
836
- .badge.boolean { background: #fef3c7; color: #92400e; }
837
- footer { text-align: center; margin-top: 40px; padding-top: 20px; border-top: 1px solid #e5e7eb; color: #666; font-size: 14px; }
838
- </style>
839
- </head>
840
- <body>
841
- <div class="container">
842
- <h1>📊 Data Analysis Report</h1>
843
- <div class="meta">
844
- Generated: ${report.overview.timestamp} | Processing Time: ${report.overview.processingTime}ms
845
- </div>
846
-
847
- <h2>Dataset Overview</h2>
848
- <div class="overview">
849
- <div class="overview-item"><strong>File</strong>${report.overview.fileName}</div>
850
- <div class="overview-item"><strong>Size</strong>${report.overview.fileSize}</div>
851
- <div class="overview-item"><strong>Type</strong>${report.overview.fileType}</div>
852
- <div class="overview-item"><strong>Rows</strong>${report.overview.rowCount.toLocaleString()}</div>
853
- <div class="overview-item"><strong>Columns</strong>${report.overview.columnCount}</div>
854
- <div class="overview-item"><strong>Memory</strong>${report.overview.memoryUsage}</div>
855
- </div>
856
-
857
- <h2>Data Quality</h2>
858
- <div class="quality-score ${report.quality.dataQualityScore >= 70 ? '' : report.quality.dataQualityScore >= 50 ? 'medium' : 'low'}">
859
- ${report.quality.dataQualityScore}/100
860
- </div>
861
- <table>
862
- <tr><th>Metric</th><th>Value</th></tr>
863
- <tr><td>Missing Cells</td><td>${report.quality.missingCells} (${report.quality.missingPercentage}%)</td></tr>
864
- <tr><td>Duplicate Rows</td><td>${report.quality.duplicateRows} (${report.quality.duplicatePercentage}%)</td></tr>
865
- </table>
866
- ${report.quality.issues.length > 0 ? `
867
- <h3>Issues Found</h3>
868
- ${report.quality.issues.map(issue => `<div class="issue">${issue}</div>`).join('')}
869
- ` : ''}
870
-
871
- <h2>Column Analysis</h2>
872
- ${report.columns.map(col => `
873
- <div class="column-card">
874
- <h3>${col.name} <span class="badge ${col.dataType}">${col.dataType}</span></h3>
875
- <table>
876
- <tr><td><strong>Count</strong></td><td>${col.count.toLocaleString()}</td></tr>
877
- <tr><td><strong>Null</strong></td><td>${col.nullCount} (${col.nullPercentage}%)</td></tr>
878
- <tr><td><strong>Unique</strong></td><td>${col.uniqueCount} (${col.uniquePercentage}%)</td></tr>
879
- ${col.dataType === 'numeric' ? `
880
- <tr><td><strong>Mean</strong></td><td>${col.mean}</td></tr>
881
- <tr><td><strong>Median</strong></td><td>${col.median}</td></tr>
882
- <tr><td><strong>Std Dev</strong></td><td>${col.stdDev}</td></tr>
883
- <tr><td><strong>Min / Max</strong></td><td>${col.min} / ${col.max}</td></tr>
884
- <tr><td><strong>Q1 / Q3</strong></td><td>${col.q1} / ${col.q3}</td></tr>
885
- ` : ''}
886
- </table>
887
- </div>
888
- `).join('')}
889
-
890
- ${report.correlationPairs && report.correlationPairs.length > 0 ? `
891
- <h2>Correlation Analysis</h2>
892
- <table>
893
- <tr><th>Column 1</th><th>Column 2</th><th>Correlation</th></tr>
894
- ${report.correlationPairs.map(pair => `
895
- <tr><td>${pair.col1}</td><td>${pair.col2}</td><td>${pair.correlation}</td></tr>
896
- `).join('')}
897
- </table>
898
- ` : ''}
899
-
900
- ${report.visualizationRecommendations.length > 0 ? `
901
- <h2>Visualization Recommendations</h2>
902
- <table>
903
- <tr><th>Column</th><th>Chart Type</th><th>Reason</th></tr>
904
- ${report.visualizationRecommendations.map(rec => `
905
- <tr><td>${rec.column}</td><td>${rec.chartType}</td><td>${rec.reason}</td></tr>
906
- `).join('')}
907
- </table>
908
- ` : ''}
909
-
910
- ${report.insights.length > 0 ? `
911
- <h2>Key Insights</h2>
912
- ${report.insights.map(insight => `<div class="insight">${insight}</div>`).join('')}
913
- ` : ''}
914
-
915
- <footer>
916
- Generated by <strong>skills.md/analyze-data</strong>
917
- </footer>
918
- </div>
919
- </body>
920
- </html>`;
921
- }
922
-
923
- // ============================================================================
924
- // Main Analysis Function
925
- // ============================================================================
926
-
927
- async function analyzeData(filePath: string, options: AnalysisOptions): Promise<AnalysisReport> {
928
- const startTime = Date.now();
929
-
930
- // Read file
931
- if (options.verbose) {
932
- log(`Reading file: ${filePath}`);
933
- }
934
-
935
- const fileStats = statSync(filePath);
936
- const fileExt = extname(filePath).toLowerCase();
937
- const content = readFileSync(filePath, 'utf-8');
938
-
939
- // Parse data
940
- let data: any[];
941
- if (fileExt === '.csv') {
942
- data = parseCSV(content);
943
- } else if (fileExt === '.json') {
944
- data = parseJSON(content);
945
- } else {
946
- throw new Error(`Unsupported file type: ${fileExt}`);
947
- }
948
-
949
- // Apply sampling
950
- if (options.sample && data.length > options.sample) {
951
- if (options.verbose) {
952
- log(`Sampling first ${options.sample} rows out of ${data.length}`);
953
- }
954
- data = data.slice(0, options.sample);
955
- }
956
-
957
- if (data.length === 0) {
958
- throw new Error('No data found in file');
959
- }
960
-
961
- // Get column names
962
- const columnNames = Object.keys(data[0]);
963
-
964
- if (options.verbose) {
965
- log(`Analyzing ${data.length} rows and ${columnNames.length} columns...`);
966
- }
967
-
968
- // Analyze each column
969
- const columnStats: ColumnStats[] = columnNames.map(colName => {
970
- const values = data.map(row => row[colName]);
971
- return analyzeColumn(colName, values, options);
972
- });
973
-
974
- // Correlation analysis
975
- let correlations: number[][] | undefined;
976
- let correlationPairs: Array<{ col1: string; col2: string; correlation: number }> | undefined;
977
-
978
- if (options.correlations) {
979
- const numericColumns = columnStats
980
- .filter(col => col.dataType === 'numeric')
981
- .map(col => col.name);
982
-
983
- if (numericColumns.length >= 2) {
984
- if (options.verbose) {
985
- log(`Calculating correlations for ${numericColumns.length} numeric columns...`);
986
- }
987
- const corrResult = analyzeCorrelations(data, numericColumns);
988
- correlations = corrResult.matrix;
989
- correlationPairs = corrResult.pairs;
990
- }
991
- }
992
-
993
- // Trend analysis
994
- let trends: AnalysisReport['trends'];
995
- if (options.trends) {
996
- if (options.verbose) {
997
- log('Analyzing trends...');
998
- }
999
- trends = detectTrends(data, columnStats);
1000
- }
1001
-
1002
- // Data quality
1003
- const quality = calculateDataQuality(columnStats, data);
1004
-
1005
- // Visualization recommendations
1006
- const visualizationRecommendations = generateVisualizationRecommendations(columnStats);
1007
-
1008
- // Build report
1009
- const report: AnalysisReport = {
1010
- overview: {
1011
- fileName: basename(filePath),
1012
- fileSize: formatBytes(fileStats.size),
1013
- fileType: fileExt.slice(1).toUpperCase(),
1014
- rowCount: data.length,
1015
- columnCount: columnNames.length,
1016
- memoryUsage: formatBytes(JSON.stringify(data).length),
1017
- processingTime: Date.now() - startTime,
1018
- timestamp: new Date().toISOString(),
1019
- },
1020
- columns: columnStats,
1021
- correlations,
1022
- correlationPairs,
1023
- quality,
1024
- trends,
1025
- visualizationRecommendations,
1026
- insights: [],
1027
- };
1028
-
1029
- // Generate insights
1030
- report.insights = generateInsights(report);
1031
-
1032
- return report;
1033
- }
1034
-
1035
- // ============================================================================
1036
- // Main Entry Point
1037
- // ============================================================================
13
+ import { analyzeData } from './analysis';
14
+ import { parseArguments } from './cli';
15
+ import { formatHTML, formatMarkdown } from './formatters';
16
+ import { log, SESSION_ID, SKILL_NAME } from './logger';
1038
17
 
1039
18
  async function main() {
1040
19
  try {