@hasna/skills 0.1.27 → 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 +30121 -27576
- package/bin/mcp.js +22073 -18556
- 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 +11606 -598
- 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 +22 -11
- 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/exports/products-2025-12-14T13-50-53-041Z.csv +16 -0
- package/skills/consolelog/exports/products-2025-12-14T13-50-53-041Z.json +227 -0
- 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/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
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Audio Chunker
|
|
3
|
-
* Splits large audio files into smaller chunks for transcription
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { spawn } from 'child_process';
|
|
7
|
-
import { mkdir, rm, stat, readdir } from 'fs/promises';
|
|
8
|
-
import { join, basename, extname } from 'path';
|
|
9
|
-
import type { ChunkInfo } from './types';
|
|
10
|
-
|
|
11
|
-
// Default chunk duration in seconds (10 minutes)
|
|
12
|
-
const DEFAULT_CHUNK_DURATION = 600;
|
|
13
|
-
// Overlap in seconds to prevent word cutoff
|
|
14
|
-
const CHUNK_OVERLAP = 10;
|
|
15
|
-
|
|
16
|
-
export async function getAudioDuration(filePath: string): Promise<number> {
|
|
17
|
-
return new Promise((resolve, reject) => {
|
|
18
|
-
const ffprobe = spawn('ffprobe', [
|
|
19
|
-
'-v', 'error',
|
|
20
|
-
'-show_entries', 'format=duration',
|
|
21
|
-
'-of', 'default=noprint_wrappers=1:nokey=1',
|
|
22
|
-
filePath
|
|
23
|
-
]);
|
|
24
|
-
|
|
25
|
-
let output = '';
|
|
26
|
-
let error = '';
|
|
27
|
-
|
|
28
|
-
ffprobe.stdout.on('data', (data) => {
|
|
29
|
-
output += data.toString();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
ffprobe.stderr.on('data', (data) => {
|
|
33
|
-
error += data.toString();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
ffprobe.on('close', (code) => {
|
|
37
|
-
if (code !== 0) {
|
|
38
|
-
reject(new Error(`ffprobe failed: ${error}`));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const duration = parseFloat(output.trim());
|
|
42
|
-
if (isNaN(duration)) {
|
|
43
|
-
reject(new Error('Could not parse audio duration'));
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
resolve(duration);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function getFileSize(filePath: string): Promise<number> {
|
|
52
|
-
const stats = await stat(filePath);
|
|
53
|
-
return stats.size;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export async function needsChunking(filePath: string, maxSize: number): Promise<boolean> {
|
|
57
|
-
const size = await getFileSize(filePath);
|
|
58
|
-
return size > maxSize;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function splitAudioFile(
|
|
62
|
-
inputPath: string,
|
|
63
|
-
outputDir: string,
|
|
64
|
-
chunkDuration: number = DEFAULT_CHUNK_DURATION
|
|
65
|
-
): Promise<ChunkInfo[]> {
|
|
66
|
-
console.log(`[Chunker] Splitting audio file: ${inputPath}`);
|
|
67
|
-
|
|
68
|
-
// Create output directory
|
|
69
|
-
const chunkDir = join(outputDir, '.chunks');
|
|
70
|
-
await mkdir(chunkDir, { recursive: true });
|
|
71
|
-
|
|
72
|
-
const duration = await getAudioDuration(inputPath);
|
|
73
|
-
const baseName = basename(inputPath, extname(inputPath));
|
|
74
|
-
const ext = extname(inputPath) || '.mp3';
|
|
75
|
-
|
|
76
|
-
console.log(`[Chunker] Total duration: ${Math.round(duration)}s`);
|
|
77
|
-
console.log(`[Chunker] Chunk duration: ${chunkDuration}s with ${CHUNK_OVERLAP}s overlap`);
|
|
78
|
-
|
|
79
|
-
const chunks: ChunkInfo[] = [];
|
|
80
|
-
let startTime = 0;
|
|
81
|
-
let chunkIndex = 0;
|
|
82
|
-
|
|
83
|
-
while (startTime < duration) {
|
|
84
|
-
const chunkPath = join(chunkDir, `${baseName}_chunk_${String(chunkIndex).padStart(3, '0')}${ext}`);
|
|
85
|
-
const endTime = Math.min(startTime + chunkDuration, duration);
|
|
86
|
-
|
|
87
|
-
await createChunk(inputPath, chunkPath, startTime, chunkDuration + CHUNK_OVERLAP);
|
|
88
|
-
|
|
89
|
-
const chunkSize = await getFileSize(chunkPath);
|
|
90
|
-
|
|
91
|
-
chunks.push({
|
|
92
|
-
index: chunkIndex,
|
|
93
|
-
startTime,
|
|
94
|
-
endTime,
|
|
95
|
-
path: chunkPath,
|
|
96
|
-
size: chunkSize
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
console.log(`[Chunker] Created chunk ${chunkIndex + 1}: ${Math.round(startTime)}s - ${Math.round(endTime)}s (${(chunkSize / 1024 / 1024).toFixed(2)}MB)`);
|
|
100
|
-
|
|
101
|
-
startTime += chunkDuration;
|
|
102
|
-
chunkIndex++;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
console.log(`[Chunker] Created ${chunks.length} chunks`);
|
|
106
|
-
return chunks;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function createChunk(
|
|
110
|
-
inputPath: string,
|
|
111
|
-
outputPath: string,
|
|
112
|
-
startTime: number,
|
|
113
|
-
duration: number
|
|
114
|
-
): Promise<void> {
|
|
115
|
-
return new Promise((resolve, reject) => {
|
|
116
|
-
const ffmpeg = spawn('ffmpeg', [
|
|
117
|
-
'-y',
|
|
118
|
-
'-i', inputPath,
|
|
119
|
-
'-ss', startTime.toString(),
|
|
120
|
-
'-t', duration.toString(),
|
|
121
|
-
'-acodec', 'copy',
|
|
122
|
-
outputPath
|
|
123
|
-
]);
|
|
124
|
-
|
|
125
|
-
let error = '';
|
|
126
|
-
|
|
127
|
-
ffmpeg.stderr.on('data', (data) => {
|
|
128
|
-
error += data.toString();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
ffmpeg.on('close', (code) => {
|
|
132
|
-
if (code !== 0) {
|
|
133
|
-
reject(new Error(`ffmpeg chunk creation failed: ${error}`));
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
resolve();
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export async function compressAudio(
|
|
142
|
-
inputPath: string,
|
|
143
|
-
outputPath: string,
|
|
144
|
-
targetBitrate: string = '32k'
|
|
145
|
-
): Promise<string> {
|
|
146
|
-
console.log(`[Chunker] Compressing audio: ${inputPath}`);
|
|
147
|
-
console.log(`[Chunker] Target bitrate: ${targetBitrate}`);
|
|
148
|
-
|
|
149
|
-
return new Promise((resolve, reject) => {
|
|
150
|
-
const ffmpeg = spawn('ffmpeg', [
|
|
151
|
-
'-y',
|
|
152
|
-
'-i', inputPath,
|
|
153
|
-
'-vn', // No video
|
|
154
|
-
'-map_metadata', '-1', // Remove metadata
|
|
155
|
-
'-ac', '1', // Mono
|
|
156
|
-
'-c:a', 'libopus', // Opus codec (best compression for voice)
|
|
157
|
-
'-b:a', targetBitrate, // Target bitrate
|
|
158
|
-
'-application', 'voip', // Optimized for voice
|
|
159
|
-
outputPath
|
|
160
|
-
]);
|
|
161
|
-
|
|
162
|
-
let error = '';
|
|
163
|
-
|
|
164
|
-
ffmpeg.stderr.on('data', (data) => {
|
|
165
|
-
error += data.toString();
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
ffmpeg.on('close', async (code) => {
|
|
169
|
-
if (code !== 0) {
|
|
170
|
-
reject(new Error(`ffmpeg compression failed: ${error}`));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const newSize = await getFileSize(outputPath);
|
|
174
|
-
console.log(`[Chunker] Compressed size: ${(newSize / 1024 / 1024).toFixed(2)}MB`);
|
|
175
|
-
resolve(outputPath);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export async function cleanupChunks(chunkDir: string): Promise<void> {
|
|
181
|
-
try {
|
|
182
|
-
await rm(chunkDir, { recursive: true, force: true });
|
|
183
|
-
console.log('[Chunker] Cleaned up temporary chunks');
|
|
184
|
-
} catch {
|
|
185
|
-
// Ignore cleanup errors
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function mergeTranscriptions(
|
|
190
|
-
transcriptions: string[],
|
|
191
|
-
chunkDuration: number = DEFAULT_CHUNK_DURATION,
|
|
192
|
-
overlap: number = CHUNK_OVERLAP
|
|
193
|
-
): string {
|
|
194
|
-
if (transcriptions.length === 0) return '';
|
|
195
|
-
if (transcriptions.length === 1) return transcriptions[0];
|
|
196
|
-
|
|
197
|
-
// Simple merge strategy: trim overlap from the beginning of each chunk except the first
|
|
198
|
-
// This is a basic approach; more sophisticated overlap detection could be added
|
|
199
|
-
const merged: string[] = [transcriptions[0]];
|
|
200
|
-
|
|
201
|
-
for (let i = 1; i < transcriptions.length; i++) {
|
|
202
|
-
const text = transcriptions[i];
|
|
203
|
-
// Remove potential duplicate sentences at the beginning
|
|
204
|
-
// This is a heuristic approach
|
|
205
|
-
const sentences = text.split(/(?<=[.!?])\s+/);
|
|
206
|
-
if (sentences.length > 1) {
|
|
207
|
-
// Skip first sentence as it likely overlaps with previous chunk
|
|
208
|
-
merged.push(sentences.slice(1).join(' '));
|
|
209
|
-
} else {
|
|
210
|
-
merged.push(text);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return merged.join('\n\n');
|
|
215
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Output Formatter
|
|
3
|
-
* Converts transcription results to various output formats
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { TranscriptionResult, TranscriptionSegment } from './types';
|
|
7
|
-
|
|
8
|
-
export type OutputFormat = 'text' | 'srt' | 'vtt' | 'json';
|
|
9
|
-
|
|
10
|
-
export function formatOutput(result: TranscriptionResult, format: OutputFormat): string {
|
|
11
|
-
switch (format) {
|
|
12
|
-
case 'text':
|
|
13
|
-
return formatText(result);
|
|
14
|
-
case 'srt':
|
|
15
|
-
return formatSRT(result);
|
|
16
|
-
case 'vtt':
|
|
17
|
-
return formatVTT(result);
|
|
18
|
-
case 'json':
|
|
19
|
-
return formatJSON(result);
|
|
20
|
-
default:
|
|
21
|
-
return formatText(result);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function formatText(result: TranscriptionResult): string {
|
|
26
|
-
if (!result.segments || result.segments.length === 0) {
|
|
27
|
-
return result.text;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Format with speaker labels if available
|
|
31
|
-
let output = '';
|
|
32
|
-
let currentSpeaker = '';
|
|
33
|
-
|
|
34
|
-
for (const segment of result.segments) {
|
|
35
|
-
if (segment.speaker && segment.speaker !== currentSpeaker) {
|
|
36
|
-
currentSpeaker = segment.speaker;
|
|
37
|
-
output += `\n[${currentSpeaker}]\n`;
|
|
38
|
-
}
|
|
39
|
-
output += segment.text + ' ';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return output.trim();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function formatSRT(result: TranscriptionResult): string {
|
|
46
|
-
if (!result.segments || result.segments.length === 0) {
|
|
47
|
-
// Create a single segment if no segments available
|
|
48
|
-
return `1\n00:00:00,000 --> 00:00:00,000\n${result.text}\n`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let srt = '';
|
|
52
|
-
|
|
53
|
-
for (let i = 0; i < result.segments.length; i++) {
|
|
54
|
-
const segment = result.segments[i];
|
|
55
|
-
const startTime = formatTimestamp(segment.start, 'srt');
|
|
56
|
-
const endTime = formatTimestamp(segment.end, 'srt');
|
|
57
|
-
|
|
58
|
-
srt += `${i + 1}\n`;
|
|
59
|
-
srt += `${startTime} --> ${endTime}\n`;
|
|
60
|
-
|
|
61
|
-
if (segment.speaker) {
|
|
62
|
-
srt += `<v ${segment.speaker}>${segment.text}\n`;
|
|
63
|
-
} else {
|
|
64
|
-
srt += `${segment.text}\n`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
srt += '\n';
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return srt.trim();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function formatVTT(result: TranscriptionResult): string {
|
|
74
|
-
let vtt = 'WEBVTT\n\n';
|
|
75
|
-
|
|
76
|
-
if (!result.segments || result.segments.length === 0) {
|
|
77
|
-
vtt += `00:00:00.000 --> 00:00:00.000\n${result.text}\n`;
|
|
78
|
-
return vtt;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
for (const segment of result.segments) {
|
|
82
|
-
const startTime = formatTimestamp(segment.start, 'vtt');
|
|
83
|
-
const endTime = formatTimestamp(segment.end, 'vtt');
|
|
84
|
-
|
|
85
|
-
vtt += `${startTime} --> ${endTime}\n`;
|
|
86
|
-
|
|
87
|
-
if (segment.speaker) {
|
|
88
|
-
vtt += `<v ${segment.speaker}>${segment.text}\n`;
|
|
89
|
-
} else {
|
|
90
|
-
vtt += `${segment.text}\n`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
vtt += '\n';
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return vtt.trim();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function formatJSON(result: TranscriptionResult): string {
|
|
100
|
-
return JSON.stringify(result, null, 2);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function formatTimestamp(seconds: number, format: 'srt' | 'vtt'): string {
|
|
104
|
-
const hours = Math.floor(seconds / 3600);
|
|
105
|
-
const minutes = Math.floor((seconds % 3600) / 60);
|
|
106
|
-
const secs = Math.floor(seconds % 60);
|
|
107
|
-
const ms = Math.round((seconds % 1) * 1000);
|
|
108
|
-
|
|
109
|
-
const hh = String(hours).padStart(2, '0');
|
|
110
|
-
const mm = String(minutes).padStart(2, '0');
|
|
111
|
-
const ss = String(secs).padStart(2, '0');
|
|
112
|
-
const mmm = String(ms).padStart(3, '0');
|
|
113
|
-
|
|
114
|
-
if (format === 'srt') {
|
|
115
|
-
return `${hh}:${mm}:${ss},${mmm}`;
|
|
116
|
-
} else {
|
|
117
|
-
return `${hh}:${mm}:${ss}.${mmm}`;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function getOutputExtension(format: OutputFormat): string {
|
|
122
|
-
switch (format) {
|
|
123
|
-
case 'text':
|
|
124
|
-
return '.txt';
|
|
125
|
-
case 'srt':
|
|
126
|
-
return '.srt';
|
|
127
|
-
case 'vtt':
|
|
128
|
-
return '.vtt';
|
|
129
|
-
case 'json':
|
|
130
|
-
return '.json';
|
|
131
|
-
default:
|
|
132
|
-
return '.txt';
|
|
133
|
-
}
|
|
134
|
-
}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Transcription CLI
|
|
5
|
-
* Speech-to-text using ElevenLabs, OpenAI Whisper, or Google Gemini
|
|
6
|
-
* Supports automatic chunking for large files
|
|
7
|
-
*/
|
|
8
|
-
import { handleInstallCommand } from '../../_common';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Handle install/uninstall commands
|
|
12
|
-
const SKILL_META = {
|
|
13
|
-
name: 'transcript',
|
|
14
|
-
description: 'Audio/video transcription skill supporting ElevenLabs, OpenAI Whisper, and Google Gemini with automatic chunking for large files',
|
|
15
|
-
version: '1.0.0',
|
|
16
|
-
commands: `Use: transcript --help`,
|
|
17
|
-
requiredEnvVars: ['SKILL_API_KEY'],
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
import { getProvider, getProviderInfo } from './providers';
|
|
25
|
-
import { formatOutput, getOutputExtension } from './formatter';
|
|
26
|
-
import type { Provider, TranscriptionOptions } from './types';
|
|
27
|
-
import type { OutputFormat } from './formatter';
|
|
28
|
-
import { basename, extname, dirname, join } from 'path';
|
|
29
|
-
|
|
30
|
-
// Parse command line arguments
|
|
31
|
-
function parseArgs(): {
|
|
32
|
-
command: string;
|
|
33
|
-
input?: string;
|
|
34
|
-
output?: string;
|
|
35
|
-
provider?: Provider;
|
|
36
|
-
language?: string;
|
|
37
|
-
model?: string;
|
|
38
|
-
diarize?: boolean;
|
|
39
|
-
timestamps?: boolean;
|
|
40
|
-
format?: OutputFormat;
|
|
41
|
-
} {
|
|
42
|
-
const args = process.argv.slice(2);
|
|
43
|
-
const parsed: any = { command: args[0] || 'help' };
|
|
44
|
-
|
|
45
|
-
for (let i = 1; i < args.length; i++) {
|
|
46
|
-
const arg = args[i];
|
|
47
|
-
if (arg.startsWith('--')) {
|
|
48
|
-
const key = arg.replace(/^--/, '');
|
|
49
|
-
|
|
50
|
-
if (key === 'diarize' || key === 'timestamps') {
|
|
51
|
-
parsed[key] = true;
|
|
52
|
-
} else {
|
|
53
|
-
parsed[key] = args[++i];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return parsed;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Display help information
|
|
62
|
-
function showHelp(): void {
|
|
63
|
-
console.log(`
|
|
64
|
-
Transcription CLI - Speech-to-text with automatic chunking
|
|
65
|
-
|
|
66
|
-
USAGE:
|
|
67
|
-
bun run src/index.ts <command> [options]
|
|
68
|
-
|
|
69
|
-
COMMANDS:
|
|
70
|
-
transcribe Transcribe an audio/video file
|
|
71
|
-
providers Show available providers and their capabilities
|
|
72
|
-
help Show this help message
|
|
73
|
-
|
|
74
|
-
TRANSCRIBE OPTIONS:
|
|
75
|
-
--input <path> Input audio/video file (required)
|
|
76
|
-
--output <path> Output file path (optional, defaults to input name + format extension)
|
|
77
|
-
--provider <name> Provider: elevenlabs, openai, gemini (required)
|
|
78
|
-
--language <code> Language code, e.g., en, es, fr (optional)
|
|
79
|
-
--model <name> Specific model to use (optional)
|
|
80
|
-
--diarize Enable speaker diarization (ElevenLabs, Gemini)
|
|
81
|
-
--timestamps Include timestamps in output
|
|
82
|
-
--format <type> Output format: text, srt, vtt, json (default: text)
|
|
83
|
-
|
|
84
|
-
SUPPORTED FORMATS:
|
|
85
|
-
Audio: mp3, wav, m4a, ogg, flac, aac, webm
|
|
86
|
-
Video: mp4, webm
|
|
87
|
-
|
|
88
|
-
EXAMPLES:
|
|
89
|
-
# Basic transcription with OpenAI Whisper
|
|
90
|
-
bun run src/index.ts transcribe \\
|
|
91
|
-
--provider openai \\
|
|
92
|
-
--input ./recording.mp3 \\
|
|
93
|
-
--output ./transcript.txt
|
|
94
|
-
|
|
95
|
-
# Transcription with speaker diarization (ElevenLabs)
|
|
96
|
-
bun run src/index.ts transcribe \\
|
|
97
|
-
--provider elevenlabs \\
|
|
98
|
-
--input ./meeting.mp3 \\
|
|
99
|
-
--diarize \\
|
|
100
|
-
--timestamps \\
|
|
101
|
-
--format srt
|
|
102
|
-
|
|
103
|
-
# Cost-effective transcription (Gemini)
|
|
104
|
-
bun run src/index.ts transcribe \\
|
|
105
|
-
--provider gemini \\
|
|
106
|
-
--input ./podcast.mp3 \\
|
|
107
|
-
--format vtt
|
|
108
|
-
|
|
109
|
-
# Transcribe with specific language
|
|
110
|
-
bun run src/index.ts transcribe \\
|
|
111
|
-
--provider openai \\
|
|
112
|
-
--input ./spanish.mp3 \\
|
|
113
|
-
--language es \\
|
|
114
|
-
--format json
|
|
115
|
-
|
|
116
|
-
LARGE FILE HANDLING:
|
|
117
|
-
- ElevenLabs: Up to 3GB (native support)
|
|
118
|
-
- Gemini: Up to 2GB (auto-chunking for efficiency)
|
|
119
|
-
- OpenAI: 25MB limit (automatic compression/chunking for larger files)
|
|
120
|
-
|
|
121
|
-
ENVIRONMENT VARIABLES:
|
|
122
|
-
ELEVENLABS_API_KEY API key for ElevenLabs Scribe
|
|
123
|
-
OPENAI_API_KEY API key for OpenAI Whisper
|
|
124
|
-
GOOGLE_API_KEY API key for Google Gemini
|
|
125
|
-
|
|
126
|
-
DEPENDENCIES:
|
|
127
|
-
- ffmpeg (required for chunking large files with OpenAI)
|
|
128
|
-
- ffprobe (required for audio duration detection)
|
|
129
|
-
`);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Main CLI handler
|
|
133
|
-
async function main(): Promise<void> {
|
|
134
|
-
const args = parseArgs();
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
switch (args.command) {
|
|
138
|
-
case 'transcribe': {
|
|
139
|
-
if (!args.input) {
|
|
140
|
-
console.error('Error: --input is required');
|
|
141
|
-
console.error('Use: bun run src/index.ts help');
|
|
142
|
-
process.exit(1);
|
|
143
|
-
}
|
|
144
|
-
if (!args.provider) {
|
|
145
|
-
console.error('Error: --provider is required');
|
|
146
|
-
console.error('Available providers: elevenlabs, openai, gemini');
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const provider = getProvider(args.provider as Provider);
|
|
151
|
-
console.log(`\nUsing ${provider.name}`);
|
|
152
|
-
console.log(`Max file size: ${(provider.maxFileSize / 1024 / 1024 / 1024).toFixed(1)}GB`);
|
|
153
|
-
console.log('');
|
|
154
|
-
|
|
155
|
-
const options: TranscriptionOptions = {
|
|
156
|
-
input: args.input,
|
|
157
|
-
output: args.output,
|
|
158
|
-
provider: args.provider as Provider,
|
|
159
|
-
language: args.language,
|
|
160
|
-
model: args.model,
|
|
161
|
-
diarize: args.diarize,
|
|
162
|
-
timestamps: args.timestamps,
|
|
163
|
-
format: (args.format as OutputFormat) || 'text'
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const result = await provider.transcribe(options);
|
|
167
|
-
|
|
168
|
-
// Format output
|
|
169
|
-
const format = (args.format as OutputFormat) || 'text';
|
|
170
|
-
const formattedOutput = formatOutput(result, format);
|
|
171
|
-
|
|
172
|
-
// Determine output path
|
|
173
|
-
let outputPath = args.output;
|
|
174
|
-
if (!outputPath) {
|
|
175
|
-
const inputDir = dirname(args.input);
|
|
176
|
-
const inputName = basename(args.input, extname(args.input));
|
|
177
|
-
outputPath = join(inputDir, `${inputName}${getOutputExtension(format)}`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Write output
|
|
181
|
-
await Bun.write(outputPath, formattedOutput);
|
|
182
|
-
|
|
183
|
-
console.log(`\nTranscription complete!`);
|
|
184
|
-
console.log(`Output: ${outputPath}`);
|
|
185
|
-
console.log(`Format: ${format}`);
|
|
186
|
-
|
|
187
|
-
if (result.duration) {
|
|
188
|
-
console.log(`Duration: ${Math.round(result.duration)}s`);
|
|
189
|
-
}
|
|
190
|
-
if (result.language) {
|
|
191
|
-
console.log(`Detected language: ${result.language}`);
|
|
192
|
-
}
|
|
193
|
-
if (result.segments) {
|
|
194
|
-
console.log(`Segments: ${result.segments.length}`);
|
|
195
|
-
}
|
|
196
|
-
if (result.speakers) {
|
|
197
|
-
console.log(`Speakers: ${result.speakers.length}`);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Show word count
|
|
201
|
-
const wordCount = result.text.split(/\s+/).length;
|
|
202
|
-
console.log(`Words: ${wordCount.toLocaleString()}`);
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
case 'providers':
|
|
207
|
-
getProviderInfo();
|
|
208
|
-
break;
|
|
209
|
-
|
|
210
|
-
case 'help':
|
|
211
|
-
showHelp();
|
|
212
|
-
break;
|
|
213
|
-
|
|
214
|
-
default:
|
|
215
|
-
console.error(`Unknown command: ${args.command}`);
|
|
216
|
-
console.error('Use: bun run src/index.ts help');
|
|
217
|
-
process.exit(1);
|
|
218
|
-
}
|
|
219
|
-
} catch (error) {
|
|
220
|
-
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
221
|
-
process.exit(1);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Run the CLI
|
|
226
|
-
main();
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Skill Transcript (HTTP Client)
|
|
5
|
-
* Calls the remote skill API server
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { executeAndSave, executeSkill, handleInstallCommand } from '../../_common';
|
|
9
|
-
|
|
10
|
-
// Skill metadata for install command
|
|
11
|
-
const SKILL_META = {
|
|
12
|
-
name: 'transcript',
|
|
13
|
-
description: 'Transcript skill - calls remote API',
|
|
14
|
-
version: '1.0.0',
|
|
15
|
-
commands: `transcript <command> [options]`,
|
|
16
|
-
requiredEnvVars: ['SKILL_API_KEY'],
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// Handle install/uninstall commands
|
|
20
|
-
if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Parse command line arguments
|
|
25
|
-
function parseArgs(): Record<string, string | boolean> {
|
|
26
|
-
const args = process.argv.slice(2);
|
|
27
|
-
const parsed: Record<string, string | boolean> = {};
|
|
28
|
-
|
|
29
|
-
for (let i = 0; i < args.length; i++) {
|
|
30
|
-
if (args[i].startsWith('--')) {
|
|
31
|
-
const key = args[i].slice(2);
|
|
32
|
-
const value = args[i + 1];
|
|
33
|
-
if (value && !value.startsWith('--')) {
|
|
34
|
-
parsed[key] = value;
|
|
35
|
-
i++;
|
|
36
|
-
} else {
|
|
37
|
-
parsed[key] = true;
|
|
38
|
-
}
|
|
39
|
-
} else if (!parsed.command) {
|
|
40
|
-
parsed.command = args[i];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return parsed;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Main logic
|
|
48
|
-
async function main() {
|
|
49
|
-
const args = parseArgs();
|
|
50
|
-
const command = (args.command as string) || 'help';
|
|
51
|
-
|
|
52
|
-
if (command === 'help' || args.help) {
|
|
53
|
-
console.log(`Skill Transcript CLI
|
|
54
|
-
|
|
55
|
-
USAGE:
|
|
56
|
-
transcript <command> [options]
|
|
57
|
-
|
|
58
|
-
COMMANDS:
|
|
59
|
-
Call with any command and it will be forwarded to the remote API server
|
|
60
|
-
|
|
61
|
-
EXAMPLES:
|
|
62
|
-
transcript generate --provider <provider> [options]`);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Extract all parameters
|
|
67
|
-
const { command: cmd, ...params } = args;
|
|
68
|
-
|
|
69
|
-
// Check if output file is expected (for file-generating skills)
|
|
70
|
-
const fileSkills = ['audio', 'image', 'video', 'emoji'];
|
|
71
|
-
const isFileSkill = fileSkills.includes('transcript');
|
|
72
|
-
|
|
73
|
-
if (isFileSkill && params.output) {
|
|
74
|
-
// Skill that generates files
|
|
75
|
-
const success = await executeAndSave({
|
|
76
|
-
skill: 'transcript',
|
|
77
|
-
command: cmd,
|
|
78
|
-
...params,
|
|
79
|
-
});
|
|
80
|
-
process.exit(success ? 0 : 1);
|
|
81
|
-
} else {
|
|
82
|
-
// Skill that returns JSON/text
|
|
83
|
-
const result = await executeSkill({
|
|
84
|
-
skill: 'transcript',
|
|
85
|
-
command: cmd,
|
|
86
|
-
...params,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if (result instanceof Blob) {
|
|
90
|
-
console.error('❌ Unexpected binary response');
|
|
91
|
-
process.exit(1);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (result.success && result.output) {
|
|
95
|
-
console.log(result.output);
|
|
96
|
-
} else {
|
|
97
|
-
console.error(`❌ Error: ${result.error}`);
|
|
98
|
-
if (result.details) {
|
|
99
|
-
console.error(` ${result.details}`);
|
|
100
|
-
}
|
|
101
|
-
process.exit(1);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Run main
|
|
107
|
-
main().catch((error) => {
|
|
108
|
-
console.error('❌ Fatal error:', error.message);
|
|
109
|
-
process.exit(1);
|
|
110
|
-
});
|