@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
|
@@ -6,532 +6,29 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { parseArgs } from "util";
|
|
9
|
-
import { existsSync, mkdirSync, appendFileSync } from "fs";
|
|
10
|
-
import { join } from "path";
|
|
11
|
-
import { randomUUID } from "crypto";
|
|
12
|
-
|
|
13
|
-
// Google Calendar API base URL
|
|
14
|
-
const CALENDAR_API_BASE = "https://www.googleapis.com/calendar/v3";
|
|
15
|
-
|
|
16
|
-
// Request timeout in milliseconds (30 seconds)
|
|
17
|
-
const REQUEST_TIMEOUT_MS = 30000;
|
|
18
|
-
|
|
19
|
-
// Constants
|
|
20
|
-
const SKILL_NAME = "calendar-events";
|
|
21
|
-
const SESSION_ID = randomUUID().slice(0, 8);
|
|
22
|
-
const SKILLS_OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || join(process.cwd(), ".skills");
|
|
23
|
-
const LOGS_DIR = join(SKILLS_OUTPUT_DIR, "logs", SKILL_NAME);
|
|
24
|
-
const SESSION_TIMESTAMP = new Date().toISOString().replace(/[:.]/g, "_").slice(0, 19);
|
|
25
|
-
|
|
26
|
-
// Ensure directories exist
|
|
27
|
-
function ensureDir(dir: string) {
|
|
28
|
-
if (!existsSync(dir)) {
|
|
29
|
-
mkdirSync(dir, { recursive: true });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Logger
|
|
34
|
-
function log(message: string, level: "info" | "error" | "success" | "debug" = "info") {
|
|
35
|
-
ensureDir(LOGS_DIR);
|
|
36
|
-
const timestamp = new Date().toISOString();
|
|
37
|
-
const logFile = join(LOGS_DIR, `log_${SESSION_TIMESTAMP}_${SESSION_ID}.log`);
|
|
38
|
-
const logEntry = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
|
|
39
|
-
appendFileSync(logFile, logEntry);
|
|
40
|
-
|
|
41
|
-
const prefix = level === "error" ? "❌" : level === "success" ? "✅" : level === "debug" ? "🔍" : "ℹ️";
|
|
42
|
-
if (level === "error") {
|
|
43
|
-
console.error(`${prefix} ${message}`);
|
|
44
|
-
} else if (level !== "debug") {
|
|
45
|
-
console.log(`${prefix} ${message}`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Types
|
|
50
|
-
interface CalendarEvent {
|
|
51
|
-
id: string;
|
|
52
|
-
summary?: string;
|
|
53
|
-
description?: string;
|
|
54
|
-
location?: string;
|
|
55
|
-
start: {
|
|
56
|
-
dateTime?: string;
|
|
57
|
-
date?: string;
|
|
58
|
-
timeZone?: string;
|
|
59
|
-
};
|
|
60
|
-
end: {
|
|
61
|
-
dateTime?: string;
|
|
62
|
-
date?: string;
|
|
63
|
-
timeZone?: string;
|
|
64
|
-
};
|
|
65
|
-
attendees?: Array<{
|
|
66
|
-
email: string;
|
|
67
|
-
displayName?: string;
|
|
68
|
-
responseStatus?: string;
|
|
69
|
-
}>;
|
|
70
|
-
htmlLink?: string;
|
|
71
|
-
status?: string;
|
|
72
|
-
created?: string;
|
|
73
|
-
updated?: string;
|
|
74
|
-
organizer?: {
|
|
75
|
-
email: string;
|
|
76
|
-
displayName?: string;
|
|
77
|
-
};
|
|
78
|
-
reminders?: {
|
|
79
|
-
useDefault: boolean;
|
|
80
|
-
overrides?: Array<{
|
|
81
|
-
method: string;
|
|
82
|
-
minutes: number;
|
|
83
|
-
}>;
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
interface Calendar {
|
|
88
|
-
id: string;
|
|
89
|
-
summary: string;
|
|
90
|
-
description?: string;
|
|
91
|
-
primary?: boolean;
|
|
92
|
-
backgroundColor?: string;
|
|
93
|
-
accessRole?: string;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
interface EventsListResponse {
|
|
97
|
-
items?: CalendarEvent[];
|
|
98
|
-
nextPageToken?: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
interface CalendarListResponse {
|
|
102
|
-
items?: Calendar[];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Parsed event from AI
|
|
106
|
-
interface ParsedEvent {
|
|
107
|
-
title: string;
|
|
108
|
-
startDateTime: string; // ISO 8601
|
|
109
|
-
endDateTime: string; // ISO 8601
|
|
110
|
-
isAllDay: boolean;
|
|
111
|
-
location?: string;
|
|
112
|
-
description?: string;
|
|
113
|
-
attendees?: string[];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Get access token from environment
|
|
117
|
-
function getAccessToken(): string {
|
|
118
|
-
const token = process.env.GOOGLE_CALENDAR_ACCESS_TOKEN;
|
|
119
|
-
if (!token) {
|
|
120
|
-
log("Error: Google Calendar not connected.", "error");
|
|
121
|
-
console.error("");
|
|
122
|
-
console.error("To use this skill, you need to connect your Google Calendar:");
|
|
123
|
-
console.error("1. Go to https://skills.md/dashboard/connectors");
|
|
124
|
-
console.error("2. Click 'Connect' on the Google Calendar connector");
|
|
125
|
-
console.error("3. Authorize access to your Google Calendar");
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
return token;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Get OpenAI API key
|
|
132
|
-
function getOpenAIKey(): string | null {
|
|
133
|
-
return process.env.OPENAI_API_KEY || null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Make authenticated Calendar API request
|
|
137
|
-
async function calendarRequest<T>(
|
|
138
|
-
endpoint: string,
|
|
139
|
-
accessToken: string,
|
|
140
|
-
options: RequestInit = {}
|
|
141
|
-
): Promise<T> {
|
|
142
|
-
const url = `${CALENDAR_API_BASE}${endpoint}`;
|
|
143
|
-
|
|
144
|
-
log(`Calendar API request: ${options.method || "GET"} ${endpoint}`, "debug");
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
const response = await fetch(url, {
|
|
148
|
-
...options,
|
|
149
|
-
headers: {
|
|
150
|
-
Authorization: `Bearer ${accessToken}`,
|
|
151
|
-
Accept: "application/json",
|
|
152
|
-
"Content-Type": "application/json",
|
|
153
|
-
...options.headers,
|
|
154
|
-
},
|
|
155
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
log(`Calendar API response: ${response.status}`, "debug");
|
|
159
|
-
|
|
160
|
-
if (!response.ok) {
|
|
161
|
-
const error = await response.json().catch(() => ({}));
|
|
162
|
-
if (response.status === 401) {
|
|
163
|
-
log("Error: Google Calendar access token expired or invalid.", "error");
|
|
164
|
-
console.error("Please reconnect your Google Calendar in the Connectors dashboard.");
|
|
165
|
-
process.exit(1);
|
|
166
|
-
}
|
|
167
|
-
throw new Error(error.error?.message || `Calendar API error: ${response.status}`);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Handle empty responses
|
|
171
|
-
if (response.status === 204) {
|
|
172
|
-
return {} as T;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return response.json();
|
|
176
|
-
} catch (error) {
|
|
177
|
-
if (error instanceof Error && error.name === "TimeoutError") {
|
|
178
|
-
throw new Error(`Calendar API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);
|
|
179
|
-
}
|
|
180
|
-
throw error;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Parse natural language event using OpenAI
|
|
185
|
-
async function parseEventWithAI(
|
|
186
|
-
text: string,
|
|
187
|
-
timezone: string
|
|
188
|
-
): Promise<ParsedEvent> {
|
|
189
|
-
const openaiKey = getOpenAIKey();
|
|
190
|
-
if (!openaiKey) {
|
|
191
|
-
throw new Error("OPENAI_API_KEY is required for natural language parsing. Use 'create' command with explicit options instead.");
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const now = new Date();
|
|
195
|
-
const currentDate = now.toISOString().split("T")[0];
|
|
196
|
-
const currentTime = now.toTimeString().split(" ")[0];
|
|
197
|
-
const dayOfWeek = now.toLocaleDateString("en-US", { weekday: "long" });
|
|
198
|
-
|
|
199
|
-
const systemPrompt = `You are a calendar event parser. Extract event details from natural language and return a JSON object.
|
|
200
|
-
|
|
201
|
-
Current context:
|
|
202
|
-
- Today is ${dayOfWeek}, ${currentDate}
|
|
203
|
-
- Current time is ${currentTime}
|
|
204
|
-
- Timezone: ${timezone}
|
|
205
|
-
|
|
206
|
-
Rules:
|
|
207
|
-
1. Parse the input and extract: title, start date/time, end date/time, location, description, attendees
|
|
208
|
-
2. For relative dates like "tomorrow", "next week", "next Monday", calculate the actual date
|
|
209
|
-
3. "Next week" means 7 days from today
|
|
210
|
-
4. If only a time is given (e.g., "at 5am"), assume it's the next occurrence of that time
|
|
211
|
-
5. If no duration is specified, default to 1 hour for meetings/events
|
|
212
|
-
6. For all-day events (like "vacation on Dec 25"), set isAllDay to true
|
|
213
|
-
7. Return dates in ISO 8601 format with timezone offset
|
|
214
|
-
|
|
215
|
-
Return ONLY a valid JSON object with this structure:
|
|
216
|
-
{
|
|
217
|
-
"title": "Event title",
|
|
218
|
-
"startDateTime": "2025-01-15T10:00:00-08:00",
|
|
219
|
-
"endDateTime": "2025-01-15T11:00:00-08:00",
|
|
220
|
-
"isAllDay": false,
|
|
221
|
-
"location": "optional location",
|
|
222
|
-
"description": "optional description",
|
|
223
|
-
"attendees": ["email@example.com"]
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
For all-day events, use date format without time:
|
|
227
|
-
{
|
|
228
|
-
"title": "Vacation",
|
|
229
|
-
"startDateTime": "2025-01-15",
|
|
230
|
-
"endDateTime": "2025-01-16",
|
|
231
|
-
"isAllDay": true
|
|
232
|
-
}`;
|
|
233
|
-
|
|
234
|
-
log(`OpenAI API request: Parsing event`, "debug");
|
|
235
|
-
|
|
236
|
-
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
237
|
-
method: "POST",
|
|
238
|
-
headers: {
|
|
239
|
-
Authorization: `Bearer ${openaiKey}`,
|
|
240
|
-
"Content-Type": "application/json",
|
|
241
|
-
},
|
|
242
|
-
body: JSON.stringify({
|
|
243
|
-
model: "gpt-4o-mini",
|
|
244
|
-
messages: [
|
|
245
|
-
{ role: "system", content: systemPrompt },
|
|
246
|
-
{ role: "user", content: text },
|
|
247
|
-
],
|
|
248
|
-
temperature: 0,
|
|
249
|
-
response_format: { type: "json_object" },
|
|
250
|
-
}),
|
|
251
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
log(`OpenAI API response: ${response.status}`, "debug");
|
|
255
|
-
|
|
256
|
-
if (!response.ok) {
|
|
257
|
-
const error = await response.json().catch(() => ({}));
|
|
258
|
-
throw new Error(error.error?.message || `OpenAI API error: ${response.status}`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const data = await response.json();
|
|
262
|
-
const content = data.choices?.[0]?.message?.content;
|
|
263
|
-
|
|
264
|
-
if (!content) {
|
|
265
|
-
throw new Error("Failed to parse event from AI response");
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
try {
|
|
269
|
-
const parsed = JSON.parse(content) as ParsedEvent;
|
|
270
|
-
|
|
271
|
-
// Validate required fields
|
|
272
|
-
if (!parsed.title || !parsed.startDateTime || !parsed.endDateTime) {
|
|
273
|
-
throw new Error("AI response missing required fields");
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return parsed;
|
|
277
|
-
} catch (e) {
|
|
278
|
-
throw new Error(`Failed to parse AI response: ${e instanceof Error ? e.message : "Invalid JSON"}`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
9
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (options.timeMin) {
|
|
305
|
-
params.set("timeMin", options.timeMin);
|
|
306
|
-
}
|
|
307
|
-
if (options.timeMax) {
|
|
308
|
-
params.set("timeMax", options.timeMax);
|
|
309
|
-
}
|
|
310
|
-
if (options.maxResults) {
|
|
311
|
-
params.set("maxResults", options.maxResults.toString());
|
|
312
|
-
}
|
|
313
|
-
if (options.pageToken) {
|
|
314
|
-
params.set("pageToken", options.pageToken);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
params.set("singleEvents", "true");
|
|
318
|
-
params.set("orderBy", "startTime");
|
|
319
|
-
|
|
320
|
-
return calendarRequest(
|
|
321
|
-
`/calendars/${encodeURIComponent(options.calendarId)}/events?${params.toString()}`,
|
|
322
|
-
accessToken
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Get single event
|
|
327
|
-
async function getEvent(
|
|
328
|
-
accessToken: string,
|
|
329
|
-
calendarId: string,
|
|
330
|
-
eventId: string
|
|
331
|
-
): Promise<CalendarEvent> {
|
|
332
|
-
return calendarRequest(
|
|
333
|
-
`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`,
|
|
334
|
-
accessToken
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Create event
|
|
339
|
-
async function createEvent(
|
|
340
|
-
accessToken: string,
|
|
341
|
-
calendarId: string,
|
|
342
|
-
event: Partial<CalendarEvent>
|
|
343
|
-
): Promise<CalendarEvent> {
|
|
344
|
-
return calendarRequest(
|
|
345
|
-
`/calendars/${encodeURIComponent(calendarId)}/events`,
|
|
346
|
-
accessToken,
|
|
347
|
-
{
|
|
348
|
-
method: "POST",
|
|
349
|
-
body: JSON.stringify(event),
|
|
350
|
-
}
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Update event
|
|
355
|
-
async function updateEvent(
|
|
356
|
-
accessToken: string,
|
|
357
|
-
calendarId: string,
|
|
358
|
-
eventId: string,
|
|
359
|
-
updates: Partial<CalendarEvent>
|
|
360
|
-
): Promise<CalendarEvent> {
|
|
361
|
-
return calendarRequest(
|
|
362
|
-
`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`,
|
|
363
|
-
accessToken,
|
|
364
|
-
{
|
|
365
|
-
method: "PATCH",
|
|
366
|
-
body: JSON.stringify(updates),
|
|
367
|
-
}
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Delete event
|
|
372
|
-
async function deleteEvent(
|
|
373
|
-
accessToken: string,
|
|
374
|
-
calendarId: string,
|
|
375
|
-
eventId: string
|
|
376
|
-
): Promise<void> {
|
|
377
|
-
await calendarRequest(
|
|
378
|
-
`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`,
|
|
379
|
-
accessToken,
|
|
380
|
-
{
|
|
381
|
-
method: "DELETE",
|
|
382
|
-
}
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
// Format date for display
|
|
387
|
-
function formatDate(dateStr: string): string {
|
|
388
|
-
const date = new Date(dateStr);
|
|
389
|
-
return date.toLocaleDateString("en-US", {
|
|
390
|
-
weekday: "short",
|
|
391
|
-
month: "short",
|
|
392
|
-
day: "numeric",
|
|
393
|
-
year: "numeric",
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Format time for display
|
|
398
|
-
function formatTime(dateStr: string): string {
|
|
399
|
-
const date = new Date(dateStr);
|
|
400
|
-
return date.toLocaleTimeString("en-US", {
|
|
401
|
-
hour: "2-digit",
|
|
402
|
-
minute: "2-digit",
|
|
403
|
-
hour12: true,
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// Format events for text output
|
|
408
|
-
function formatEventsText(events: CalendarEvent[]): string {
|
|
409
|
-
if (events.length === 0) {
|
|
410
|
-
return "No upcoming events found.";
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
const lines: string[] = [];
|
|
414
|
-
let currentDate = "";
|
|
415
|
-
|
|
416
|
-
for (const event of events) {
|
|
417
|
-
const startDate = event.start.dateTime || event.start.date || "";
|
|
418
|
-
const eventDate = formatDate(startDate);
|
|
419
|
-
|
|
420
|
-
if (eventDate !== currentDate) {
|
|
421
|
-
if (currentDate !== "") lines.push("");
|
|
422
|
-
lines.push(eventDate);
|
|
423
|
-
currentDate = eventDate;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const isAllDay = !event.start.dateTime;
|
|
427
|
-
if (isAllDay) {
|
|
428
|
-
lines.push(` All Day ${event.summary || "(No title)"}`);
|
|
429
|
-
} else {
|
|
430
|
-
const startTime = formatTime(event.start.dateTime!);
|
|
431
|
-
const endTime = formatTime(event.end.dateTime!);
|
|
432
|
-
lines.push(` ${startTime} - ${endTime} ${event.summary || "(No title)"}`);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (event.location) {
|
|
436
|
-
lines.push(` Location: ${event.location}`);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
lines.push(` ID: ${event.id}`);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
return lines.join("\n");
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// Format calendars for text output
|
|
446
|
-
function formatCalendarsText(calendars: Calendar[]): string {
|
|
447
|
-
const lines = ["Your Calendars", "==============", ""];
|
|
448
|
-
|
|
449
|
-
for (const cal of calendars) {
|
|
450
|
-
const primary = cal.primary ? " (primary)" : "";
|
|
451
|
-
lines.push(`${cal.summary}${primary}`);
|
|
452
|
-
lines.push(` ID: ${cal.id}`);
|
|
453
|
-
if (cal.description) {
|
|
454
|
-
lines.push(` Description: ${cal.description}`);
|
|
455
|
-
}
|
|
456
|
-
lines.push("");
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
return lines.join("\n");
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Parse attendees from comma-separated string
|
|
463
|
-
function parseAttendees(input: string): Array<{ email: string }> {
|
|
464
|
-
return input
|
|
465
|
-
.split(",")
|
|
466
|
-
.map((email) => email.trim())
|
|
467
|
-
.filter(Boolean)
|
|
468
|
-
.map((email) => ({ email }));
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Parse reminder minutes from comma-separated string
|
|
472
|
-
function parseReminders(input: string): Array<{ method: string; minutes: number }> {
|
|
473
|
-
return input
|
|
474
|
-
.split(",")
|
|
475
|
-
.map((m) => parseInt(m.trim(), 10))
|
|
476
|
-
.filter((m) => !isNaN(m))
|
|
477
|
-
.map((minutes) => ({ method: "popup", minutes }));
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Show help
|
|
481
|
-
function showHelp(): void {
|
|
482
|
-
console.log(`
|
|
483
|
-
Calendar Events - Manage Google Calendar events
|
|
484
|
-
|
|
485
|
-
Usage:
|
|
486
|
-
skills run calendar-events -- <command> [options]
|
|
487
|
-
|
|
488
|
-
Commands:
|
|
489
|
-
list List upcoming events
|
|
490
|
-
create Create a new event with explicit options
|
|
491
|
-
add <text> Create event from natural language (AI-powered)
|
|
492
|
-
update Update an existing event
|
|
493
|
-
delete Delete an event
|
|
494
|
-
get Get details of a specific event
|
|
495
|
-
calendars List available calendars
|
|
496
|
-
|
|
497
|
-
Options:
|
|
498
|
-
--days <n> Days to look ahead (for list) [default: 14]
|
|
499
|
-
--max <n> Maximum events to return [default: 50]
|
|
500
|
-
--calendar <id> Calendar ID [default: primary]
|
|
501
|
-
--id <event-id> Event ID (for get/update/delete)
|
|
502
|
-
--title <text> Event title
|
|
503
|
-
--start <datetime> Start time (ISO 8601: "2025-01-15T10:00:00")
|
|
504
|
-
--end <datetime> End time (ISO 8601: "2025-01-15T11:00:00")
|
|
505
|
-
--duration <mins> Duration in minutes (alternative to --end)
|
|
506
|
-
--date <date> Date for all-day event (YYYY-MM-DD)
|
|
507
|
-
--all-day Create as all-day event
|
|
508
|
-
--location <text> Event location
|
|
509
|
-
--description <text> Event description
|
|
510
|
-
--attendees <emails> Comma-separated attendee emails (create/update)
|
|
511
|
-
--reminder <mins> Reminder minutes (comma-separated, e.g., 10,30)
|
|
512
|
-
--format <format> Output format: text or json [default: text]
|
|
513
|
-
--help, -h Show this help
|
|
514
|
-
|
|
515
|
-
Examples:
|
|
516
|
-
# List events for next 7 days
|
|
517
|
-
skills run calendar-events -- list --days 7
|
|
518
|
-
|
|
519
|
-
# Create an event with explicit options
|
|
520
|
-
skills run calendar-events -- create --title "Meeting" --start "2025-01-15T10:00:00" --end "2025-01-15T11:00:00"
|
|
521
|
-
|
|
522
|
-
# Create an event using natural language (AI-powered)
|
|
523
|
-
skills run calendar-events -- add "Team standup next Monday at 9am for 30 minutes"
|
|
524
|
-
skills run calendar-events -- add "Lunch with Sarah tomorrow at noon at Cafe Milano"
|
|
525
|
-
skills run calendar-events -- add "Vacation Dec 25-27"
|
|
526
|
-
|
|
527
|
-
# Delete an event
|
|
528
|
-
skills run calendar-events -- delete --id abc123
|
|
529
|
-
|
|
530
|
-
Note: The 'add' command requires OPENAI_API_KEY for natural language parsing.
|
|
531
|
-
`);
|
|
532
|
-
}
|
|
10
|
+
import { getAccessToken } from "./auth";
|
|
11
|
+
import { parseEventWithAI } from "./ai-parser";
|
|
12
|
+
import {
|
|
13
|
+
createEvent,
|
|
14
|
+
deleteEvent,
|
|
15
|
+
getEvent,
|
|
16
|
+
listCalendars,
|
|
17
|
+
listEvents,
|
|
18
|
+
updateEvent,
|
|
19
|
+
} from "./api";
|
|
20
|
+
import {
|
|
21
|
+
formatCalendarsText,
|
|
22
|
+
formatDate,
|
|
23
|
+
formatEventsText,
|
|
24
|
+
formatTime,
|
|
25
|
+
parseAttendees,
|
|
26
|
+
parseReminders,
|
|
27
|
+
} from "./format";
|
|
28
|
+
import { showHelp } from "./help";
|
|
29
|
+
import { log, SESSION_ID, SKILL_NAME } from "./logger";
|
|
30
|
+
import type { CalendarEvent } from "./types";
|
|
533
31
|
|
|
534
|
-
// Main function
|
|
535
32
|
async function main() {
|
|
536
33
|
log(`Starting ${SKILL_NAME} session: ${SESSION_ID}`, "debug");
|
|
537
34
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync } from "fs";
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
|
|
5
|
+
export const SKILL_NAME = "calendar-events";
|
|
6
|
+
export const SESSION_ID = randomUUID().slice(0, 8);
|
|
7
|
+
export const SKILLS_OUTPUT_DIR = process.env.SKILLS_OUTPUT_DIR || join(process.cwd(), ".skills");
|
|
8
|
+
export const LOGS_DIR = join(SKILLS_OUTPUT_DIR, "logs", SKILL_NAME);
|
|
9
|
+
export const SESSION_TIMESTAMP = new Date().toISOString().replace(/[:.]/g, "_").slice(0, 19);
|
|
10
|
+
|
|
11
|
+
// Ensure directories exist
|
|
12
|
+
export function ensureDir(dir: string) {
|
|
13
|
+
if (!existsSync(dir)) {
|
|
14
|
+
mkdirSync(dir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Logger
|
|
19
|
+
export function log(message: string, level: "info" | "error" | "success" | "debug" = "info") {
|
|
20
|
+
ensureDir(LOGS_DIR);
|
|
21
|
+
const timestamp = new Date().toISOString();
|
|
22
|
+
const logFile = join(LOGS_DIR, `log_${SESSION_TIMESTAMP}_${SESSION_ID}.log`);
|
|
23
|
+
const logEntry = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
|
|
24
|
+
appendFileSync(logFile, logEntry);
|
|
25
|
+
|
|
26
|
+
const prefix = level === "error" ? "❌" : level === "success" ? "✅" : level === "debug" ? "🔍" : "ℹ️";
|
|
27
|
+
if (level === "error") {
|
|
28
|
+
console.error(`${prefix} ${message}`);
|
|
29
|
+
} else if (level !== "debug") {
|
|
30
|
+
console.log(`${prefix} ${message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Types
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface CalendarEvent {
|
|
2
|
+
id: string;
|
|
3
|
+
summary?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
location?: string;
|
|
6
|
+
start: {
|
|
7
|
+
dateTime?: string;
|
|
8
|
+
date?: string;
|
|
9
|
+
timeZone?: string;
|
|
10
|
+
};
|
|
11
|
+
end: {
|
|
12
|
+
dateTime?: string;
|
|
13
|
+
date?: string;
|
|
14
|
+
timeZone?: string;
|
|
15
|
+
};
|
|
16
|
+
attendees?: Array<{
|
|
17
|
+
email: string;
|
|
18
|
+
displayName?: string;
|
|
19
|
+
responseStatus?: string;
|
|
20
|
+
}>;
|
|
21
|
+
htmlLink?: string;
|
|
22
|
+
status?: string;
|
|
23
|
+
created?: string;
|
|
24
|
+
updated?: string;
|
|
25
|
+
organizer?: {
|
|
26
|
+
email: string;
|
|
27
|
+
displayName?: string;
|
|
28
|
+
};
|
|
29
|
+
reminders?: {
|
|
30
|
+
useDefault: boolean;
|
|
31
|
+
overrides?: Array<{
|
|
32
|
+
method: string;
|
|
33
|
+
minutes: number;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Calendar {
|
|
39
|
+
id: string;
|
|
40
|
+
summary: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
primary?: boolean;
|
|
43
|
+
backgroundColor?: string;
|
|
44
|
+
accessRole?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface EventsListResponse {
|
|
48
|
+
items?: CalendarEvent[];
|
|
49
|
+
nextPageToken?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CalendarListResponse {
|
|
53
|
+
items?: Calendar[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Parsed event from AI
|
|
57
|
+
export interface ParsedEvent {
|
|
58
|
+
title: string;
|
|
59
|
+
startDateTime: string; // ISO 8601
|
|
60
|
+
endDateTime: string; // ISO 8601
|
|
61
|
+
isAllDay: boolean;
|
|
62
|
+
location?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
attendees?: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Get access token from environment
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: compress-video
|
|
3
3
|
version: 0.1.0
|
|
4
4
|
description: Compress videos while preserving quality using FFmpeg with multiple codec options and preset configurations
|
|
5
5
|
author: skills.md
|
|
@@ -76,4 +76,4 @@ skills run compress-video -- vlog.mp4 \
|
|
|
76
76
|
## Requirements
|
|
77
77
|
|
|
78
78
|
- FFmpeg installed and in PATH.
|
|
79
|
-
- Bun runtime.
|
|
79
|
+
- Bun runtime.
|