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.
Files changed (381) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -0
  3. package/clawdbot-skill/README.md +328 -0
  4. package/clawdbot-skill/SKILL.md +362 -0
  5. package/clawdbot-skill/index.ts +486 -0
  6. package/clawdbot-skill/package.json +28 -0
  7. package/clawdbot-skill/skill.json +28 -0
  8. package/dist/commands/agents.d.ts +5 -0
  9. package/dist/commands/agents.d.ts.map +1 -0
  10. package/dist/commands/agents.js +399 -0
  11. package/dist/commands/agents.js.map +1 -0
  12. package/dist/commands/context-hub.d.ts +12 -0
  13. package/dist/commands/context-hub.d.ts.map +1 -0
  14. package/dist/commands/context-hub.js +642 -0
  15. package/dist/commands/context-hub.js.map +1 -0
  16. package/dist/commands/deploy.d.ts +5 -0
  17. package/dist/commands/deploy.d.ts.map +1 -0
  18. package/dist/commands/deploy.js +370 -0
  19. package/dist/commands/deploy.js.map +1 -0
  20. package/dist/commands/feedback.d.ts +2 -0
  21. package/dist/commands/feedback.d.ts.map +1 -0
  22. package/dist/commands/feedback.js +178 -0
  23. package/dist/commands/feedback.js.map +1 -0
  24. package/dist/commands/hud.d.ts +4 -0
  25. package/dist/commands/hud.d.ts.map +1 -0
  26. package/dist/commands/hud.js +262 -0
  27. package/dist/commands/hud.js.map +1 -0
  28. package/dist/commands/init.d.ts +4 -0
  29. package/dist/commands/init.d.ts.map +1 -0
  30. package/dist/commands/init.js +553 -0
  31. package/dist/commands/init.js.map +1 -0
  32. package/dist/commands/login.d.ts +23 -0
  33. package/dist/commands/login.d.ts.map +1 -0
  34. package/dist/commands/login.js +818 -0
  35. package/dist/commands/login.js.map +1 -0
  36. package/dist/commands/ralph.d.ts +9 -0
  37. package/dist/commands/ralph.d.ts.map +1 -0
  38. package/dist/commands/ralph.js +67 -0
  39. package/dist/commands/ralph.js.map +1 -0
  40. package/dist/commands/repair.d.ts +7 -0
  41. package/dist/commands/repair.d.ts.map +1 -0
  42. package/dist/commands/repair.js +283 -0
  43. package/dist/commands/repair.js.map +1 -0
  44. package/dist/commands/session-mgmt.d.ts +33 -0
  45. package/dist/commands/session-mgmt.d.ts.map +1 -0
  46. package/dist/commands/session-mgmt.js +404 -0
  47. package/dist/commands/session-mgmt.js.map +1 -0
  48. package/dist/commands/session.d.ts +2 -0
  49. package/dist/commands/session.d.ts.map +1 -0
  50. package/dist/commands/session.js +639 -0
  51. package/dist/commands/session.js.map +1 -0
  52. package/dist/commands/skills.d.ts +31 -0
  53. package/dist/commands/skills.d.ts.map +1 -0
  54. package/dist/commands/skills.js +314 -0
  55. package/dist/commands/skills.js.map +1 -0
  56. package/dist/commands/status.d.ts +2 -0
  57. package/dist/commands/status.d.ts.map +1 -0
  58. package/dist/commands/status.js +127 -0
  59. package/dist/commands/status.js.map +1 -0
  60. package/dist/commands/synopsis.d.ts +10 -0
  61. package/dist/commands/synopsis.d.ts.map +1 -0
  62. package/dist/commands/synopsis.js +277 -0
  63. package/dist/commands/synopsis.js.map +1 -0
  64. package/dist/commands/update.d.ts +10 -0
  65. package/dist/commands/update.d.ts.map +1 -0
  66. package/dist/commands/update.js +165 -0
  67. package/dist/commands/update.js.map +1 -0
  68. package/dist/commands/voice.d.ts +410 -0
  69. package/dist/commands/voice.d.ts.map +1 -0
  70. package/dist/commands/voice.js +4763 -0
  71. package/dist/commands/voice.js.map +1 -0
  72. package/dist/index.d.ts +9 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +512 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/mcp/context-hub-mcp.d.ts +11 -0
  77. package/dist/mcp/context-hub-mcp.d.ts.map +1 -0
  78. package/dist/mcp/context-hub-mcp.js +548 -0
  79. package/dist/mcp/context-hub-mcp.js.map +1 -0
  80. package/dist/telegram/voice.d.ts +146 -0
  81. package/dist/telegram/voice.d.ts.map +1 -0
  82. package/dist/telegram/voice.js +351 -0
  83. package/dist/telegram/voice.js.map +1 -0
  84. package/dist/types/skills.d.ts +44 -0
  85. package/dist/types/skills.d.ts.map +1 -0
  86. package/dist/types/skills.js +5 -0
  87. package/dist/types/skills.js.map +1 -0
  88. package/dist/ui/banner.d.ts +18 -0
  89. package/dist/ui/banner.d.ts.map +1 -0
  90. package/dist/ui/banner.js +323 -0
  91. package/dist/ui/banner.js.map +1 -0
  92. package/dist/ui/index.d.ts +8 -0
  93. package/dist/ui/index.d.ts.map +1 -0
  94. package/dist/ui/index.js +8 -0
  95. package/dist/ui/index.js.map +1 -0
  96. package/dist/ui/prompts.d.ts +52 -0
  97. package/dist/ui/prompts.d.ts.map +1 -0
  98. package/dist/ui/prompts.js +72 -0
  99. package/dist/ui/prompts.js.map +1 -0
  100. package/dist/ui/theme.d.ts +82 -0
  101. package/dist/ui/theme.d.ts.map +1 -0
  102. package/dist/ui/theme.js +142 -0
  103. package/dist/ui/theme.js.map +1 -0
  104. package/dist/utils/auth-guard.d.ts +66 -0
  105. package/dist/utils/auth-guard.d.ts.map +1 -0
  106. package/dist/utils/auth-guard.js +348 -0
  107. package/dist/utils/auth-guard.js.map +1 -0
  108. package/dist/utils/ensure-project.d.ts +11 -0
  109. package/dist/utils/ensure-project.d.ts.map +1 -0
  110. package/dist/utils/ensure-project.js +70 -0
  111. package/dist/utils/ensure-project.js.map +1 -0
  112. package/dist/utils/git.d.ts +73 -0
  113. package/dist/utils/git.d.ts.map +1 -0
  114. package/dist/utils/git.js +219 -0
  115. package/dist/utils/git.js.map +1 -0
  116. package/dist/utils/github-auth.d.ts +54 -0
  117. package/dist/utils/github-auth.d.ts.map +1 -0
  118. package/dist/utils/github-auth.js +375 -0
  119. package/dist/utils/github-auth.js.map +1 -0
  120. package/dist/utils/github-repo.d.ts +30 -0
  121. package/dist/utils/github-repo.d.ts.map +1 -0
  122. package/dist/utils/github-repo.js +219 -0
  123. package/dist/utils/github-repo.js.map +1 -0
  124. package/dist/utils/platform-auth.d.ts +81 -0
  125. package/dist/utils/platform-auth.d.ts.map +1 -0
  126. package/dist/utils/platform-auth.js +191 -0
  127. package/dist/utils/platform-auth.js.map +1 -0
  128. package/dist/utils/project-config.d.ts +43 -0
  129. package/dist/utils/project-config.d.ts.map +1 -0
  130. package/dist/utils/project-config.js +97 -0
  131. package/dist/utils/project-config.js.map +1 -0
  132. package/dist/utils/skill-registry.d.ts +49 -0
  133. package/dist/utils/skill-registry.d.ts.map +1 -0
  134. package/dist/utils/skill-registry.js +192 -0
  135. package/dist/utils/skill-registry.js.map +1 -0
  136. package/dist/utils/wallet.d.ts +62 -0
  137. package/dist/utils/wallet.d.ts.map +1 -0
  138. package/dist/utils/wallet.js +252 -0
  139. package/dist/utils/wallet.js.map +1 -0
  140. package/dist/utils/x402-client.d.ts +86 -0
  141. package/dist/utils/x402-client.d.ts.map +1 -0
  142. package/dist/utils/x402-client.js +265 -0
  143. package/dist/utils/x402-client.js.map +1 -0
  144. package/package.json +76 -0
  145. package/scripts/postinstall.js +116 -0
  146. package/scripts/test-onboarding.sh +121 -0
  147. package/scripts/voice-start.sh +128 -0
  148. package/scripts/voice-stop.sh +33 -0
  149. package/template/.claude/settings.json +92 -0
  150. package/template/.claude/skills/agent-browser/SKILL.md +116 -0
  151. package/template/.claude/skills/brand-architect/SKILL.md +240 -0
  152. package/template/.claude/skills/brand-architect/config.yaml +137 -0
  153. package/template/.claude/skills/campaign-hud/config.yaml +112 -0
  154. package/template/.claude/skills/content-creator/SKILL.md +294 -0
  155. package/template/.claude/skills/debug/MULTI_AGENT.md +360 -0
  156. package/template/.claude/skills/debug/SKILL.md +549 -0
  157. package/template/.claude/skills/fly-deploy/SKILL.md +676 -0
  158. package/template/.claude/skills/founder-video/SKILL.md +467 -0
  159. package/template/.claude/skills/hud/SKILL.md +157 -0
  160. package/template/.claude/skills/ralph-tui/SKILL.md +210 -0
  161. package/template/.claude/skills/react-best-practices/AGENTS.md +2249 -0
  162. package/template/.claude/skills/react-best-practices/README.md +123 -0
  163. package/template/.claude/skills/react-best-practices/SKILL.md +125 -0
  164. package/template/.claude/skills/react-best-practices/metadata.json +15 -0
  165. package/template/.claude/skills/react-best-practices/rules/_sections.md +46 -0
  166. package/template/.claude/skills/react-best-practices/rules/_template.md +28 -0
  167. package/template/.claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  168. package/template/.claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  169. package/template/.claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  170. package/template/.claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  171. package/template/.claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  172. package/template/.claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  173. package/template/.claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  174. package/template/.claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  175. package/template/.claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  176. package/template/.claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  177. package/template/.claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  178. package/template/.claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  179. package/template/.claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  180. package/template/.claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  181. package/template/.claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  182. package/template/.claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  183. package/template/.claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  184. package/template/.claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  185. package/template/.claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  186. package/template/.claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  187. package/template/.claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  188. package/template/.claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  189. package/template/.claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  190. package/template/.claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  191. package/template/.claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  192. package/template/.claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  193. package/template/.claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  194. package/template/.claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  195. package/template/.claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  196. package/template/.claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  197. package/template/.claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  198. package/template/.claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  199. package/template/.claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  200. package/template/.claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  201. package/template/.claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  202. package/template/.claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  203. package/template/.claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  204. package/template/.claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  205. package/template/.claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  206. package/template/.claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  207. package/template/.claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  208. package/template/.claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  209. package/template/.claude/skills/react-best-practices/rules/server-cache-react.md +26 -0
  210. package/template/.claude/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  211. package/template/.claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  212. package/template/.claude/skills/remotion-best-practices/SKILL.md +43 -0
  213. package/template/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
  214. package/template/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
  215. package/template/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  216. package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  217. package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  218. package/template/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
  219. package/template/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
  220. package/template/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  221. package/template/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
  222. package/template/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
  223. package/template/.claude/skills/remotion-best-practices/rules/compositions.md +146 -0
  224. package/template/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
  225. package/template/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  226. package/template/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
  227. package/template/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  228. package/template/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  229. package/template/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  230. package/template/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
  231. package/template/.claude/skills/remotion-best-practices/rules/images.md +130 -0
  232. package/template/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  233. package/template/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
  234. package/template/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  235. package/template/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  236. package/template/.claude/skills/remotion-best-practices/rules/sequencing.md +106 -0
  237. package/template/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
  238. package/template/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
  239. package/template/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
  240. package/template/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  241. package/template/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
  242. package/template/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
  243. package/template/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
  244. package/template/.claude/skills/search/SKILL.md +220 -0
  245. package/template/.claude/skills/spec/SKILL.md +377 -0
  246. package/template/.claude/skills/startup/SKILL.md +310 -0
  247. package/template/.claude/skills/web-architect/SKILL.md +309 -0
  248. package/template/.claude/skills/x-algorithm/SKILL.md +305 -0
  249. package/template/.jfl/config.json +8 -0
  250. package/template/.mcp.json +11 -0
  251. package/template/CLAUDE.md +960 -0
  252. package/template/content/.gitkeep +0 -0
  253. package/template/context-hub +3 -0
  254. package/template/knowledge/BRAND_BRIEF.md +124 -0
  255. package/template/knowledge/BRAND_DECISIONS.md +168 -0
  256. package/template/knowledge/NARRATIVE.md +114 -0
  257. package/template/knowledge/ROADMAP.md +128 -0
  258. package/template/knowledge/THESIS.md +108 -0
  259. package/template/knowledge/VISION.md +74 -0
  260. package/template/knowledge/VOICE_AND_TONE.md +146 -0
  261. package/template/previews/.gitkeep +0 -0
  262. package/template/scripts/session/auto-commit.sh +245 -0
  263. package/template/scripts/session/auto-merge.sh +325 -0
  264. package/template/scripts/session/jfl-doctor.sh +587 -0
  265. package/template/scripts/session/session-end.sh +194 -0
  266. package/template/scripts/session/session-init.sh +163 -0
  267. package/template/scripts/session/session-sync.sh +167 -0
  268. package/template/scripts/session/test-context-preservation.sh +160 -0
  269. package/template/skills/agent-browser/SKILL.md +116 -0
  270. package/template/skills/brand-architect/SKILL.md +240 -0
  271. package/template/skills/brand-architect/config.yaml +137 -0
  272. package/template/skills/campaign-hud/config.yaml +112 -0
  273. package/template/skills/content-creator/SKILL.md +294 -0
  274. package/template/skills/debug/MULTI_AGENT.md +360 -0
  275. package/template/skills/debug/SKILL.md +549 -0
  276. package/template/skills/fly-deploy/SKILL.md +676 -0
  277. package/template/skills/founder-video/SKILL.md +467 -0
  278. package/template/skills/hud/SKILL.md +204 -0
  279. package/template/skills/ralph-tui/SKILL.md +210 -0
  280. package/template/skills/react-best-practices/AGENTS.md +2249 -0
  281. package/template/skills/react-best-practices/README.md +123 -0
  282. package/template/skills/react-best-practices/SKILL.md +125 -0
  283. package/template/skills/react-best-practices/metadata.json +15 -0
  284. package/template/skills/react-best-practices/rules/_sections.md +46 -0
  285. package/template/skills/react-best-practices/rules/_template.md +28 -0
  286. package/template/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  287. package/template/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  288. package/template/skills/react-best-practices/rules/async-api-routes.md +38 -0
  289. package/template/skills/react-best-practices/rules/async-defer-await.md +80 -0
  290. package/template/skills/react-best-practices/rules/async-dependencies.md +36 -0
  291. package/template/skills/react-best-practices/rules/async-parallel.md +28 -0
  292. package/template/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  293. package/template/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  294. package/template/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  295. package/template/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  296. package/template/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  297. package/template/skills/react-best-practices/rules/bundle-preload.md +50 -0
  298. package/template/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  299. package/template/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  300. package/template/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  301. package/template/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  302. package/template/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  303. package/template/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  304. package/template/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  305. package/template/skills/react-best-practices/rules/js-early-exit.md +50 -0
  306. package/template/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  307. package/template/skills/react-best-practices/rules/js-index-maps.md +37 -0
  308. package/template/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  309. package/template/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  310. package/template/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  311. package/template/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  312. package/template/skills/react-best-practices/rules/rendering-activity.md +26 -0
  313. package/template/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  314. package/template/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  315. package/template/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  316. package/template/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  317. package/template/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  318. package/template/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  319. package/template/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  320. package/template/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  321. package/template/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  322. package/template/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  323. package/template/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  324. package/template/skills/react-best-practices/rules/rerender-memo.md +44 -0
  325. package/template/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  326. package/template/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  327. package/template/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  328. package/template/skills/react-best-practices/rules/server-cache-react.md +26 -0
  329. package/template/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  330. package/template/skills/react-best-practices/rules/server-serialization.md +38 -0
  331. package/template/skills/remotion-best-practices/SKILL.md +43 -0
  332. package/template/skills/remotion-best-practices/rules/3d.md +86 -0
  333. package/template/skills/remotion-best-practices/rules/animations.md +29 -0
  334. package/template/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  335. package/template/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  336. package/template/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  337. package/template/skills/remotion-best-practices/rules/assets.md +78 -0
  338. package/template/skills/remotion-best-practices/rules/audio.md +172 -0
  339. package/template/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  340. package/template/skills/remotion-best-practices/rules/can-decode.md +75 -0
  341. package/template/skills/remotion-best-practices/rules/charts.md +58 -0
  342. package/template/skills/remotion-best-practices/rules/compositions.md +146 -0
  343. package/template/skills/remotion-best-practices/rules/display-captions.md +126 -0
  344. package/template/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  345. package/template/skills/remotion-best-practices/rules/fonts.md +152 -0
  346. package/template/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  347. package/template/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  348. package/template/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  349. package/template/skills/remotion-best-practices/rules/gifs.md +138 -0
  350. package/template/skills/remotion-best-practices/rules/images.md +130 -0
  351. package/template/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  352. package/template/skills/remotion-best-practices/rules/lottie.md +68 -0
  353. package/template/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  354. package/template/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  355. package/template/skills/remotion-best-practices/rules/sequencing.md +106 -0
  356. package/template/skills/remotion-best-practices/rules/tailwind.md +11 -0
  357. package/template/skills/remotion-best-practices/rules/text-animations.md +20 -0
  358. package/template/skills/remotion-best-practices/rules/timing.md +179 -0
  359. package/template/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  360. package/template/skills/remotion-best-practices/rules/transitions.md +122 -0
  361. package/template/skills/remotion-best-practices/rules/trimming.md +53 -0
  362. package/template/skills/remotion-best-practices/rules/videos.md +171 -0
  363. package/template/skills/search/SKILL.md +220 -0
  364. package/template/skills/spec/SKILL.md +377 -0
  365. package/template/skills/startup/SKILL.md +310 -0
  366. package/template/skills/web-architect/SKILL.md +309 -0
  367. package/template/skills/x-algorithm/SKILL.md +305 -0
  368. package/template/suggestions/.gitkeep +0 -0
  369. package/template/templates/QUICKSTART_SKILL_TO_PRODUCT.md +242 -0
  370. package/template/templates/brand/BRAND_BRIEF.md +124 -0
  371. package/template/templates/brand/BRAND_DECISIONS.md +168 -0
  372. package/template/templates/brand/BRAND_GUIDELINES.md +251 -0
  373. package/template/templates/brand/VOICE_AND_TONE.md +146 -0
  374. package/template/templates/brand/global.css +240 -0
  375. package/template/templates/collaboration/CONTRIBUTOR.md +74 -0
  376. package/template/templates/collaboration/CRM.md +97 -0
  377. package/template/templates/collaboration/TASKS.md +83 -0
  378. package/template/templates/strategic/NARRATIVE.md +114 -0
  379. package/template/templates/strategic/ROADMAP.md +128 -0
  380. package/template/templates/strategic/THESIS.md +108 -0
  381. 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,5 @@
1
+ /**
2
+ * Skill Registry Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=skills.js.map
@@ -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"}