jfl 0.0.0
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 +21 -0
- package/README.md +313 -0
- package/clawdbot-skill/README.md +328 -0
- package/clawdbot-skill/SKILL.md +362 -0
- package/clawdbot-skill/index.ts +486 -0
- package/clawdbot-skill/package.json +28 -0
- package/clawdbot-skill/skill.json +28 -0
- package/dist/commands/agents.d.ts +5 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +399 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/context-hub.d.ts +12 -0
- package/dist/commands/context-hub.d.ts.map +1 -0
- package/dist/commands/context-hub.js +642 -0
- package/dist/commands/context-hub.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +370 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/feedback.d.ts +2 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +178 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/hud.d.ts +4 -0
- package/dist/commands/hud.d.ts.map +1 -0
- package/dist/commands/hud.js +262 -0
- package/dist/commands/hud.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +553 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +23 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +818 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/ralph.d.ts +9 -0
- package/dist/commands/ralph.d.ts.map +1 -0
- package/dist/commands/ralph.js +67 -0
- package/dist/commands/ralph.js.map +1 -0
- package/dist/commands/repair.d.ts +7 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +283 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/session-mgmt.d.ts +33 -0
- package/dist/commands/session-mgmt.d.ts.map +1 -0
- package/dist/commands/session-mgmt.js +404 -0
- package/dist/commands/session-mgmt.js.map +1 -0
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +639 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/skills.d.ts +31 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +314 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +127 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/synopsis.d.ts +10 -0
- package/dist/commands/synopsis.d.ts.map +1 -0
- package/dist/commands/synopsis.js +277 -0
- package/dist/commands/synopsis.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +165 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/voice.d.ts +410 -0
- package/dist/commands/voice.d.ts.map +1 -0
- package/dist/commands/voice.js +4763 -0
- package/dist/commands/voice.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +512 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/context-hub-mcp.d.ts +11 -0
- package/dist/mcp/context-hub-mcp.d.ts.map +1 -0
- package/dist/mcp/context-hub-mcp.js +548 -0
- package/dist/mcp/context-hub-mcp.js.map +1 -0
- package/dist/telegram/voice.d.ts +146 -0
- package/dist/telegram/voice.d.ts.map +1 -0
- package/dist/telegram/voice.js +351 -0
- package/dist/telegram/voice.js.map +1 -0
- package/dist/types/skills.d.ts +44 -0
- package/dist/types/skills.d.ts.map +1 -0
- package/dist/types/skills.js +5 -0
- package/dist/types/skills.js.map +1 -0
- package/dist/ui/banner.d.ts +18 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +323 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/prompts.d.ts +52 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +72 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/theme.d.ts +82 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +142 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/auth-guard.d.ts +66 -0
- package/dist/utils/auth-guard.d.ts.map +1 -0
- package/dist/utils/auth-guard.js +348 -0
- package/dist/utils/auth-guard.js.map +1 -0
- package/dist/utils/ensure-project.d.ts +11 -0
- package/dist/utils/ensure-project.d.ts.map +1 -0
- package/dist/utils/ensure-project.js +70 -0
- package/dist/utils/ensure-project.js.map +1 -0
- package/dist/utils/git.d.ts +73 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +219 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/github-auth.d.ts +54 -0
- package/dist/utils/github-auth.d.ts.map +1 -0
- package/dist/utils/github-auth.js +375 -0
- package/dist/utils/github-auth.js.map +1 -0
- package/dist/utils/github-repo.d.ts +30 -0
- package/dist/utils/github-repo.d.ts.map +1 -0
- package/dist/utils/github-repo.js +219 -0
- package/dist/utils/github-repo.js.map +1 -0
- package/dist/utils/platform-auth.d.ts +81 -0
- package/dist/utils/platform-auth.d.ts.map +1 -0
- package/dist/utils/platform-auth.js +191 -0
- package/dist/utils/platform-auth.js.map +1 -0
- package/dist/utils/project-config.d.ts +43 -0
- package/dist/utils/project-config.d.ts.map +1 -0
- package/dist/utils/project-config.js +97 -0
- package/dist/utils/project-config.js.map +1 -0
- package/dist/utils/skill-registry.d.ts +49 -0
- package/dist/utils/skill-registry.d.ts.map +1 -0
- package/dist/utils/skill-registry.js +192 -0
- package/dist/utils/skill-registry.js.map +1 -0
- package/dist/utils/wallet.d.ts +62 -0
- package/dist/utils/wallet.d.ts.map +1 -0
- package/dist/utils/wallet.js +252 -0
- package/dist/utils/wallet.js.map +1 -0
- package/dist/utils/x402-client.d.ts +86 -0
- package/dist/utils/x402-client.d.ts.map +1 -0
- package/dist/utils/x402-client.js +265 -0
- package/dist/utils/x402-client.js.map +1 -0
- package/package.json +76 -0
- package/scripts/postinstall.js +116 -0
- package/scripts/test-onboarding.sh +121 -0
- package/scripts/voice-start.sh +128 -0
- package/scripts/voice-stop.sh +33 -0
- package/template/.claude/settings.json +92 -0
- package/template/.claude/skills/agent-browser/SKILL.md +116 -0
- package/template/.claude/skills/brand-architect/SKILL.md +240 -0
- package/template/.claude/skills/brand-architect/config.yaml +137 -0
- package/template/.claude/skills/campaign-hud/config.yaml +112 -0
- package/template/.claude/skills/content-creator/SKILL.md +294 -0
- package/template/.claude/skills/debug/MULTI_AGENT.md +360 -0
- package/template/.claude/skills/debug/SKILL.md +549 -0
- package/template/.claude/skills/fly-deploy/SKILL.md +676 -0
- package/template/.claude/skills/founder-video/SKILL.md +467 -0
- package/template/.claude/skills/hud/SKILL.md +157 -0
- package/template/.claude/skills/ralph-tui/SKILL.md +210 -0
- package/template/.claude/skills/react-best-practices/AGENTS.md +2249 -0
- package/template/.claude/skills/react-best-practices/README.md +123 -0
- package/template/.claude/skills/react-best-practices/SKILL.md +125 -0
- package/template/.claude/skills/react-best-practices/metadata.json +15 -0
- package/template/.claude/skills/react-best-practices/rules/_sections.md +46 -0
- package/template/.claude/skills/react-best-practices/rules/_template.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/template/.claude/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/template/.claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/template/.claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/template/.claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/template/.claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/template/.claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/template/.claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/template/.claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/template/.claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/template/.claude/skills/remotion-best-practices/SKILL.md +43 -0
- package/template/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
- package/template/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/template/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
- package/template/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
- package/template/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/template/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/template/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/compositions.md +146 -0
- package/template/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
- package/template/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/template/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/template/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/template/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
- package/template/.claude/skills/remotion-best-practices/rules/images.md +130 -0
- package/template/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/template/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
- package/template/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/template/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/template/.claude/skills/remotion-best-practices/rules/sequencing.md +106 -0
- package/template/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/template/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/template/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
- package/template/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/template/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
- package/template/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
- package/template/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
- package/template/.claude/skills/search/SKILL.md +220 -0
- package/template/.claude/skills/spec/SKILL.md +377 -0
- package/template/.claude/skills/startup/SKILL.md +310 -0
- package/template/.claude/skills/web-architect/SKILL.md +309 -0
- package/template/.claude/skills/x-algorithm/SKILL.md +305 -0
- package/template/.jfl/config.json +8 -0
- package/template/.mcp.json +11 -0
- package/template/CLAUDE.md +960 -0
- package/template/content/.gitkeep +0 -0
- package/template/context-hub +3 -0
- package/template/knowledge/BRAND_BRIEF.md +124 -0
- package/template/knowledge/BRAND_DECISIONS.md +168 -0
- package/template/knowledge/NARRATIVE.md +114 -0
- package/template/knowledge/ROADMAP.md +128 -0
- package/template/knowledge/THESIS.md +108 -0
- package/template/knowledge/VISION.md +74 -0
- package/template/knowledge/VOICE_AND_TONE.md +146 -0
- package/template/previews/.gitkeep +0 -0
- package/template/scripts/session/auto-commit.sh +245 -0
- package/template/scripts/session/auto-merge.sh +325 -0
- package/template/scripts/session/jfl-doctor.sh +587 -0
- package/template/scripts/session/session-end.sh +194 -0
- package/template/scripts/session/session-init.sh +163 -0
- package/template/scripts/session/session-sync.sh +167 -0
- package/template/scripts/session/test-context-preservation.sh +160 -0
- package/template/skills/agent-browser/SKILL.md +116 -0
- package/template/skills/brand-architect/SKILL.md +240 -0
- package/template/skills/brand-architect/config.yaml +137 -0
- package/template/skills/campaign-hud/config.yaml +112 -0
- package/template/skills/content-creator/SKILL.md +294 -0
- package/template/skills/debug/MULTI_AGENT.md +360 -0
- package/template/skills/debug/SKILL.md +549 -0
- package/template/skills/fly-deploy/SKILL.md +676 -0
- package/template/skills/founder-video/SKILL.md +467 -0
- package/template/skills/hud/SKILL.md +204 -0
- package/template/skills/ralph-tui/SKILL.md +210 -0
- package/template/skills/react-best-practices/AGENTS.md +2249 -0
- package/template/skills/react-best-practices/README.md +123 -0
- package/template/skills/react-best-practices/SKILL.md +125 -0
- package/template/skills/react-best-practices/metadata.json +15 -0
- package/template/skills/react-best-practices/rules/_sections.md +46 -0
- package/template/skills/react-best-practices/rules/_template.md +28 -0
- package/template/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/template/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/template/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/template/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/template/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/template/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/template/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/template/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/template/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/template/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/template/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/template/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/template/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/template/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/template/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/template/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/template/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/template/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/template/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/template/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/template/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/template/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/template/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/template/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/template/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/template/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/template/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/template/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/template/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/template/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/template/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/template/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/template/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/template/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/template/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/template/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/template/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/template/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/template/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/template/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/template/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/template/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/template/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/template/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/template/skills/remotion-best-practices/SKILL.md +43 -0
- package/template/skills/remotion-best-practices/rules/3d.md +86 -0
- package/template/skills/remotion-best-practices/rules/animations.md +29 -0
- package/template/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/template/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/template/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/template/skills/remotion-best-practices/rules/assets.md +78 -0
- package/template/skills/remotion-best-practices/rules/audio.md +172 -0
- package/template/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/template/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/template/skills/remotion-best-practices/rules/charts.md +58 -0
- package/template/skills/remotion-best-practices/rules/compositions.md +146 -0
- package/template/skills/remotion-best-practices/rules/display-captions.md +126 -0
- package/template/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/template/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/template/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/template/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/template/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/template/skills/remotion-best-practices/rules/gifs.md +138 -0
- package/template/skills/remotion-best-practices/rules/images.md +130 -0
- package/template/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/template/skills/remotion-best-practices/rules/lottie.md +68 -0
- package/template/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/template/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/template/skills/remotion-best-practices/rules/sequencing.md +106 -0
- package/template/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/template/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/template/skills/remotion-best-practices/rules/timing.md +179 -0
- package/template/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/template/skills/remotion-best-practices/rules/transitions.md +122 -0
- package/template/skills/remotion-best-practices/rules/trimming.md +53 -0
- package/template/skills/remotion-best-practices/rules/videos.md +171 -0
- package/template/skills/search/SKILL.md +220 -0
- package/template/skills/spec/SKILL.md +377 -0
- package/template/skills/startup/SKILL.md +310 -0
- package/template/skills/web-architect/SKILL.md +309 -0
- package/template/skills/x-algorithm/SKILL.md +305 -0
- package/template/suggestions/.gitkeep +0 -0
- package/template/templates/QUICKSTART_SKILL_TO_PRODUCT.md +242 -0
- package/template/templates/brand/BRAND_BRIEF.md +124 -0
- package/template/templates/brand/BRAND_DECISIONS.md +168 -0
- package/template/templates/brand/BRAND_GUIDELINES.md +251 -0
- package/template/templates/brand/VOICE_AND_TONE.md +146 -0
- package/template/templates/brand/global.css +240 -0
- package/template/templates/collaboration/CONTRIBUTOR.md +74 -0
- package/template/templates/collaboration/CRM.md +97 -0
- package/template/templates/collaboration/TASKS.md +83 -0
- package/template/templates/strategic/NARRATIVE.md +114 -0
- package/template/templates/strategic/ROADMAP.md +128 -0
- package/template/templates/strategic/THESIS.md +108 -0
- package/template/templates/strategic/VISION.md +74 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Voice Message Handler
|
|
3
|
+
*
|
|
4
|
+
* TG-001: Add voice message handler to Telegram bot
|
|
5
|
+
* TG-002: Implement OGG to WAV conversion
|
|
6
|
+
* TG-003: Connect Telegram to whisper HTTP endpoint
|
|
7
|
+
*
|
|
8
|
+
* Handles voice messages from Telegram, converts OGG Opus to WAV,
|
|
9
|
+
* and sends to local whisper server for transcription.
|
|
10
|
+
*/
|
|
11
|
+
/** Telegram context object (stub for integration) */
|
|
12
|
+
export interface TelegramContext {
|
|
13
|
+
message?: {
|
|
14
|
+
voice?: {
|
|
15
|
+
file_id: string;
|
|
16
|
+
file_unique_id: string;
|
|
17
|
+
duration: number;
|
|
18
|
+
mime_type?: string;
|
|
19
|
+
file_size?: number;
|
|
20
|
+
};
|
|
21
|
+
from?: {
|
|
22
|
+
id: number;
|
|
23
|
+
username?: string;
|
|
24
|
+
first_name?: string;
|
|
25
|
+
};
|
|
26
|
+
chat: {
|
|
27
|
+
id: number;
|
|
28
|
+
type: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
reply: (text: string, options?: ReplyOptions) => Promise<void>;
|
|
32
|
+
replyWithMarkdown?: (text: string, options?: ReplyOptions) => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
interface ReplyOptions {
|
|
35
|
+
reply_to_message_id?: number;
|
|
36
|
+
parse_mode?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Whisper transcription response */
|
|
39
|
+
interface WhisperResponse {
|
|
40
|
+
text: string;
|
|
41
|
+
segments?: Array<{
|
|
42
|
+
start: number;
|
|
43
|
+
end: number;
|
|
44
|
+
text: string;
|
|
45
|
+
}>;
|
|
46
|
+
language?: string;
|
|
47
|
+
duration?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Voice handler configuration */
|
|
50
|
+
export interface VoiceHandlerConfig {
|
|
51
|
+
/** Telegram Bot API token */
|
|
52
|
+
botToken: string;
|
|
53
|
+
/** Whisper server URL (default: http://localhost:8080) */
|
|
54
|
+
whisperUrl?: string;
|
|
55
|
+
/** Max file size in bytes (default: 20MB) */
|
|
56
|
+
maxFileSize?: number;
|
|
57
|
+
/** Max duration in seconds (default: 120s) */
|
|
58
|
+
maxDuration?: number;
|
|
59
|
+
/** Rate limit: max messages per window (default: 10) */
|
|
60
|
+
rateLimitMax?: number;
|
|
61
|
+
/** Rate limit window in ms (default: 60000 = 1 minute) */
|
|
62
|
+
rateLimitWindow?: number;
|
|
63
|
+
}
|
|
64
|
+
declare const DEFAULT_CONFIG: Required<Omit<VoiceHandlerConfig, 'botToken'>>;
|
|
65
|
+
declare const WAV_SAMPLE_RATE = 16000;
|
|
66
|
+
declare const WAV_BITS_PER_SAMPLE = 16;
|
|
67
|
+
declare const WAV_CHANNELS = 1;
|
|
68
|
+
/**
|
|
69
|
+
* Clear expired rate limit entries (call periodically)
|
|
70
|
+
*/
|
|
71
|
+
export declare function cleanupRateLimits(windowMs?: number): void;
|
|
72
|
+
/**
|
|
73
|
+
* Download audio file from Telegram servers
|
|
74
|
+
* TG-001: Downloads audio file from Telegram servers
|
|
75
|
+
*/
|
|
76
|
+
export declare function downloadTelegramAudio(fileId: string, botToken: string): Promise<Buffer>;
|
|
77
|
+
/**
|
|
78
|
+
* Convert OGG Opus audio to WAV format
|
|
79
|
+
* TG-002: Convert Telegram OGG Opus audio to WAV format
|
|
80
|
+
*
|
|
81
|
+
* Uses ffmpeg for conversion. ffmpeg is widely available and handles
|
|
82
|
+
* OGG Opus → WAV conversion reliably.
|
|
83
|
+
*
|
|
84
|
+
* Output: 16-bit PCM WAV, 16kHz sample rate, mono
|
|
85
|
+
*/
|
|
86
|
+
export declare function convertOggToWav(oggBuffer: Buffer): Promise<Buffer>;
|
|
87
|
+
/**
|
|
88
|
+
* Alternative: Convert OGG to WAV without ffmpeg using opusenc/opusdec
|
|
89
|
+
* This is a fallback if someone wants to avoid ffmpeg dependency.
|
|
90
|
+
* Currently not implemented - would require opus-tools.
|
|
91
|
+
*/
|
|
92
|
+
export declare function convertOggToWavNative(_oggBuffer: Buffer): Promise<Buffer>;
|
|
93
|
+
/**
|
|
94
|
+
* Send audio to whisper server for transcription
|
|
95
|
+
* TG-003: POST to /v1/transcribe with WAV body
|
|
96
|
+
*/
|
|
97
|
+
export declare function transcribeAudio(wavBuffer: Buffer, whisperUrl?: string): Promise<WhisperResponse>;
|
|
98
|
+
/**
|
|
99
|
+
* Main voice message handler
|
|
100
|
+
* TG-001, TG-002, TG-003: Complete voice message handling flow
|
|
101
|
+
*
|
|
102
|
+
* 1. Validates the voice message (size, duration, rate limit)
|
|
103
|
+
* 2. Sends acknowledgment to user
|
|
104
|
+
* 3. Downloads audio from Telegram
|
|
105
|
+
* 4. Converts OGG Opus to WAV
|
|
106
|
+
* 5. Sends to whisper server for transcription
|
|
107
|
+
* 6. Returns transcription to user
|
|
108
|
+
*/
|
|
109
|
+
export declare function handleVoiceMessage(ctx: TelegramContext, config: VoiceHandlerConfig): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Create a voice handler with pre-configured settings
|
|
112
|
+
* Use this to integrate with telegraf or other bot frameworks
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* import { Telegraf } from 'telegraf'
|
|
117
|
+
* import { createVoiceHandler } from './telegram/voice.js'
|
|
118
|
+
*
|
|
119
|
+
* const bot = new Telegraf(process.env.BOT_TOKEN)
|
|
120
|
+
* const handleVoice = createVoiceHandler({
|
|
121
|
+
* botToken: process.env.BOT_TOKEN,
|
|
122
|
+
* whisperUrl: 'http://localhost:8080'
|
|
123
|
+
* })
|
|
124
|
+
*
|
|
125
|
+
* bot.on('voice', handleVoice)
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function createVoiceHandler(config: VoiceHandlerConfig): (ctx: TelegramContext) => Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Middleware to add voice handling to an existing bot
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { Telegraf } from 'telegraf'
|
|
135
|
+
* import { voiceMiddleware } from './telegram/voice.js'
|
|
136
|
+
*
|
|
137
|
+
* const bot = new Telegraf(process.env.BOT_TOKEN)
|
|
138
|
+
* bot.use(voiceMiddleware({
|
|
139
|
+
* botToken: process.env.BOT_TOKEN,
|
|
140
|
+
* whisperUrl: 'http://localhost:8080'
|
|
141
|
+
* }))
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare function voiceMiddleware(config: VoiceHandlerConfig): (ctx: TelegramContext, next: () => Promise<void>) => Promise<void>;
|
|
145
|
+
export { DEFAULT_CONFIG, WAV_SAMPLE_RATE, WAV_BITS_PER_SAMPLE, WAV_CHANNELS, };
|
|
146
|
+
//# sourceMappingURL=voice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/telegram/voice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Voice Message Handler
|
|
3
|
+
*
|
|
4
|
+
* TG-001: Add voice message handler to Telegram bot
|
|
5
|
+
* TG-002: Implement OGG to WAV conversion
|
|
6
|
+
* TG-003: Connect Telegram to whisper HTTP endpoint
|
|
7
|
+
*
|
|
8
|
+
* Handles voice messages from Telegram, converts OGG Opus to WAV,
|
|
9
|
+
* and sends to local whisper server for transcription.
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from 'child_process';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Constants
|
|
14
|
+
// ============================================================================
|
|
15
|
+
const DEFAULT_CONFIG = {
|
|
16
|
+
whisperUrl: 'http://localhost:8080',
|
|
17
|
+
maxFileSize: 20 * 1024 * 1024, // 20MB
|
|
18
|
+
maxDuration: 120, // 120 seconds
|
|
19
|
+
rateLimitMax: 10,
|
|
20
|
+
rateLimitWindow: 60 * 1000, // 1 minute
|
|
21
|
+
};
|
|
22
|
+
const TELEGRAM_API_BASE = 'https://api.telegram.org';
|
|
23
|
+
// OGG magic bytes: "OggS"
|
|
24
|
+
const OGG_MAGIC = Buffer.from([0x4f, 0x67, 0x67, 0x53]);
|
|
25
|
+
// WAV format constants
|
|
26
|
+
const WAV_SAMPLE_RATE = 16000;
|
|
27
|
+
const WAV_BITS_PER_SAMPLE = 16;
|
|
28
|
+
const WAV_CHANNELS = 1;
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Rate Limiting
|
|
31
|
+
// ============================================================================
|
|
32
|
+
/** Per-user rate limit tracking */
|
|
33
|
+
const rateLimitMap = new Map();
|
|
34
|
+
/**
|
|
35
|
+
* Check if user is rate limited
|
|
36
|
+
* @returns true if rate limited, false if allowed
|
|
37
|
+
*/
|
|
38
|
+
function isRateLimited(userId, maxMessages, windowMs) {
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const entry = rateLimitMap.get(userId);
|
|
41
|
+
if (!entry) {
|
|
42
|
+
// First request from this user
|
|
43
|
+
rateLimitMap.set(userId, { count: 1, windowStart: now });
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
// Check if window has expired
|
|
47
|
+
if (now - entry.windowStart > windowMs) {
|
|
48
|
+
// Reset window
|
|
49
|
+
rateLimitMap.set(userId, { count: 1, windowStart: now });
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
// Within window - check count
|
|
53
|
+
if (entry.count >= maxMessages) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
// Increment count
|
|
57
|
+
entry.count++;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Clear expired rate limit entries (call periodically)
|
|
62
|
+
*/
|
|
63
|
+
export function cleanupRateLimits(windowMs = DEFAULT_CONFIG.rateLimitWindow) {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const entries = Array.from(rateLimitMap.entries());
|
|
66
|
+
for (const [userId, entry] of entries) {
|
|
67
|
+
if (now - entry.windowStart > windowMs) {
|
|
68
|
+
rateLimitMap.delete(userId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Telegram API
|
|
74
|
+
// ============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Download audio file from Telegram servers
|
|
77
|
+
* TG-001: Downloads audio file from Telegram servers
|
|
78
|
+
*/
|
|
79
|
+
export async function downloadTelegramAudio(fileId, botToken) {
|
|
80
|
+
// Step 1: Get file path from Telegram
|
|
81
|
+
const getFileUrl = `${TELEGRAM_API_BASE}/bot${botToken}/getFile?file_id=${fileId}`;
|
|
82
|
+
const fileInfoResponse = await fetch(getFileUrl);
|
|
83
|
+
if (!fileInfoResponse.ok) {
|
|
84
|
+
throw new Error(`Failed to get file info: ${fileInfoResponse.statusText}`);
|
|
85
|
+
}
|
|
86
|
+
const fileInfo = await fileInfoResponse.json();
|
|
87
|
+
if (!fileInfo.ok || !fileInfo.result?.file_path) {
|
|
88
|
+
throw new Error(`Telegram API error: ${fileInfo.description || 'No file path returned'}`);
|
|
89
|
+
}
|
|
90
|
+
// Step 2: Download the actual file
|
|
91
|
+
const downloadUrl = `${TELEGRAM_API_BASE}/file/bot${botToken}/${fileInfo.result.file_path}`;
|
|
92
|
+
const fileResponse = await fetch(downloadUrl);
|
|
93
|
+
if (!fileResponse.ok) {
|
|
94
|
+
throw new Error(`Failed to download file: ${fileResponse.statusText}`);
|
|
95
|
+
}
|
|
96
|
+
const arrayBuffer = await fileResponse.arrayBuffer();
|
|
97
|
+
return Buffer.from(arrayBuffer);
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Audio Conversion
|
|
101
|
+
// ============================================================================
|
|
102
|
+
/**
|
|
103
|
+
* Validate OGG file by checking magic bytes
|
|
104
|
+
*/
|
|
105
|
+
function validateOggFile(buffer) {
|
|
106
|
+
if (buffer.length < 4) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return buffer.subarray(0, 4).equals(OGG_MAGIC);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Convert OGG Opus audio to WAV format
|
|
113
|
+
* TG-002: Convert Telegram OGG Opus audio to WAV format
|
|
114
|
+
*
|
|
115
|
+
* Uses ffmpeg for conversion. ffmpeg is widely available and handles
|
|
116
|
+
* OGG Opus → WAV conversion reliably.
|
|
117
|
+
*
|
|
118
|
+
* Output: 16-bit PCM WAV, 16kHz sample rate, mono
|
|
119
|
+
*/
|
|
120
|
+
export async function convertOggToWav(oggBuffer) {
|
|
121
|
+
// Validate input
|
|
122
|
+
if (!validateOggFile(oggBuffer)) {
|
|
123
|
+
throw new Error('Invalid OGG file: magic bytes do not match');
|
|
124
|
+
}
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
// ffmpeg args:
|
|
127
|
+
// -f ogg: input format
|
|
128
|
+
// -i pipe:0: read from stdin
|
|
129
|
+
// -f wav: output format
|
|
130
|
+
// -acodec pcm_s16le: 16-bit PCM
|
|
131
|
+
// -ar 16000: 16kHz sample rate
|
|
132
|
+
// -ac 1: mono
|
|
133
|
+
// pipe:1: write to stdout
|
|
134
|
+
const ffmpeg = spawn('ffmpeg', [
|
|
135
|
+
'-f', 'ogg',
|
|
136
|
+
'-i', 'pipe:0',
|
|
137
|
+
'-f', 'wav',
|
|
138
|
+
'-acodec', 'pcm_s16le',
|
|
139
|
+
'-ar', String(WAV_SAMPLE_RATE),
|
|
140
|
+
'-ac', String(WAV_CHANNELS),
|
|
141
|
+
'-loglevel', 'error',
|
|
142
|
+
'pipe:1'
|
|
143
|
+
]);
|
|
144
|
+
const chunks = [];
|
|
145
|
+
let errorOutput = '';
|
|
146
|
+
ffmpeg.stdout.on('data', (chunk) => {
|
|
147
|
+
chunks.push(chunk);
|
|
148
|
+
});
|
|
149
|
+
ffmpeg.stderr.on('data', (data) => {
|
|
150
|
+
errorOutput += data.toString();
|
|
151
|
+
});
|
|
152
|
+
ffmpeg.on('error', (err) => {
|
|
153
|
+
if (err.code === 'ENOENT') {
|
|
154
|
+
reject(new Error('ffmpeg not found. Please install ffmpeg:\n' +
|
|
155
|
+
' macOS: brew install ffmpeg\n' +
|
|
156
|
+
' Ubuntu: sudo apt install ffmpeg\n' +
|
|
157
|
+
' Windows: choco install ffmpeg'));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
reject(new Error(`ffmpeg error: ${err.message}`));
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
ffmpeg.on('close', (code) => {
|
|
164
|
+
if (code === 0) {
|
|
165
|
+
resolve(Buffer.concat(chunks));
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
reject(new Error(`ffmpeg exited with code ${code}: ${errorOutput}`));
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
// Write OGG data to ffmpeg stdin
|
|
172
|
+
ffmpeg.stdin.write(oggBuffer);
|
|
173
|
+
ffmpeg.stdin.end();
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Alternative: Convert OGG to WAV without ffmpeg using opusenc/opusdec
|
|
178
|
+
* This is a fallback if someone wants to avoid ffmpeg dependency.
|
|
179
|
+
* Currently not implemented - would require opus-tools.
|
|
180
|
+
*/
|
|
181
|
+
export async function convertOggToWavNative(_oggBuffer) {
|
|
182
|
+
throw new Error('Native OGG to WAV conversion not implemented. ' +
|
|
183
|
+
'Please install ffmpeg or contribute an implementation using opus-tools.');
|
|
184
|
+
}
|
|
185
|
+
// ============================================================================
|
|
186
|
+
// Whisper Integration
|
|
187
|
+
// ============================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Send audio to whisper server for transcription
|
|
190
|
+
* TG-003: POST to /v1/transcribe with WAV body
|
|
191
|
+
*/
|
|
192
|
+
export async function transcribeAudio(wavBuffer, whisperUrl = DEFAULT_CONFIG.whisperUrl) {
|
|
193
|
+
const url = `${whisperUrl}/v1/transcribe`;
|
|
194
|
+
const response = await fetch(url, {
|
|
195
|
+
method: 'POST',
|
|
196
|
+
headers: {
|
|
197
|
+
'Content-Type': 'audio/wav',
|
|
198
|
+
},
|
|
199
|
+
body: new Uint8Array(wavBuffer),
|
|
200
|
+
});
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
203
|
+
throw new Error(`Whisper transcription failed (${response.status}): ${errorText}`);
|
|
204
|
+
}
|
|
205
|
+
const result = await response.json();
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// Main Handler
|
|
210
|
+
// ============================================================================
|
|
211
|
+
/**
|
|
212
|
+
* Main voice message handler
|
|
213
|
+
* TG-001, TG-002, TG-003: Complete voice message handling flow
|
|
214
|
+
*
|
|
215
|
+
* 1. Validates the voice message (size, duration, rate limit)
|
|
216
|
+
* 2. Sends acknowledgment to user
|
|
217
|
+
* 3. Downloads audio from Telegram
|
|
218
|
+
* 4. Converts OGG Opus to WAV
|
|
219
|
+
* 5. Sends to whisper server for transcription
|
|
220
|
+
* 6. Returns transcription to user
|
|
221
|
+
*/
|
|
222
|
+
export async function handleVoiceMessage(ctx, config) {
|
|
223
|
+
const { botToken, whisperUrl = DEFAULT_CONFIG.whisperUrl, maxFileSize = DEFAULT_CONFIG.maxFileSize, maxDuration = DEFAULT_CONFIG.maxDuration, rateLimitMax = DEFAULT_CONFIG.rateLimitMax, rateLimitWindow = DEFAULT_CONFIG.rateLimitWindow, } = config;
|
|
224
|
+
// Validate message has voice
|
|
225
|
+
const voice = ctx.message?.voice;
|
|
226
|
+
if (!voice) {
|
|
227
|
+
await ctx.reply('No voice message found.');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const userId = ctx.message?.from?.id;
|
|
231
|
+
if (!userId) {
|
|
232
|
+
await ctx.reply('Could not identify user.');
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
// TG-001: Rate limiting per user
|
|
236
|
+
if (isRateLimited(userId, rateLimitMax, rateLimitWindow)) {
|
|
237
|
+
await ctx.reply('You are sending voice messages too quickly. Please wait a moment before trying again.', { reply_to_message_id: ctx.message?.chat.id });
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// TG-001: Validate file size
|
|
241
|
+
if (voice.file_size && voice.file_size > maxFileSize) {
|
|
242
|
+
const maxMb = Math.round(maxFileSize / (1024 * 1024));
|
|
243
|
+
await ctx.reply(`Voice message too large. Maximum size is ${maxMb}MB.`, { reply_to_message_id: ctx.message?.chat.id });
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
// TG-001: Validate duration
|
|
247
|
+
if (voice.duration > maxDuration) {
|
|
248
|
+
await ctx.reply(`Voice message too long. Maximum duration is ${maxDuration} seconds.`, { reply_to_message_id: ctx.message?.chat.id });
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// TG-003: Send acknowledgment before processing
|
|
252
|
+
await ctx.reply('Transcribing your voice message...');
|
|
253
|
+
try {
|
|
254
|
+
// TG-001: Download audio from Telegram
|
|
255
|
+
const oggBuffer = await downloadTelegramAudio(voice.file_id, botToken);
|
|
256
|
+
// Double-check downloaded size
|
|
257
|
+
if (oggBuffer.length > maxFileSize) {
|
|
258
|
+
await ctx.reply('Downloaded file exceeded maximum size.');
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// TG-002: Convert OGG to WAV
|
|
262
|
+
const wavBuffer = await convertOggToWav(oggBuffer);
|
|
263
|
+
// TG-003: Send to whisper for transcription
|
|
264
|
+
const transcription = await transcribeAudio(wavBuffer, whisperUrl);
|
|
265
|
+
// Send transcription result
|
|
266
|
+
if (transcription.text && transcription.text.trim()) {
|
|
267
|
+
const response = `Transcription:\n\n${transcription.text.trim()}`;
|
|
268
|
+
if (ctx.replyWithMarkdown) {
|
|
269
|
+
await ctx.replyWithMarkdown(`*Transcription:*\n\n${transcription.text.trim()}`);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
await ctx.reply(response);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
await ctx.reply('No speech detected in the voice message.');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
// TG-003: Handle transcription failures gracefully
|
|
281
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
282
|
+
console.error('Voice transcription error:', errorMessage);
|
|
283
|
+
// User-friendly error messages
|
|
284
|
+
if (errorMessage.includes('ffmpeg not found')) {
|
|
285
|
+
await ctx.reply('Voice transcription is not available. The server is missing required audio processing tools.');
|
|
286
|
+
}
|
|
287
|
+
else if (errorMessage.includes('Whisper transcription failed')) {
|
|
288
|
+
await ctx.reply('Transcription service is temporarily unavailable. Please try again later.');
|
|
289
|
+
}
|
|
290
|
+
else if (errorMessage.includes('Invalid OGG file')) {
|
|
291
|
+
await ctx.reply('Could not process the audio file. Please try recording again.');
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
await ctx.reply('An error occurred while processing your voice message. Please try again.');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// Bot Integration Helpers
|
|
300
|
+
// ============================================================================
|
|
301
|
+
/**
|
|
302
|
+
* Create a voice handler with pre-configured settings
|
|
303
|
+
* Use this to integrate with telegraf or other bot frameworks
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { Telegraf } from 'telegraf'
|
|
308
|
+
* import { createVoiceHandler } from './telegram/voice.js'
|
|
309
|
+
*
|
|
310
|
+
* const bot = new Telegraf(process.env.BOT_TOKEN)
|
|
311
|
+
* const handleVoice = createVoiceHandler({
|
|
312
|
+
* botToken: process.env.BOT_TOKEN,
|
|
313
|
+
* whisperUrl: 'http://localhost:8080'
|
|
314
|
+
* })
|
|
315
|
+
*
|
|
316
|
+
* bot.on('voice', handleVoice)
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
export function createVoiceHandler(config) {
|
|
320
|
+
return (ctx) => handleVoiceMessage(ctx, config);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Middleware to add voice handling to an existing bot
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* import { Telegraf } from 'telegraf'
|
|
328
|
+
* import { voiceMiddleware } from './telegram/voice.js'
|
|
329
|
+
*
|
|
330
|
+
* const bot = new Telegraf(process.env.BOT_TOKEN)
|
|
331
|
+
* bot.use(voiceMiddleware({
|
|
332
|
+
* botToken: process.env.BOT_TOKEN,
|
|
333
|
+
* whisperUrl: 'http://localhost:8080'
|
|
334
|
+
* }))
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
export function voiceMiddleware(config) {
|
|
338
|
+
return async (ctx, next) => {
|
|
339
|
+
if (ctx.message?.voice) {
|
|
340
|
+
await handleVoiceMessage(ctx, config);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
await next();
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// ============================================================================
|
|
348
|
+
// Exports
|
|
349
|
+
// ============================================================================
|
|
350
|
+
export { DEFAULT_CONFIG, WAV_SAMPLE_RATE, WAV_BITS_PER_SAMPLE, WAV_CHANNELS, };
|
|
351
|
+
//# sourceMappingURL=voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../src/telegram/voice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Registry Types
|
|
3
|
+
*/
|
|
4
|
+
export interface SkillMetadata {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
category: "core" | "catalog";
|
|
9
|
+
version: string;
|
|
10
|
+
size: number;
|
|
11
|
+
tags: string[];
|
|
12
|
+
url: string;
|
|
13
|
+
checksum: string;
|
|
14
|
+
dependencies?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface SkillRegistry {
|
|
17
|
+
version: string;
|
|
18
|
+
updated: string;
|
|
19
|
+
skills: Record<string, SkillMetadata>;
|
|
20
|
+
}
|
|
21
|
+
export interface InstalledSkill {
|
|
22
|
+
version: string;
|
|
23
|
+
installedAt: string;
|
|
24
|
+
source: "core" | "catalog";
|
|
25
|
+
}
|
|
26
|
+
export interface ProjectSkills {
|
|
27
|
+
installed: Record<string, InstalledSkill>;
|
|
28
|
+
registryUrl: string;
|
|
29
|
+
lastUpdate: string;
|
|
30
|
+
}
|
|
31
|
+
export interface SkillManifest {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
version: string;
|
|
35
|
+
description: string;
|
|
36
|
+
author: string;
|
|
37
|
+
license: string;
|
|
38
|
+
category: "core" | "catalog";
|
|
39
|
+
tags: string[];
|
|
40
|
+
files: string[];
|
|
41
|
+
dependencies: string[];
|
|
42
|
+
minJflVersion: string;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/types/skills.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/types/skills.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JFL Banner & Taglines
|
|
3
|
+
* Beautiful ASCII art banner with rotating taglines (Clawdbot-style)
|
|
4
|
+
*/
|
|
5
|
+
export declare function getTagline(): string;
|
|
6
|
+
export declare function getBannerArt(): string[];
|
|
7
|
+
export interface BannerOptions {
|
|
8
|
+
version?: string;
|
|
9
|
+
tagline?: string;
|
|
10
|
+
showTagline?: boolean;
|
|
11
|
+
centered?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function renderBanner(options?: BannerOptions): string;
|
|
14
|
+
export declare function showBanner(version?: string): void;
|
|
15
|
+
export declare function showStatus(message: string): void;
|
|
16
|
+
export declare function showSection(title: string): void;
|
|
17
|
+
export declare function showHowItWorksNotice(): void;
|
|
18
|
+
//# sourceMappingURL=banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiNH,wBAAgB,UAAU,IAAI,MAAM,CAMnC;AAED,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAWvC;AAmCD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAoDhE;AAMD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAEjD;AAGD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK/C;AAMD,wBAAgB,oBAAoB,IAAI,IAAI,CA2B3C"}
|