@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.
- package/LICENSE +1 -10
- package/README.md +141 -39
- package/bin/index.js +30122 -27575
- package/bin/mcp.js +22112 -18593
- package/dist/cli/cli.test-utils.d.ts +15 -0
- package/dist/cli/commands/auth.d.ts +2 -0
- package/dist/cli/commands/install.d.ts +1 -1
- package/dist/cli/commands/runtime-mcp.d.ts +4 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +11607 -597
- package/dist/lib/auth-store.d.ts +13 -0
- package/dist/lib/installer.d.ts +58 -55
- package/dist/lib/mcp-contracts.d.ts +86 -0
- package/dist/lib/project-state.d.ts +43 -0
- package/dist/lib/registry-data/business-marketing.d.ts +2 -0
- package/dist/lib/registry-data/communication.d.ts +2 -0
- package/dist/lib/registry-data/content-generation.d.ts +2 -0
- package/dist/lib/registry-data/data-analysis.d.ts +2 -0
- package/dist/lib/registry-data/design-branding.d.ts +2 -0
- package/dist/lib/registry-data/development-tools.d.ts +2 -0
- package/dist/lib/registry-data/education-learning.d.ts +2 -0
- package/dist/lib/registry-data/event-management.d.ts +2 -0
- package/dist/lib/registry-data/finance-compliance.d.ts +2 -0
- package/dist/lib/registry-data/health-wellness.d.ts +2 -0
- package/dist/lib/registry-data/index.d.ts +2 -0
- package/dist/lib/registry-data/media-processing.d.ts +2 -0
- package/dist/lib/registry-data/productivity-organization.d.ts +2 -0
- package/dist/lib/registry-data/project-management.d.ts +2 -0
- package/dist/lib/registry-data/research-writing.d.ts +2 -0
- package/dist/lib/registry-data/science-academic.d.ts +2 -0
- package/dist/lib/registry-data/travel-lifestyle.d.ts +2 -0
- package/dist/lib/registry-data/web-browser.d.ts +2 -0
- package/dist/lib/registry-types.d.ts +27 -0
- package/dist/lib/registry.d.ts +6 -18
- package/dist/lib/remote-registry.d.ts +3 -0
- package/dist/lib/run-state.d.ts +60 -0
- package/dist/lib/skill-aliases.d.ts +17 -0
- package/dist/lib/skillinfo.d.ts +5 -1
- package/dist/mcp/discovery-tools.d.ts +2 -0
- package/dist/mcp/helpers.d.ts +26 -0
- package/dist/mcp/http.d.ts +10 -0
- package/dist/mcp/index.d.ts +3 -2
- package/dist/mcp/operation-tools.d.ts +2 -0
- package/dist/mcp/resource-meta-tools.d.ts +2 -0
- package/dist/mcp/schedule-tools.d.ts +2 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/types/api.d.ts +7 -4
- package/package.json +23 -10
- package/skills/_common/http-client.ts +1 -1
- package/skills/_common/index.ts +2 -3
- package/skills/_common/install.sh +5 -110
- package/skills/_common/installer.ts +31 -282
- package/skills/_common/skill-install.ts +14 -181
- package/skills/ad-creative-pack/SKILL.md +45 -0
- package/skills/ad-creative-pack/package.json +14 -0
- package/skills/advanced-math/package.json +3 -1
- package/skills/advanced-math/src/calculators.ts +118 -0
- package/skills/advanced-math/src/cli.ts +130 -0
- package/skills/advanced-math/src/conversion.ts +90 -0
- package/skills/advanced-math/src/finance.ts +75 -0
- package/skills/advanced-math/src/formatting.ts +95 -0
- package/skills/advanced-math/src/index.ts +24 -702
- package/skills/advanced-math/src/runtime.ts +49 -0
- package/skills/advanced-math/src/symbolic.ts +110 -0
- package/skills/advanced-math/src/types.ts +36 -0
- package/skills/analyze-data/SKILL.md +2 -2
- package/skills/analyze-data/src/analysis.ts +401 -0
- package/skills/analyze-data/src/cli.ts +66 -0
- package/skills/analyze-data/src/formatters.ts +235 -0
- package/skills/analyze-data/src/index.ts +6 -1027
- package/skills/analyze-data/src/logger.ts +36 -0
- package/skills/analyze-data/src/parsers.ts +57 -0
- package/skills/analyze-data/src/stats.ts +151 -0
- package/skills/analyze-data/src/types.ts +85 -0
- package/skills/api-docs-portal/SKILL.md +46 -0
- package/skills/api-docs-portal/package.json +9 -0
- package/skills/api-test-suite/src/index.ts +13 -0
- package/skills/apidocs/package.json +1 -1
- package/skills/apidocs/src/index.ts +3 -0
- package/skills/audio/package.json +2 -3
- package/skills/audio-cleanup-lab/SKILL.md +2 -2
- package/skills/audio-extract/CLAUDE.md +1 -1
- package/skills/audio-transcript-pack/SKILL.md +43 -0
- package/skills/audio-transcript-pack/package.json +10 -0
- package/skills/blog-article/CLAUDE.md +12 -0
- package/skills/blog-article/SKILL.md +45 -0
- package/skills/{create-blog-article → blog-article}/package.json +3 -3
- package/skills/brand-kit/SKILL.md +45 -0
- package/skills/brand-kit/package.json +14 -0
- package/skills/brand-photo-shoot/SKILL.md +28 -0
- package/skills/brand-photo-shoot/package.json +10 -0
- package/skills/brand-style-guide/SKILL.md +2 -2
- package/skills/brand-style-guide/src/index.ts +0 -0
- package/skills/budget-variance-analyzer/SKILL.md +2 -2
- package/skills/businessactivity/package.json +1 -1
- package/skills/businessactivity/src/index.ts +3 -0
- package/skills/calendar-events/src/ai-parser.ts +103 -0
- package/skills/calendar-events/src/api.ts +157 -0
- package/skills/calendar-events/src/auth.ts +22 -0
- package/skills/calendar-events/src/config.ts +6 -0
- package/skills/calendar-events/src/format.ts +96 -0
- package/skills/calendar-events/src/help.ts +54 -0
- package/skills/calendar-events/src/index.ts +21 -524
- package/skills/calendar-events/src/logger.ts +34 -0
- package/skills/calendar-events/src/types.ts +67 -0
- package/skills/compress-video/SKILL.md +2 -2
- package/skills/consolelog/package.json +1 -1
- package/skills/consolelog/src/index.ts +3 -0
- package/skills/contract-review-report/SKILL.md +43 -0
- package/skills/contract-review-report/package.json +10 -0
- package/skills/convert/SKILL.md +2 -3
- package/skills/customer-feedback-report/SKILL.md +44 -0
- package/skills/customer-feedback-report/package.json +10 -0
- package/skills/dashboard-builder/package.json +3 -1
- package/skills/database-explorer/package.json +3 -1
- package/skills/deepresearch/README.md +4 -13
- package/skills/deploy/src/http-client.ts +1 -1
- package/skills/diff-viewer/package.json +4 -1
- package/skills/doc-generate/package.json +0 -1
- package/skills/doc-generate/src/ai.ts +50 -0
- package/skills/doc-generate/src/cli.ts +203 -0
- package/skills/doc-generate/src/dependencies.ts +44 -0
- package/skills/doc-generate/src/document-builder.ts +299 -0
- package/skills/doc-generate/src/index.ts +40 -764
- package/skills/doc-generate/src/markdown-parser.ts +125 -0
- package/skills/doc-generate/src/types.ts +68 -0
- package/skills/domainpurchase/SKILL.md +1 -1
- package/skills/domainpurchase/package.json +1 -1
- package/skills/domainpurchase/src/index.ts +3 -0
- package/skills/domainsearch/SKILL.md +1 -1
- package/skills/domainsearch/package.json +1 -1
- package/skills/domainsearch/src/index.ts +3 -0
- package/skills/email-sequence/SKILL.md +44 -0
- package/skills/email-sequence/package.json +14 -0
- package/skills/excel/CLAUDE.md +2 -2
- package/skills/experiment-power-calculator/package.json +3 -1
- package/skills/extract-invoice/src/cli.ts +97 -0
- package/skills/extract-invoice/src/extractor.ts +170 -0
- package/skills/extract-invoice/src/file-utils.ts +46 -0
- package/skills/extract-invoice/src/formatters.ts +144 -0
- package/skills/extract-invoice/src/index.ts +44 -629
- package/skills/extract-invoice/src/runtime.ts +46 -0
- package/skills/extract-invoice/src/types.ts +88 -0
- package/skills/folder-tree/package.json +3 -1
- package/skills/form-filler/package.json +3 -1
- package/skills/generate-api-client/package.json +3 -1
- package/skills/generate-api-client/src/generator.ts +47 -0
- package/skills/generate-api-client/src/index.ts +3 -777
- package/skills/generate-api-client/src/logger.ts +34 -0
- package/skills/generate-api-client/src/python-generator.ts +245 -0
- package/skills/generate-api-client/src/spec-loader.ts +48 -0
- package/skills/generate-api-client/src/type-mappers.ts +79 -0
- package/skills/generate-api-client/src/types.ts +76 -0
- package/skills/generate-api-client/src/typescript-generator.ts +247 -0
- package/skills/generate-book-cover/package.json +3 -1
- package/skills/generate-dockerfile/src/cli.ts +78 -0
- package/skills/generate-dockerfile/src/dockerfile-templates.ts +392 -0
- package/skills/generate-dockerfile/src/index.ts +12 -790
- package/skills/generate-dockerfile/src/logger.ts +30 -0
- package/skills/generate-dockerfile/src/project-detection.ts +68 -0
- package/skills/generate-dockerfile/src/support-files.ts +171 -0
- package/skills/generate-dockerfile/src/types.ts +29 -0
- package/skills/generate-documentation/src/ai.ts +131 -0
- package/skills/generate-documentation/src/cli.ts +71 -0
- package/skills/generate-documentation/src/code-parser.ts +300 -0
- package/skills/generate-documentation/src/file-processing.ts +182 -0
- package/skills/generate-documentation/src/index.ts +13 -753
- package/skills/generate-documentation/src/runtime.ts +35 -0
- package/skills/generate-documentation/src/types.ts +30 -0
- package/skills/generate-env/package.json +3 -1
- package/skills/generate-env/src/cli.ts +85 -0
- package/skills/generate-env/src/detection.ts +161 -0
- package/skills/generate-env/src/env-data.ts +66 -0
- package/skills/generate-env/src/generators.ts +240 -0
- package/skills/generate-env/src/index.ts +76 -676
- package/skills/generate-env/src/runtime.ts +30 -0
- package/skills/generate-env/src/types.ts +32 -0
- package/skills/generate-favicon/package.json +3 -1
- package/skills/generate-mock-data/package.json +3 -1
- package/skills/generate-mock-data/src/ai.ts +102 -0
- package/skills/generate-mock-data/src/formatters.ts +84 -0
- package/skills/generate-mock-data/src/generator.ts +377 -0
- package/skills/generate-mock-data/src/index.ts +15 -716
- package/skills/generate-mock-data/src/logger.ts +37 -0
- package/skills/generate-mock-data/src/presets.ts +110 -0
- package/skills/generate-mock-data/src/types.ts +21 -0
- package/skills/generate-pr-description/src/ai.ts +144 -0
- package/skills/generate-pr-description/src/cli.ts +80 -0
- package/skills/generate-pr-description/src/clipboard.ts +30 -0
- package/skills/generate-pr-description/src/formatters.ts +231 -0
- package/skills/generate-pr-description/src/git.ts +153 -0
- package/skills/generate-pr-description/src/index.ts +21 -714
- package/skills/generate-pr-description/src/types.ts +49 -0
- package/skills/generate-presentation/src/ai-clients.ts +61 -0
- package/skills/generate-presentation/src/cli.ts +126 -0
- package/skills/generate-presentation/src/index.ts +3 -751
- package/skills/generate-presentation/src/logger.ts +67 -0
- package/skills/generate-presentation/src/presentation-generator.ts +425 -0
- package/skills/generate-presentation/src/runtime.ts +6 -0
- package/skills/generate-presentation/src/security.ts +12 -0
- package/skills/generate-presentation/src/types.ts +28 -0
- package/skills/generate-qrcode/package.json +4 -1
- package/skills/generate-regex/package.json +3 -1
- package/skills/generate-resume/src/cli.ts +157 -0
- package/skills/generate-resume/src/index.ts +13 -917
- package/skills/generate-resume/src/parsers.ts +95 -0
- package/skills/generate-resume/src/renderers.ts +538 -0
- package/skills/generate-resume/src/security.ts +39 -0
- package/skills/generate-resume/src/types.ts +86 -0
- package/skills/generate-social-posts/src/ai.ts +88 -0
- package/skills/generate-social-posts/src/cli.ts +118 -0
- package/skills/generate-social-posts/src/exporters.ts +126 -0
- package/skills/generate-social-posts/src/generator.ts +130 -0
- package/skills/generate-social-posts/src/index.ts +19 -709
- package/skills/generate-social-posts/src/platforms.ts +39 -0
- package/skills/generate-social-posts/src/runtime.ts +34 -0
- package/skills/generate-social-posts/src/source.ts +116 -0
- package/skills/generate-social-posts/src/types.ts +58 -0
- package/skills/gif-maker/package.json +4 -1
- package/skills/github-manager/package.json +3 -1
- package/skills/gmail/CLAUDE.md +1 -1
- package/skills/highlight-reel-generator/src/index.ts +19 -0
- package/skills/hook/src/commands/create.ts +20 -845
- package/skills/hook/src/templates/root.ts +196 -0
- package/skills/hook/src/templates/source.ts +647 -0
- package/skills/http-server/package.json +3 -1
- package/skills/icon-pack/README.md +28 -0
- package/skills/icon-pack/SKILL.md +23 -0
- package/skills/icon-pack/package.json +29 -0
- package/skills/{audio → icon-pack}/tsconfig.json +10 -12
- package/skills/image/package.json +1 -2
- package/skills/implementation-agent/package.json +3 -1
- package/skills/implementation-agent/src/ai-generation.ts +225 -0
- package/skills/implementation-agent/src/index.ts +3 -960
- package/skills/implementation-agent/src/minimist.d.ts +15 -0
- package/skills/implementation-agent/src/templates.ts +686 -0
- package/skills/implementation-agent/src/types.ts +53 -0
- package/skills/implementation-plan/package.json +3 -1
- package/skills/implementation-todo/package.json +3 -1
- package/skills/invoice/package.json +1 -1
- package/skills/invoice/src/index.ts +3 -0
- package/skills/invoice-reconciliation/SKILL.md +42 -0
- package/skills/invoice-reconciliation/package.json +10 -0
- package/skills/landing-page-pack/SKILL.md +47 -0
- package/skills/landing-page-pack/package.json +14 -0
- package/skills/latex-table-generator/package.json +3 -1
- package/skills/logo-design/SKILL.md +25 -44
- package/skills/logo-design/package.json +3 -15
- package/skills/lorem-generator/package.json +3 -1
- package/skills/lorem-generator/src/index.ts +13 -0
- package/skills/managehook/package.json +1 -1
- package/skills/managehook/src/index.ts +3 -0
- package/skills/managemcp/package.json +1 -1
- package/skills/managemcp/src/index.ts +3 -0
- package/skills/manageskill/package.json +1 -1
- package/skills/manageskill/src/index.ts +3 -0
- package/skills/markdown-validator/package.json +3 -1
- package/skills/markdown-validator/src/index.ts +1 -4
- package/skills/market-research-report/SKILL.md +41 -0
- package/skills/market-research-report/package.json +10 -0
- package/skills/mcp-builder/package.json +4 -1
- package/skills/mcp-builder/src/ai-descriptions.ts +37 -0
- package/skills/mcp-builder/src/generators.ts +513 -0
- package/skills/mcp-builder/src/index.ts +7 -908
- package/skills/mcp-builder/src/minimist.d.ts +15 -0
- package/skills/mcp-builder/src/naming.ts +12 -0
- package/skills/mcp-builder/src/options.ts +170 -0
- package/skills/mcp-builder/src/templates.ts +149 -0
- package/skills/mcp-builder/src/types.ts +42 -0
- package/skills/meeting-pack/SKILL.md +43 -0
- package/skills/meeting-pack/package.json +10 -0
- package/skills/merge-pdfs/package.json +5 -1
- package/skills/migration-plan-pack/SKILL.md +45 -0
- package/skills/migration-plan-pack/package.json +10 -0
- package/skills/music/package.json +2 -3
- package/skills/music-album/SKILL.md +37 -0
- package/skills/music-album/package.json +10 -0
- package/skills/notion-manager/package.json +3 -1
- package/skills/npmpublish/CLAUDE.md +5 -8
- package/skills/npmpublish/README.md +5 -26
- package/skills/npmpublish/src/index.ts +9 -147
- package/skills/one-page-website/SKILL.md +46 -0
- package/skills/one-page-website/package.json +10 -0
- package/skills/one-page-website/tsconfig.json +8 -0
- package/skills/pdf-generate/src/cli.ts +162 -0
- package/skills/pdf-generate/src/html.ts +84 -0
- package/skills/pdf-generate/src/index.ts +11 -800
- package/skills/pdf-generate/src/markdown.ts +27 -0
- package/skills/pdf-generate/src/pdf-writer.ts +78 -0
- package/skills/pdf-generate/src/runtime.ts +34 -0
- package/skills/pdf-generate/src/security.ts +37 -0
- package/skills/pdf-generate/src/templates.ts +311 -0
- package/skills/pdf-generate/src/types.ts +28 -0
- package/skills/pdf-read/SKILL.md +10 -10
- package/skills/pdf-to-dataset/SKILL.md +45 -0
- package/skills/pdf-to-dataset/package.json +10 -0
- package/skills/pdf-to-markdown/SKILL.md +49 -0
- package/skills/pdf-to-markdown/package.json +10 -0
- package/skills/pdf-to-markdown/tsconfig.json +10 -0
- package/skills/performance-audit-report/SKILL.md +42 -0
- package/skills/performance-audit-report/package.json +10 -0
- package/skills/persona-based-adwriter/src/index.ts +19 -0
- package/skills/photo-album/SKILL.md +29 -0
- package/skills/photo-album/package.json +9 -0
- package/skills/photo-album/tsconfig.json +4 -0
- package/skills/pitch-deck/SKILL.md +43 -0
- package/skills/pitch-deck/package.json +9 -0
- package/skills/playlist-maker/SKILL.md +33 -0
- package/skills/playlist-maker/package.json +9 -0
- package/skills/playlist-maker/tsconfig.json +4 -0
- package/skills/product-mockup/SKILL.md +45 -0
- package/skills/product-mockup/package.json +3 -20
- package/skills/product-mockup/tsconfig.json +3 -5
- package/skills/project-retro-companion/src/index.ts +19 -0
- package/skills/proposal-pack/SKILL.md +45 -0
- package/skills/proposal-pack/package.json +10 -0
- package/skills/read-pdf/SKILL.md +5 -4
- package/skills/repo-onboarding-report/SKILL.md +42 -0
- package/skills/repo-onboarding-report/package.json +10 -0
- package/skills/sales-call-recapper/src/index.ts +20 -0
- package/skills/salescopy/package.json +1 -1
- package/skills/salescopy/src/index.ts +3 -0
- package/skills/scaffold-project/src/ai-detect.ts +136 -0
- package/skills/scaffold-project/src/file-generators.ts +292 -0
- package/skills/scaffold-project/src/index.ts +8 -991
- package/skills/scaffold-project/src/project-config.ts +338 -0
- package/skills/scaffold-project/src/templates.ts +173 -0
- package/skills/scaffold-project/src/types.ts +58 -0
- package/skills/scientific-figure-check/package.json +3 -1
- package/skills/sdk-generator/SKILL.md +45 -0
- package/skills/sdk-generator/package.json +10 -0
- package/skills/sdk-generator/tsconfig.json +8 -0
- package/skills/security-audit/src/index.ts +25 -6
- package/skills/security-audit-report/SKILL.md +40 -0
- package/skills/security-audit-report/package.json +10 -0
- package/skills/seo-content-pack/SKILL.md +44 -0
- package/skills/seo-content-pack/package.json +9 -0
- package/skills/short-video-pack/SKILL.md +30 -0
- package/skills/short-video-pack/package.json +10 -0
- package/skills/slack-assistant/package.json +3 -1
- package/skills/slide-deck-generator/SKILL.md +44 -0
- package/skills/slide-deck-generator/package.json +10 -0
- package/skills/sms/package.json +1 -1
- package/skills/sms/src/index.ts +15 -0
- package/skills/social-content-calendar/SKILL.md +45 -0
- package/skills/social-content-calendar/package.json +14 -0
- package/skills/split-pdf/package.json +4 -1
- package/skills/subtitle/package.json +2 -1
- package/skills/subtitle/src/index.ts +3 -0
- package/skills/terraform-generator/package.json +3 -1
- package/skills/test-suite-generator/SKILL.md +41 -0
- package/skills/test-suite-generator/package.json +10 -0
- package/skills/timesheet/package.json +1 -1
- package/skills/timesheet/src/index.ts +3 -0
- package/skills/transcript/SKILL.md +1 -8
- package/skills/validate-config/package.json +3 -1
- package/skills/video/package.json +6 -4
- package/skills/video-downloader/package.json +3 -1
- package/skills/video-highlight-pack/SKILL.md +44 -0
- package/skills/video-highlight-pack/package.json +10 -0
- package/skills/voiceover-jingle-pack/SKILL.md +28 -0
- package/skills/voiceover-jingle-pack/package.json +10 -0
- package/skills/watermark/package.json +6 -1
- package/skills/webcrawling/package.json +2 -1
- package/skills/write/SKILL.md +6 -6
- package/dist/server/serve.d.ts +0 -11
- package/skills/apidocs/.claude/settings.json +0 -5
- package/skills/audio/.env.example +0 -14
- package/skills/audio/QUICKSTART.md +0 -158
- package/skills/audio/README.md +0 -256
- package/skills/audio/src/index-local.ts +0 -206
- package/skills/audio/src/index.ts +0 -95
- package/skills/audio/src/providers/elevenlabs.ts +0 -115
- package/skills/audio/src/providers/google.ts +0 -116
- package/skills/audio/src/providers/minimax.ts +0 -83
- package/skills/audio/src/providers/openai.ts +0 -115
- package/skills/audio/src/types.ts +0 -79
- package/skills/audiobook-chapter-proofer/CLAUDE.md +0 -19
- package/skills/audiobook-chapter-proofer/package.json +0 -27
- package/skills/audiobook-chapter-proofer/src/index.ts +0 -285
- package/skills/browse/src/client.ts +0 -373
- package/skills/browse/src/index-local.ts +0 -430
- package/skills/browse/src/index.ts +0 -110
- package/skills/browse/src/sse-server.ts +0 -919
- package/skills/browse/src/types.ts +0 -104
- package/skills/consolelog/src/server/index.ts +0 -508
- package/skills/create-blog-article/CLAUDE.md +0 -19
- package/skills/create-blog-article/src/index.ts +0 -745
- package/skills/create-blog-article/tsconfig.json +0 -10
- package/skills/deepresearch/src/agents/query-generator.ts +0 -91
- package/skills/deepresearch/src/agents/synthesizer.ts +0 -111
- package/skills/deepresearch/src/index.ts +0 -224
- package/skills/deepresearch/src/research.ts +0 -166
- package/skills/deepresearch/src/services/anthropic.ts +0 -69
- package/skills/deepresearch/src/services/exa.ts +0 -108
- package/skills/deepresearch/src/services/firecrawl.ts +0 -88
- package/skills/deepresearch/src/services/openai.ts +0 -81
- package/skills/deepresearch/src/types.ts +0 -76
- package/skills/deepresearch/src/utils/file.ts +0 -111
- package/skills/deepresearch/src/utils/logger.ts +0 -84
- package/skills/domainpurchase/src/server/index.ts +0 -332
- package/skills/domainsearch/src/server/index.ts +0 -229
- package/skills/e2bswarm/README.md +0 -135
- package/skills/e2bswarm/SKILL.md +0 -118
- package/skills/e2bswarm/examples/tasks-example.json +0 -38
- package/skills/e2bswarm/package.json +0 -59
- package/skills/e2bswarm/src/commands/collect.ts +0 -135
- package/skills/e2bswarm/src/commands/install.ts +0 -164
- package/skills/e2bswarm/src/commands/kill.ts +0 -62
- package/skills/e2bswarm/src/commands/spawn.ts +0 -134
- package/skills/e2bswarm/src/commands/status.ts +0 -90
- package/skills/e2bswarm/src/commands/sync.ts +0 -208
- package/skills/e2bswarm/src/index.ts +0 -121
- package/skills/e2bswarm/src/lib/config.ts +0 -75
- package/skills/e2bswarm/src/lib/e2b.ts +0 -490
- package/skills/e2bswarm/src/lib/github.ts +0 -253
- package/skills/e2bswarm/src/lib/logger.ts +0 -41
- package/skills/e2bswarm/src/lib/paths.ts +0 -75
- package/skills/e2bswarm/src/lib/tasks.ts +0 -320
- package/skills/e2bswarm/src/types/index.ts +0 -107
- package/skills/e2bswarm/templates/codebox/e2b.Dockerfile +0 -38
- package/skills/e2bswarm/templates/codebox/e2b.toml +0 -3
- package/skills/e2bswarm/templates/setup.sh +0 -21
- package/skills/e2bswarm/tsconfig.json +0 -19
- package/skills/generate-book-cover/src/index.ts +0 -694
- package/skills/image/src/index-local.ts +0 -206
- package/skills/image/src/index.ts +0 -96
- package/skills/image/src/providers/google.ts +0 -79
- package/skills/image/src/providers/minimax.ts +0 -94
- package/skills/image/src/providers/openai.ts +0 -80
- package/skills/image/src/providers/xai.ts +0 -73
- package/skills/image/src/types.ts +0 -37
- package/skills/logo-design/CLAUDE.md +0 -30
- package/skills/logo-design/src/index.ts +0 -322
- package/skills/managehook/src/server/index.ts +0 -108
- package/skills/managemcp/src/server/index.ts +0 -108
- package/skills/manageskill/src/server/index.ts +0 -108
- package/skills/music/CLAUDE.md +0 -9
- package/skills/music/src/index.ts +0 -94
- package/skills/music/tsconfig.json +0 -10
- package/skills/pdf-read/src/index.ts +0 -320
- package/skills/product-mockup/CLAUDE.md +0 -19
- package/skills/product-mockup/src/index.ts +0 -290
- package/skills/read-pdf/src/index.ts +0 -388
- package/skills/remove-background/src/index.ts +0 -405
- package/skills/scaffold-project/my-app/.env.example +0 -2
- package/skills/scaffold-project/my-app/README.md +0 -72
- package/skills/scaffold-project/my-app/package.json +0 -29
- package/skills/scaffold-project/my-app/src/index.ts +0 -23
- package/skills/scaffold-project/my-app/tsconfig.json +0 -33
- package/skills/sound-effects/SKILL.md +0 -34
- package/skills/sound-effects/package.json +0 -21
- package/skills/sound-effects/src/index.ts +0 -172
- package/skills/sound-effects/tsconfig.json +0 -8
- package/skills/transcript/src/chunker.ts +0 -215
- package/skills/transcript/src/formatter.ts +0 -134
- package/skills/transcript/src/index-local.ts +0 -226
- package/skills/transcript/src/index.ts +0 -110
- package/skills/transcript/src/providers/elevenlabs.ts +0 -133
- package/skills/transcript/src/providers/gemini.ts +0 -192
- package/skills/transcript/src/providers/index.ts +0 -54
- package/skills/transcript/src/providers/openai.ts +0 -203
- package/skills/transcript/src/types.ts +0 -106
- package/skills/video/.env.example +0 -14
- package/skills/video/EXAMPLES.md +0 -266
- package/skills/video/LICENSE +0 -192
- package/skills/video/README.md +0 -174
- package/skills/video/src/cli.ts +0 -155
- package/skills/video/src/index-local.ts +0 -148
- package/skills/video/src/index.ts +0 -96
- package/skills/video/src/providers/google-veo.ts +0 -126
- package/skills/video/src/providers/index.ts +0 -22
- package/skills/video/src/providers/minimax.ts +0 -100
- package/skills/video/src/providers/openai-sora.ts +0 -164
- package/skills/video/src/providers/runway.ts +0 -159
- package/skills/video/src/types.ts +0 -35
- package/skills/video/tsconfig.json +0 -22
- package/skills/voiceover-casting-assistant/CLAUDE.md +0 -19
- package/skills/voiceover-casting-assistant/package.json +0 -27
- package/skills/voiceover-casting-assistant/src/index.ts +0 -255
- package/skills/voiceover-casting-assistant/tsconfig.json +0 -10
- package/skills/webcrawling/src/commands/config.ts +0 -34
- package/skills/webcrawling/src/commands/crawl.ts +0 -33
- package/skills/webcrawling/src/commands/scrape.ts +0 -32
- package/skills/webcrawling/src/commands/sessions.ts +0 -42
- package/skills/webcrawling/src/lib/crawler.ts +0 -174
- package/skills/webcrawling/src/lib/storage.ts +0 -130
- package/skills/webcrawling/src/types/index.ts +0 -45
- package/skills/webcrawling/src/utils/logger.ts +0 -30
- package/skills/webcrawling/src/utils/paths.ts +0 -28
- /package/skills/{audiobook-chapter-proofer → blog-article}/tsconfig.json +0 -0
|
@@ -7,753 +7,9 @@
|
|
|
7
7
|
* Generates Marp-compatible markdown with speaker notes.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { constants } from "fs";
|
|
14
|
-
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Types & Interfaces
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
|
-
interface SkillOptions {
|
|
20
|
-
input: string;
|
|
21
|
-
isFile: boolean;
|
|
22
|
-
slides: number;
|
|
23
|
-
style: "business" | "educational" | "pitch-deck" | "technical" | "minimal";
|
|
24
|
-
format: "markdown" | "html" | "pdf";
|
|
25
|
-
includeNotes: boolean;
|
|
26
|
-
template: "default" | "modern" | "dark" | "minimal" | "corporate";
|
|
27
|
-
aiProvider: "openai" | "anthropic";
|
|
28
|
-
output: string;
|
|
29
|
-
language: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface SlideContent {
|
|
33
|
-
number: number;
|
|
34
|
-
title: string;
|
|
35
|
-
content: string[];
|
|
36
|
-
notes?: string;
|
|
37
|
-
type: "title" | "agenda" | "content" | "summary" | "qa";
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface PresentationStructure {
|
|
41
|
-
title: string;
|
|
42
|
-
subtitle?: string;
|
|
43
|
-
author: string;
|
|
44
|
-
date: string;
|
|
45
|
-
slides: SlideContent[];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// ============================================================================
|
|
49
|
-
// Security: HTML Escaping to prevent XSS
|
|
50
|
-
// ============================================================================
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Escape HTML special characters to prevent XSS attacks
|
|
54
|
-
*/
|
|
55
|
-
function escapeHtml(str: string | undefined | null): string {
|
|
56
|
-
if (str === undefined || str === null) return "";
|
|
57
|
-
return String(str)
|
|
58
|
-
.replace(/&/g, "&")
|
|
59
|
-
.replace(/</g, "<")
|
|
60
|
-
.replace(/>/g, ">")
|
|
61
|
-
.replace(/"/g, """)
|
|
62
|
-
.replace(/'/g, "'");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ============================================================================
|
|
66
|
-
// Environment & Configuration
|
|
67
|
-
// ============================================================================
|
|
68
|
-
|
|
69
|
-
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || "";
|
|
70
|
-
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "";
|
|
71
|
-
const SKILLS_OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || ".skills";
|
|
72
|
-
const SKILLS_PROJECT_ROOT = process.env.SKILLS_PROJECT_ROOT || process.cwd();
|
|
73
|
-
|
|
74
|
-
// ============================================================================
|
|
75
|
-
// Logging Utility
|
|
76
|
-
// ============================================================================
|
|
77
|
-
|
|
78
|
-
class Logger {
|
|
79
|
-
private logFile: string;
|
|
80
|
-
private sessionId: string;
|
|
81
|
-
|
|
82
|
-
constructor() {
|
|
83
|
-
this.sessionId = new Date().toISOString().replace(/[:.]/g, "-");
|
|
84
|
-
this.logFile = join(
|
|
85
|
-
SKILLS_PROJECT_ROOT,
|
|
86
|
-
SKILLS_OUTPUT_DIR,
|
|
87
|
-
"logs",
|
|
88
|
-
"generate-presentation",
|
|
89
|
-
`${this.sessionId}.log`
|
|
90
|
-
);
|
|
91
|
-
this.initLogFile();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private async initLogFile() {
|
|
95
|
-
const logDir = join(
|
|
96
|
-
SKILLS_PROJECT_ROOT,
|
|
97
|
-
SKILLS_OUTPUT_DIR,
|
|
98
|
-
"logs",
|
|
99
|
-
"generate-presentation"
|
|
100
|
-
);
|
|
101
|
-
await mkdir(logDir, { recursive: true });
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private timestamp(): string {
|
|
105
|
-
return new Date().toISOString().replace("T", " ").split(".")[0];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
async log(message: string) {
|
|
109
|
-
const logMessage = `[${this.timestamp()}] ${message}`;
|
|
110
|
-
console.log(logMessage);
|
|
111
|
-
try {
|
|
112
|
-
await writeFile(this.logFile, logMessage + "\n", { flag: "a" });
|
|
113
|
-
} catch (error) {
|
|
114
|
-
// Silent fail for logging
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async error(message: string) {
|
|
119
|
-
const errorMessage = `[${this.timestamp()}] ERROR: ${message}`;
|
|
120
|
-
console.error(errorMessage);
|
|
121
|
-
try {
|
|
122
|
-
await writeFile(this.logFile, errorMessage + "\n", { flag: "a" });
|
|
123
|
-
} catch (error) {
|
|
124
|
-
// Silent fail for logging
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async success(message: string) {
|
|
129
|
-
const successMessage = `[${this.timestamp()}] SUCCESS: ${message}`;
|
|
130
|
-
console.log(successMessage);
|
|
131
|
-
try {
|
|
132
|
-
await writeFile(this.logFile, successMessage + "\n", { flag: "a" });
|
|
133
|
-
} catch (error) {
|
|
134
|
-
// Silent fail for logging
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ============================================================================
|
|
140
|
-
// AI Provider Clients
|
|
141
|
-
// ============================================================================
|
|
142
|
-
|
|
143
|
-
class OpenAIClient {
|
|
144
|
-
private apiKey: string;
|
|
145
|
-
|
|
146
|
-
constructor(apiKey: string) {
|
|
147
|
-
this.apiKey = apiKey;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async generateText(prompt: string, systemPrompt?: string): Promise<string> {
|
|
151
|
-
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: {
|
|
154
|
-
"Authorization": `Bearer ${this.apiKey}`,
|
|
155
|
-
"Content-Type": "application/json",
|
|
156
|
-
},
|
|
157
|
-
body: JSON.stringify({
|
|
158
|
-
model: "gpt-4-turbo-preview",
|
|
159
|
-
messages: [
|
|
160
|
-
...(systemPrompt ? [{ role: "system", content: systemPrompt }] : []),
|
|
161
|
-
{ role: "user", content: prompt },
|
|
162
|
-
],
|
|
163
|
-
temperature: 0.7,
|
|
164
|
-
max_tokens: 3000,
|
|
165
|
-
}),
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!response.ok) {
|
|
169
|
-
const error = await response.text();
|
|
170
|
-
throw new Error(`OpenAI API error: ${error}`);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const data = await response.json();
|
|
174
|
-
return data.choices[0].message.content;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
class AnthropicClient {
|
|
179
|
-
private apiKey: string;
|
|
180
|
-
|
|
181
|
-
constructor(apiKey: string) {
|
|
182
|
-
this.apiKey = apiKey;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async generateText(prompt: string, systemPrompt?: string): Promise<string> {
|
|
186
|
-
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: {
|
|
189
|
-
"x-api-key": this.apiKey,
|
|
190
|
-
"anthropic-version": "2023-06-01",
|
|
191
|
-
"Content-Type": "application/json",
|
|
192
|
-
},
|
|
193
|
-
body: JSON.stringify({
|
|
194
|
-
model: "claude-3-5-sonnet-20241022",
|
|
195
|
-
max_tokens: 3000,
|
|
196
|
-
system: systemPrompt || undefined,
|
|
197
|
-
messages: [
|
|
198
|
-
{ role: "user", content: prompt },
|
|
199
|
-
],
|
|
200
|
-
}),
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
if (!response.ok) {
|
|
204
|
-
const error = await response.text();
|
|
205
|
-
throw new Error(`Anthropic API error: ${error}`);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const data = await response.json();
|
|
209
|
-
return data.content[0].text;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// ============================================================================
|
|
214
|
-
// Presentation Generator
|
|
215
|
-
// ============================================================================
|
|
216
|
-
|
|
217
|
-
class PresentationGenerator {
|
|
218
|
-
private logger: Logger;
|
|
219
|
-
private options: SkillOptions;
|
|
220
|
-
private outputDir: string;
|
|
221
|
-
private openaiClient?: OpenAIClient;
|
|
222
|
-
private anthropicClient?: AnthropicClient;
|
|
223
|
-
|
|
224
|
-
constructor(options: SkillOptions, logger: Logger) {
|
|
225
|
-
this.logger = logger;
|
|
226
|
-
this.options = options;
|
|
227
|
-
this.outputDir = join(SKILLS_PROJECT_ROOT, options.output);
|
|
228
|
-
|
|
229
|
-
// Initialize AI clients
|
|
230
|
-
if (options.aiProvider === "openai" && OPENAI_API_KEY) {
|
|
231
|
-
this.openaiClient = new OpenAIClient(OPENAI_API_KEY);
|
|
232
|
-
} else if (options.aiProvider === "anthropic" && ANTHROPIC_API_KEY) {
|
|
233
|
-
this.anthropicClient = new AnthropicClient(ANTHROPIC_API_KEY);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async generate(): Promise<void> {
|
|
238
|
-
await this.logger.log(`Starting presentation generation: "${this.options.input}"`);
|
|
239
|
-
|
|
240
|
-
// Step 1: Load or prepare input content
|
|
241
|
-
const inputContent = await this.loadInput();
|
|
242
|
-
await this.logger.success(`Input content loaded`);
|
|
243
|
-
|
|
244
|
-
// Step 2: Generate presentation structure
|
|
245
|
-
const structure = await this.generateStructure(inputContent);
|
|
246
|
-
await this.logger.success(`Generated presentation structure (${structure.slides.length} slides)`);
|
|
247
|
-
|
|
248
|
-
// Step 3: Generate content for each slide
|
|
249
|
-
await this.logger.log("Generating slide content...");
|
|
250
|
-
for (let i = 0; i < structure.slides.length; i++) {
|
|
251
|
-
const slide = structure.slides[i];
|
|
252
|
-
await this.generateSlideContent(slide, inputContent);
|
|
253
|
-
await this.logger.success(`Generated slide ${i + 1}/${structure.slides.length}: ${slide.title}`);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Step 4: Compile presentation
|
|
257
|
-
await this.logger.log("Compiling presentation...");
|
|
258
|
-
const markdown = this.compileMarpMarkdown(structure);
|
|
259
|
-
|
|
260
|
-
// Step 5: Save output
|
|
261
|
-
await mkdir(this.outputDir, { recursive: true });
|
|
262
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").split("T").join("-").substring(0, 19);
|
|
263
|
-
const baseName = `presentation-${timestamp}`;
|
|
264
|
-
|
|
265
|
-
const markdownPath = join(this.outputDir, `${baseName}.md`);
|
|
266
|
-
await writeFile(markdownPath, markdown);
|
|
267
|
-
await this.logger.success(`Saved Markdown: ${markdownPath}`);
|
|
268
|
-
|
|
269
|
-
// Step 6: Convert to other formats if requested
|
|
270
|
-
if (this.options.format === "html") {
|
|
271
|
-
await this.convertToHTML(markdown, baseName);
|
|
272
|
-
} else if (this.options.format === "pdf") {
|
|
273
|
-
await this.convertToPDF(markdownPath, baseName);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Save metadata
|
|
277
|
-
const metadata = {
|
|
278
|
-
title: structure.title,
|
|
279
|
-
author: structure.author,
|
|
280
|
-
date: structure.date,
|
|
281
|
-
slides: structure.slides.length,
|
|
282
|
-
style: this.options.style,
|
|
283
|
-
format: this.options.format,
|
|
284
|
-
generated: new Date().toISOString(),
|
|
285
|
-
};
|
|
286
|
-
await writeFile(
|
|
287
|
-
join(this.outputDir, "metadata.json"),
|
|
288
|
-
JSON.stringify(metadata, null, 2)
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
await this.logger.success("Presentation generation complete!");
|
|
292
|
-
console.log(`\nOutput: ${markdownPath}`);
|
|
293
|
-
console.log(`Slides: ${structure.slides.length}`);
|
|
294
|
-
console.log(`Style: ${this.options.style}`);
|
|
295
|
-
|
|
296
|
-
if (this.options.format === "markdown") {
|
|
297
|
-
console.log("\nTo convert to PowerPoint or PDF, install Marp CLI:");
|
|
298
|
-
console.log(" npm install -g @marp-team/marp-cli");
|
|
299
|
-
console.log(` marp ${baseName}.md -o ${baseName}.pptx`);
|
|
300
|
-
console.log(` marp ${baseName}.md -o ${baseName}.pdf`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
private async loadInput(): Promise<string> {
|
|
305
|
-
if (this.options.isFile) {
|
|
306
|
-
try {
|
|
307
|
-
await access(this.options.input, constants.R_OK);
|
|
308
|
-
const content = await readFile(this.options.input, "utf-8");
|
|
309
|
-
return content;
|
|
310
|
-
} catch (error) {
|
|
311
|
-
throw new Error(`Cannot read file: ${this.options.input}`);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return this.options.input;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
private async generateStructure(inputContent: string): Promise<PresentationStructure> {
|
|
318
|
-
const systemPrompt = this.buildSystemPrompt();
|
|
319
|
-
const prompt = `Generate a presentation structure for ${this.options.slides} slides about:
|
|
320
|
-
|
|
321
|
-
${inputContent}
|
|
322
|
-
|
|
323
|
-
Requirements:
|
|
324
|
-
- Style: ${this.options.style}
|
|
325
|
-
- Total slides: ${this.options.slides} (including title, agenda, summary, and Q&A)
|
|
326
|
-
- Language: ${this.options.language}
|
|
327
|
-
- Structure: Title slide + Agenda + Content slides + Summary + Q&A
|
|
328
|
-
|
|
329
|
-
Return ONLY a valid JSON object (no markdown, no code blocks):
|
|
330
|
-
{
|
|
331
|
-
"title": "Presentation Title",
|
|
332
|
-
"subtitle": "Optional subtitle",
|
|
333
|
-
"author": "skills.md",
|
|
334
|
-
"date": "${new Date().toISOString().split('T')[0]}",
|
|
335
|
-
"slides": [
|
|
336
|
-
{
|
|
337
|
-
"number": 1,
|
|
338
|
-
"title": "Title",
|
|
339
|
-
"content": [],
|
|
340
|
-
"type": "title"
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
"number": 2,
|
|
344
|
-
"title": "Agenda",
|
|
345
|
-
"content": ["Topic 1", "Topic 2", "Topic 3"],
|
|
346
|
-
"type": "agenda"
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
"number": 3,
|
|
350
|
-
"title": "Content Slide Title",
|
|
351
|
-
"content": ["Point 1", "Point 2", "Point 3"],
|
|
352
|
-
"type": "content"
|
|
353
|
-
}
|
|
354
|
-
]
|
|
355
|
-
}`;
|
|
356
|
-
|
|
357
|
-
const response = await this.generateText(prompt, systemPrompt);
|
|
358
|
-
|
|
359
|
-
// Clean response
|
|
360
|
-
let cleanedResponse = response.trim();
|
|
361
|
-
if (cleanedResponse.startsWith("```")) {
|
|
362
|
-
cleanedResponse = cleanedResponse
|
|
363
|
-
.replace(/```json\n?/, "")
|
|
364
|
-
.replace(/```\n?$/, "")
|
|
365
|
-
.trim();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return JSON.parse(cleanedResponse);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
private async generateSlideContent(slide: SlideContent, inputContent: string): Promise<void> {
|
|
372
|
-
// Title and Q&A slides don't need AI-generated content
|
|
373
|
-
if (slide.type === "title" || slide.type === "qa") {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const systemPrompt = this.buildSystemPrompt();
|
|
378
|
-
const notesPrompt = this.options.includeNotes
|
|
379
|
-
? "\n\nAlso provide speaker notes (max 500 characters) for this slide."
|
|
380
|
-
: "";
|
|
381
|
-
|
|
382
|
-
const prompt = `Generate content for slide ${slide.number}: "${slide.title}"
|
|
383
|
-
|
|
384
|
-
Context: ${inputContent.substring(0, 1000)}
|
|
385
|
-
|
|
386
|
-
Requirements:
|
|
387
|
-
- Style: ${this.options.style}
|
|
388
|
-
- Type: ${slide.type}
|
|
389
|
-
- 3-5 concise bullet points
|
|
390
|
-
- Each point should be clear and impactful
|
|
391
|
-
- Language: ${this.options.language}${notesPrompt}
|
|
392
|
-
|
|
393
|
-
Return ONLY a valid JSON object (no markdown, no code blocks):
|
|
394
|
-
{
|
|
395
|
-
"content": ["Point 1", "Point 2", "Point 3"],
|
|
396
|
-
"notes": "Speaker notes here"
|
|
397
|
-
}`;
|
|
398
|
-
|
|
399
|
-
const response = await this.generateText(prompt, systemPrompt);
|
|
400
|
-
|
|
401
|
-
// Clean response
|
|
402
|
-
let cleanedResponse = response.trim();
|
|
403
|
-
if (cleanedResponse.startsWith("```")) {
|
|
404
|
-
cleanedResponse = cleanedResponse
|
|
405
|
-
.replace(/```json\n?/, "")
|
|
406
|
-
.replace(/```\n?$/, "")
|
|
407
|
-
.trim();
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const result = JSON.parse(cleanedResponse);
|
|
411
|
-
slide.content = result.content;
|
|
412
|
-
if (this.options.includeNotes && result.notes) {
|
|
413
|
-
slide.notes = result.notes;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
private compileMarpMarkdown(structure: PresentationStructure): string {
|
|
418
|
-
const themeConfig = this.getThemeConfig();
|
|
419
|
-
|
|
420
|
-
let markdown = `---
|
|
421
|
-
marp: true
|
|
422
|
-
theme: ${themeConfig.theme}
|
|
423
|
-
paginate: true
|
|
424
|
-
${themeConfig.backgroundColor ? `backgroundColor: ${themeConfig.backgroundColor}` : ""}
|
|
425
|
-
${themeConfig.color ? `color: ${themeConfig.color}` : ""}
|
|
426
|
-
---
|
|
427
|
-
|
|
428
|
-
`;
|
|
429
|
-
|
|
430
|
-
for (const slide of structure.slides) {
|
|
431
|
-
if (slide.type === "title") {
|
|
432
|
-
markdown += `# ${structure.title}\n\n`;
|
|
433
|
-
if (structure.subtitle) {
|
|
434
|
-
markdown += `${structure.subtitle}\n\n`;
|
|
435
|
-
}
|
|
436
|
-
markdown += `${structure.author}\n`;
|
|
437
|
-
markdown += `${structure.date}\n\n`;
|
|
438
|
-
} else if (slide.type === "qa") {
|
|
439
|
-
markdown += `## ${slide.title}\n\n`;
|
|
440
|
-
markdown += `Thank you for your attention\n\n`;
|
|
441
|
-
markdown += `Questions?\n\n`;
|
|
442
|
-
} else {
|
|
443
|
-
markdown += `## ${slide.title}\n\n`;
|
|
444
|
-
|
|
445
|
-
if (slide.content && slide.content.length > 0) {
|
|
446
|
-
for (const point of slide.content) {
|
|
447
|
-
markdown += `- ${point}\n`;
|
|
448
|
-
}
|
|
449
|
-
markdown += `\n`;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (slide.notes && this.options.includeNotes) {
|
|
454
|
-
markdown += `<!--\nSpeaker Notes:\n${slide.notes}\n-->\n\n`;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
markdown += `---\n\n`;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
return markdown.trim();
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
private getThemeConfig() {
|
|
464
|
-
const configs = {
|
|
465
|
-
default: { theme: "default" },
|
|
466
|
-
modern: { theme: "default", backgroundColor: "#f8f9fa" },
|
|
467
|
-
dark: { theme: "gaia", backgroundColor: "#1a1a1a", color: "#ffffff" },
|
|
468
|
-
minimal: { theme: "uncover" },
|
|
469
|
-
corporate: { theme: "default", backgroundColor: "#ffffff" },
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
return configs[this.options.template] || configs.default;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
private async convertToHTML(markdown: string, baseName: string): Promise<void> {
|
|
476
|
-
await this.logger.log("Converting to HTML...");
|
|
477
|
-
|
|
478
|
-
// Generate a simple Reveal.js HTML
|
|
479
|
-
const html = `<!DOCTYPE html>
|
|
480
|
-
<html lang="en">
|
|
481
|
-
<head>
|
|
482
|
-
<meta charset="UTF-8">
|
|
483
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
484
|
-
<title>Presentation</title>
|
|
485
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/reveal.css">
|
|
486
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/theme/white.css">
|
|
487
|
-
<style>
|
|
488
|
-
.reveal h1 { font-size: 2.5em; }
|
|
489
|
-
.reveal h2 { font-size: 2em; }
|
|
490
|
-
.reveal ul { font-size: 1.2em; }
|
|
491
|
-
</style>
|
|
492
|
-
</head>
|
|
493
|
-
<body>
|
|
494
|
-
<div class="reveal">
|
|
495
|
-
<div class="slides">
|
|
496
|
-
${this.markdownToRevealJS(markdown)}
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/reveal.js"></script>
|
|
500
|
-
<script>
|
|
501
|
-
Reveal.initialize({
|
|
502
|
-
hash: true,
|
|
503
|
-
slideNumber: true,
|
|
504
|
-
transition: 'slide'
|
|
505
|
-
});
|
|
506
|
-
</script>
|
|
507
|
-
</body>
|
|
508
|
-
</html>`;
|
|
509
|
-
|
|
510
|
-
const htmlPath = join(this.outputDir, `${baseName}.html`);
|
|
511
|
-
await writeFile(htmlPath, html);
|
|
512
|
-
await this.logger.success(`Saved HTML: ${htmlPath}`);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
private markdownToRevealJS(markdown: string): string {
|
|
516
|
-
const slides = markdown.split("---\n");
|
|
517
|
-
let html = "";
|
|
518
|
-
|
|
519
|
-
for (const slide of slides) {
|
|
520
|
-
const trimmed = slide.trim();
|
|
521
|
-
if (!trimmed || trimmed.startsWith("marp:") || trimmed.startsWith("theme:")) {
|
|
522
|
-
continue;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Remove speaker notes
|
|
526
|
-
const content = trimmed.replace(/<!--[\s\S]*?-->/g, "");
|
|
527
|
-
|
|
528
|
-
// Convert markdown to HTML with proper escaping
|
|
529
|
-
// First escape all content, then process markdown syntax
|
|
530
|
-
const lines = content.split("\n");
|
|
531
|
-
let slideHTML = "";
|
|
532
|
-
|
|
533
|
-
for (const line of lines) {
|
|
534
|
-
const trimmedLine = line.trim();
|
|
535
|
-
if (!trimmedLine) continue;
|
|
536
|
-
|
|
537
|
-
if (trimmedLine.startsWith("# ")) {
|
|
538
|
-
// H1 heading
|
|
539
|
-
slideHTML += `<h1>${escapeHtml(trimmedLine.slice(2))}</h1>\n`;
|
|
540
|
-
} else if (trimmedLine.startsWith("## ")) {
|
|
541
|
-
// H2 heading
|
|
542
|
-
slideHTML += `<h2>${escapeHtml(trimmedLine.slice(3))}</h2>\n`;
|
|
543
|
-
} else if (trimmedLine.startsWith("- ")) {
|
|
544
|
-
// List item - collect consecutive list items
|
|
545
|
-
slideHTML += `<li>${escapeHtml(trimmedLine.slice(2))}</li>\n`;
|
|
546
|
-
} else {
|
|
547
|
-
// Regular text
|
|
548
|
-
slideHTML += `<p>${escapeHtml(trimmedLine)}</p>\n`;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// Wrap consecutive list items in ul tags
|
|
553
|
-
slideHTML = slideHTML.replace(/(<li>[\s\S]*?<\/li>\n)+/g, (match) => `<ul>\n${match}</ul>\n`);
|
|
554
|
-
|
|
555
|
-
html += ` <section>\n${slideHTML} </section>\n`;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
return html;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
private async convertToPDF(markdownPath: string, baseName: string): Promise<void> {
|
|
562
|
-
await this.logger.log("Converting to PDF...");
|
|
563
|
-
|
|
564
|
-
// Check if Marp CLI is available
|
|
565
|
-
const marpCheck = Bun.spawn(["which", "marp"]);
|
|
566
|
-
await marpCheck.exited;
|
|
567
|
-
|
|
568
|
-
if (marpCheck.exitCode === 0) {
|
|
569
|
-
// Use Marp CLI
|
|
570
|
-
const pdfPath = join(this.outputDir, `${baseName}.pdf`);
|
|
571
|
-
const marp = Bun.spawn(["marp", markdownPath, "-o", pdfPath, "--allow-local-files"]);
|
|
572
|
-
await marp.exited;
|
|
573
|
-
|
|
574
|
-
if (marp.exitCode === 0) {
|
|
575
|
-
await this.logger.success(`Saved PDF: ${pdfPath}`);
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
// Fallback to Pandoc
|
|
581
|
-
const pandocCheck = Bun.spawn(["which", "pandoc"]);
|
|
582
|
-
await pandocCheck.exited;
|
|
583
|
-
|
|
584
|
-
if (pandocCheck.exitCode !== 0) {
|
|
585
|
-
throw new Error("PDF conversion requires either Marp CLI or Pandoc. Install with: npm install -g @marp-team/marp-cli");
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
const pdfPath = join(this.outputDir, `${baseName}.pdf`);
|
|
589
|
-
const pandoc = Bun.spawn([
|
|
590
|
-
"pandoc",
|
|
591
|
-
markdownPath,
|
|
592
|
-
"-o",
|
|
593
|
-
pdfPath,
|
|
594
|
-
"-t",
|
|
595
|
-
"beamer",
|
|
596
|
-
"--pdf-engine=xelatex",
|
|
597
|
-
]);
|
|
598
|
-
|
|
599
|
-
await pandoc.exited;
|
|
600
|
-
|
|
601
|
-
if (pandoc.exitCode !== 0) {
|
|
602
|
-
throw new Error(`PDF conversion failed with exit code ${pandoc.exitCode}`);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
await this.logger.success(`Saved PDF: ${pdfPath}`);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
private async generateText(prompt: string, systemPrompt?: string): Promise<string> {
|
|
609
|
-
if (this.openaiClient) {
|
|
610
|
-
return this.openaiClient.generateText(prompt, systemPrompt);
|
|
611
|
-
} else if (this.anthropicClient) {
|
|
612
|
-
return this.anthropicClient.generateText(prompt, systemPrompt);
|
|
613
|
-
} else {
|
|
614
|
-
throw new Error("No AI provider configured. Set OPENAI_API_KEY or ANTHROPIC_API_KEY");
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
private buildSystemPrompt(): string {
|
|
619
|
-
const styleContext = {
|
|
620
|
-
business: "Create professional, corporate-style content. Focus on metrics, ROI, and business value. Use formal language.",
|
|
621
|
-
educational: "Create clear, instructional content. Focus on teaching and explaining. Use simple, accessible language.",
|
|
622
|
-
"pitch-deck": "Create compelling, persuasive content. Focus on problem-solution and opportunity. Use engaging, impactful language.",
|
|
623
|
-
technical: "Create detailed, technical content. Focus on architecture, implementation, and best practices. Use precise terminology.",
|
|
624
|
-
minimal: "Create concise, impactful content. Focus on key points only. Use brief, powerful statements.",
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
return `You are an expert presentation designer. ${styleContext[this.options.style]} Create content optimized for slides with 3-5 bullet points per slide. Each point should be concise yet meaningful. Write in ${this.options.language} language.`;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
// ============================================================================
|
|
632
|
-
// Argument Parsing
|
|
633
|
-
// ============================================================================
|
|
634
|
-
|
|
635
|
-
function showHelp(): void {
|
|
636
|
-
console.log(`
|
|
637
|
-
generate-presentation - Create professional slide deck presentations using AI
|
|
638
|
-
|
|
639
|
-
Usage:
|
|
640
|
-
skills run generate-presentation -- "<topic or content>" [options]
|
|
641
|
-
skills run generate-presentation -- ./content.md [options]
|
|
642
|
-
|
|
643
|
-
Options:
|
|
644
|
-
-h, --help Show this help message
|
|
645
|
-
--slides <number> Number of slides (5-30, default: 10)
|
|
646
|
-
--style <type> Presentation style:
|
|
647
|
-
business | educational | pitch-deck | technical | minimal
|
|
648
|
-
--format <type> Output format: markdown | html | pdf (default: markdown)
|
|
649
|
-
--include-notes Include speaker notes
|
|
650
|
-
--template <type> Theme: default | modern | dark | minimal | corporate
|
|
651
|
-
--ai-provider <type> AI provider: openai | anthropic (default: openai)
|
|
652
|
-
--language <code> Language code (e.g., en, es, fr)
|
|
653
|
-
--output <path> Output directory
|
|
654
|
-
|
|
655
|
-
Examples:
|
|
656
|
-
skills run generate-presentation -- "Introduction to Machine Learning"
|
|
657
|
-
skills run generate-presentation -- "Company Q4 Review" --style business --slides 15
|
|
658
|
-
skills run generate-presentation -- ./outline.md --format pdf --template dark
|
|
659
|
-
|
|
660
|
-
Requirements:
|
|
661
|
-
Set OPENAI_API_KEY or ANTHROPIC_API_KEY environment variable.
|
|
662
|
-
`);
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
function parseArguments(): SkillOptions {
|
|
666
|
-
const { values, positionals } = parseArgs({
|
|
667
|
-
args: process.argv.slice(2),
|
|
668
|
-
options: {
|
|
669
|
-
help: { type: "boolean", short: "h" },
|
|
670
|
-
slides: { type: "string", default: "10" },
|
|
671
|
-
style: { type: "string", default: "business" },
|
|
672
|
-
format: { type: "string", default: "markdown" },
|
|
673
|
-
"include-notes": { type: "string", default: "false" },
|
|
674
|
-
template: { type: "string", default: "default" },
|
|
675
|
-
"ai-provider": { type: "string", default: "openai" },
|
|
676
|
-
output: { type: "string", default: join(SKILLS_OUTPUT_DIR, "exports", "generate-presentation") },
|
|
677
|
-
language: { type: "string", default: "en" },
|
|
678
|
-
},
|
|
679
|
-
allowPositionals: true,
|
|
680
|
-
});
|
|
681
|
-
|
|
682
|
-
if (values.help) {
|
|
683
|
-
showHelp();
|
|
684
|
-
process.exit(0);
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
const input = positionals[0];
|
|
688
|
-
if (!input) {
|
|
689
|
-
throw new Error("Input is required. Usage: skills run generate-presentation -- \"Your Topic\" or ./file.md");
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// Check if input is a file path
|
|
693
|
-
let isFile = false;
|
|
694
|
-
try {
|
|
695
|
-
// Simple heuristic: if it has a path separator or file extension, treat as file
|
|
696
|
-
isFile = input.includes("/") || input.includes("\\") || input.includes(".");
|
|
697
|
-
} catch (error) {
|
|
698
|
-
isFile = false;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
const slides = parseInt(values.slides as string, 10);
|
|
702
|
-
if (isNaN(slides) || slides < 5 || slides > 30) {
|
|
703
|
-
throw new Error("Slides must be between 5 and 30");
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
const style = values.style as string;
|
|
707
|
-
if (!["business", "educational", "pitch-deck", "technical", "minimal"].includes(style)) {
|
|
708
|
-
throw new Error("Style must be: business, educational, pitch-deck, technical, or minimal");
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
const format = values.format as string;
|
|
712
|
-
if (!["markdown", "html", "pdf"].includes(format)) {
|
|
713
|
-
throw new Error("Format must be: markdown, html, or pdf");
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
const template = values.template as string;
|
|
717
|
-
if (!["default", "modern", "dark", "minimal", "corporate"].includes(template)) {
|
|
718
|
-
throw new Error("Template must be: default, modern, dark, minimal, or corporate");
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const aiProvider = values["ai-provider"] as string;
|
|
722
|
-
if (!["openai", "anthropic"].includes(aiProvider)) {
|
|
723
|
-
throw new Error("AI provider must be: openai or anthropic");
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
return {
|
|
727
|
-
input,
|
|
728
|
-
isFile,
|
|
729
|
-
slides,
|
|
730
|
-
style: style as any,
|
|
731
|
-
format: format as any,
|
|
732
|
-
includeNotes: values["include-notes"] === "true",
|
|
733
|
-
template: template as any,
|
|
734
|
-
aiProvider: aiProvider as any,
|
|
735
|
-
output: values.output as string,
|
|
736
|
-
language: values.language as string,
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
// ============================================================================
|
|
741
|
-
// Validation
|
|
742
|
-
// ============================================================================
|
|
743
|
-
|
|
744
|
-
function validateEnvironment(options: SkillOptions): void {
|
|
745
|
-
if (options.aiProvider === "openai" && !OPENAI_API_KEY) {
|
|
746
|
-
throw new Error("OPENAI_API_KEY environment variable is required for OpenAI provider");
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (options.aiProvider === "anthropic" && !ANTHROPIC_API_KEY) {
|
|
750
|
-
throw new Error("ANTHROPIC_API_KEY environment variable is required for Anthropic provider");
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
// ============================================================================
|
|
755
|
-
// Main Execution
|
|
756
|
-
// ============================================================================
|
|
10
|
+
import { parseArguments, validateEnvironment } from "./cli";
|
|
11
|
+
import { Logger } from "./logger";
|
|
12
|
+
import { PresentationGenerator } from "./presentation-generator";
|
|
757
13
|
|
|
758
14
|
async function main() {
|
|
759
15
|
const logger = new Logger();
|
|
@@ -761,13 +17,9 @@ async function main() {
|
|
|
761
17
|
try {
|
|
762
18
|
console.log("🎨 Generate Presentation - Starting...\n");
|
|
763
19
|
|
|
764
|
-
// Parse arguments
|
|
765
20
|
const options = parseArguments();
|
|
766
|
-
|
|
767
|
-
// Validate environment
|
|
768
21
|
validateEnvironment(options);
|
|
769
22
|
|
|
770
|
-
// Generate presentation
|
|
771
23
|
const generator = new PresentationGenerator(options, logger);
|
|
772
24
|
await generator.generate();
|
|
773
25
|
|