vybekiit 0.7.28 → 0.7.32

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 (352) hide show
  1. package/dist/bin.js +17286 -17351
  2. package/dist/global-guidance/language.md +13 -108
  3. package/dist/global-skills/add-ai/SKILL.md +13 -8
  4. package/dist/global-skills/add-analytics/SKILL.md +10 -7
  5. package/dist/global-skills/add-app-clip/SKILL.md +1 -0
  6. package/dist/global-skills/add-blog/SKILL.md +10 -7
  7. package/dist/global-skills/add-crud/SKILL.md +8 -0
  8. package/dist/global-skills/add-files/SKILL.md +10 -7
  9. package/dist/global-skills/add-images/SKILL.md +10 -7
  10. package/dist/global-skills/add-language/SKILL.md +11 -8
  11. package/dist/global-skills/add-notifications/SKILL.md +10 -7
  12. package/dist/global-skills/add-realtime/SKILL.md +10 -7
  13. package/dist/global-skills/add-route/SKILL.md +6 -0
  14. package/dist/global-skills/add-search/SKILL.md +10 -7
  15. package/dist/global-skills/add-signin/SKILL.md +10 -8
  16. package/dist/global-skills/add-teams/SKILL.md +14 -10
  17. package/dist/global-skills/add-upload/SKILL.md +6 -0
  18. package/dist/global-skills/aws-cdk/SKILL.md +1 -0
  19. package/dist/global-skills/aws-cloudformation/SKILL.md +1 -0
  20. package/dist/global-skills/aws-serverless/SKILL.md +1 -0
  21. package/dist/global-skills/aws-serverless/references/compute-decision-edge-cases.md +77 -0
  22. package/dist/global-skills/back-up-my-code/SKILL.md +16 -5
  23. package/dist/global-skills/better-auth-best-practices/SKILL.md +1 -0
  24. package/dist/global-skills/better-auth-security-best-practices/SKILL.md +1 -0
  25. package/dist/global-skills/building-native-ui/SKILL.md +1 -0
  26. package/dist/global-skills/buy-domain/SKILL.md +10 -7
  27. package/dist/global-skills/check-safety/SKILL.md +11 -8
  28. package/dist/global-skills/claimable-postgres/SKILL.md +1 -0
  29. package/dist/global-skills/configure-capabilities/SKILL.md +7 -1
  30. package/dist/global-skills/connect-account/SKILL.md +7 -1
  31. package/dist/global-skills/connect-account-backend/SKILL.md +6 -0
  32. package/dist/global-skills/create-auth-skill/SKILL.md +1 -0
  33. package/dist/global-skills/design-my-data/SKILL.md +12 -5
  34. package/dist/global-skills/doctor/SKILL.md +17 -10
  35. package/dist/global-skills/eas-app-stores/SKILL.md +2 -1
  36. package/dist/global-skills/eas-app-stores/agents/openai.yaml +1 -1
  37. package/dist/global-skills/eas-hosting/SKILL.md +2 -1
  38. package/dist/global-skills/eas-hosting/agents/openai.yaml +1 -1
  39. package/dist/global-skills/eas-observe/SKILL.md +2 -1
  40. package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
  41. package/dist/global-skills/eas-simulator/SKILL.md +9 -1
  42. package/dist/global-skills/eas-simulator/agents/openai.yaml +1 -1
  43. package/dist/global-skills/eas-simulator/references/logs-and-crashes.md +101 -0
  44. package/dist/global-skills/eas-simulator/references/troubleshooting.md +4 -0
  45. package/dist/global-skills/eas-update/SKILL.md +2 -1
  46. package/dist/global-skills/eas-update/agents/openai.yaml +1 -1
  47. package/dist/global-skills/eas-update-insights/SKILL.md +2 -1
  48. package/dist/global-skills/eas-update-insights/agents/openai.yaml +1 -1
  49. package/dist/global-skills/eas-workflows/SKILL.md +2 -1
  50. package/dist/global-skills/eas-workflows/agents/openai.yaml +1 -1
  51. package/dist/global-skills/email-best-practices/SKILL.md +1 -0
  52. package/dist/global-skills/expo-animation/SKILL.md +2 -1
  53. package/dist/global-skills/expo-api-routes/SKILL.md +1 -0
  54. package/dist/global-skills/expo-app-clip/SKILL.md +2 -1
  55. package/dist/global-skills/expo-brownfield/SKILL.md +2 -1
  56. package/dist/global-skills/expo-cicd-workflows/SKILL.md +1 -0
  57. package/dist/global-skills/expo-data-fetching/SKILL.md +2 -1
  58. package/dist/global-skills/expo-deployment/SKILL.md +1 -0
  59. package/dist/global-skills/expo-design-system/SKILL.md +2 -1
  60. package/dist/global-skills/expo-dev-client/SKILL.md +2 -1
  61. package/dist/global-skills/expo-dom/SKILL.md +2 -1
  62. package/dist/global-skills/expo-examples/SKILL.md +2 -1
  63. package/dist/global-skills/expo-migrate-module/SKILL.md +2 -1
  64. package/dist/global-skills/expo-module/SKILL.md +2 -1
  65. package/dist/global-skills/expo-native-ui/SKILL.md +2 -1
  66. package/dist/global-skills/expo-observe/SKILL.md +1 -0
  67. package/dist/global-skills/expo-overview/SKILL.md +2 -1
  68. package/dist/global-skills/expo-project-structure/SKILL.md +2 -1
  69. package/dist/global-skills/expo-router/SKILL.md +2 -1
  70. package/dist/global-skills/expo-skill-eval/SKILL.md +1 -0
  71. package/dist/global-skills/expo-skill-feedback/SKILL.md +1 -0
  72. package/dist/global-skills/expo-tailwind-setup/SKILL.md +1 -0
  73. package/dist/global-skills/expo-ui/SKILL.md +2 -1
  74. package/dist/global-skills/expo-upgrade/SKILL.md +2 -1
  75. package/dist/global-skills/expo-web-to-native/SKILL.md +2 -1
  76. package/dist/global-skills/extension-to-functions-codebase/SKILL.md +1 -0
  77. package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +1 -0
  78. package/dist/global-skills/firebase-ai-logic-basics/references/tts_generation.md +676 -0
  79. package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +1 -0
  80. package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
  81. package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +61 -23
  82. package/dist/global-skills/firebase-basics/SKILL.md +2 -0
  83. package/dist/global-skills/firebase-basics/references/android_setup.md +165 -23
  84. package/dist/global-skills/firebase-crashlytics/SKILL.md +1 -0
  85. package/dist/global-skills/firebase-crashlytics/references/android_setup.md +147 -119
  86. package/dist/global-skills/firebase-data-connect/SKILL.md +1 -0
  87. package/dist/global-skills/firebase-data-connect/reference/sdk_android.md +81 -25
  88. package/dist/global-skills/firebase-firestore/SKILL.md +1 -0
  89. package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +70 -44
  90. package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +63 -27
  91. package/dist/global-skills/firebase-hosting-basics/SKILL.md +1 -0
  92. package/dist/global-skills/firebase-remote-config-basics/SKILL.md +1 -0
  93. package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +87 -95
  94. package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +1 -0
  95. package/dist/global-skills/firestore-rules-creation/SKILL.md +1 -0
  96. package/dist/global-skills/go-live/SKILL.md +13 -7
  97. package/dist/global-skills/harden/SKILL.md +15 -10
  98. package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
  99. package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -0
  100. package/dist/global-skills/manifest.json +5 -1
  101. package/dist/global-skills/mongodb-atlas-stream-processing/SKILL.md +1 -0
  102. package/dist/global-skills/mongodb-connection/SKILL.md +1 -0
  103. package/dist/global-skills/mongodb-mcp-setup/SKILL.md +1 -0
  104. package/dist/global-skills/mongodb-natural-language-querying/SKILL.md +1 -0
  105. package/dist/global-skills/mongodb-qe-size-estimation/SKILL.md +224 -0
  106. package/dist/global-skills/mongodb-query-optimizer/SKILL.md +1 -0
  107. package/dist/global-skills/mongodb-schema-design/SKILL.md +1 -0
  108. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +1 -0
  109. package/dist/global-skills/native-data-fetching/SKILL.md +1 -0
  110. package/dist/global-skills/neon/SKILL.md +18 -5
  111. package/dist/global-skills/neon-ai-gateway/SKILL.md +1 -0
  112. package/dist/global-skills/neon-auth/SKILL.md +1 -0
  113. package/dist/global-skills/neon-functions/SKILL.md +12 -0
  114. package/dist/global-skills/neon-functions/references/native-binaries.md +188 -0
  115. package/dist/global-skills/neon-object-storage/SKILL.md +1 -0
  116. package/dist/global-skills/neon-postgres/SKILL.md +1 -0
  117. package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -0
  118. package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -0
  119. package/dist/global-skills/onboarding/SKILL.md +46 -29
  120. package/dist/global-skills/plan-my-idea/SKILL.md +7 -1
  121. package/dist/global-skills/publish-app/SKILL.md +7 -1
  122. package/dist/global-skills/publish-extension/SKILL.md +7 -1
  123. package/dist/global-skills/resend/SKILL.md +2 -1
  124. package/dist/global-skills/resend/references/webhooks.md +2 -0
  125. package/dist/global-skills/reset-password/SKILL.md +10 -6
  126. package/dist/global-skills/save-data/SKILL.md +51 -16
  127. package/dist/global-skills/sentry-sdk-setup/SKILL.md +1 -0
  128. package/dist/global-skills/sentry-workflow/SKILL.md +1 -0
  129. package/dist/global-skills/setup-email/SKILL.md +13 -8
  130. package/dist/global-skills/setup-payments/SKILL.md +19 -15
  131. package/dist/global-skills/setup-sms/SKILL.md +7 -1
  132. package/dist/global-skills/sign-in-with-email-link/SKILL.md +10 -6
  133. package/dist/global-skills/sign-in-with-google/SKILL.md +20 -13
  134. package/dist/global-skills/sign-in-with-phone/SKILL.md +11 -7
  135. package/dist/global-skills/stripe-best-practices/SKILL.md +2 -1
  136. package/dist/global-skills/stripe-best-practices/references/billing.md +2 -0
  137. package/dist/global-skills/stripe-best-practices/references/payments.md +1 -1
  138. package/dist/global-skills/stripe-best-practices/references/tax.md +2 -2
  139. package/dist/global-skills/supabase/CHANGELOG.md +19 -0
  140. package/dist/global-skills/supabase/SKILL.md +1 -0
  141. package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -0
  142. package/dist/global-skills/track-errors/SKILL.md +18 -13
  143. package/dist/global-skills/update-kit/SKILL.md +7 -1
  144. package/dist/global-skills/upgrading-expo/SKILL.md +1 -0
  145. package/dist/global-skills/use-dom/SKILL.md +1 -0
  146. package/dist/global-skills/use-railway/SKILL.md +6 -5
  147. package/dist/global-skills/use-railway/references/configure.md +34 -1
  148. package/dist/global-skills/use-railway/references/iac.md +2 -0
  149. package/dist/global-skills/use-railway/references/tracing.md +89 -44
  150. package/dist/global-skills/validate-my-idea/SKILL.md +6 -0
  151. package/dist/global-skills/vercel-composition-patterns/SKILL.md +1 -0
  152. package/dist/global-skills/vercel-react-best-practices/SKILL.md +1 -0
  153. package/dist/global-skills/vybekiit-feedback/SKILL.md +6 -0
  154. package/dist/global-skills/vybekiitReferences/backend/AGENTS.md +50 -0
  155. package/dist/global-skills/vybekiitReferences/backend/agent/goal-index.md +17 -0
  156. package/dist/global-skills/vybekiitReferences/backend/agent/goal-routes.json +229 -0
  157. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-agent.json +12 -0
  158. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-firebase.json +8 -0
  159. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-mongodb.json +12 -0
  160. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-neon.json +8 -0
  161. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-paypal.json +8 -0
  162. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-posthog.json +17 -0
  163. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-railway-local.json +8 -0
  164. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-railway-remote.json +7 -0
  165. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-sentry.json +7 -0
  166. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-setup.md +140 -0
  167. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-supabase.json +7 -0
  168. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-twilio-alpha.json +8 -0
  169. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-twilio-docs.json +7 -0
  170. package/dist/global-skills/vybekiitReferences/backend/agent/session-bootstrap.md +44 -0
  171. package/dist/global-skills/vybekiitReferences/backend/agent/tech-references.md +28 -0
  172. package/dist/global-skills/vybekiitReferences/backend/language.md +345 -0
  173. package/dist/global-skills/vybekiitReferences/backend/platform-skills/deploy-railway-vybekiit.md +26 -0
  174. package/dist/global-skills/vybekiitReferences/backend/platform-skills/extend-capabilities-vybekiit.md +127 -0
  175. package/dist/global-skills/vybekiitReferences/backend/platform-skills/mcp-tools-vybekiit.md +87 -0
  176. package/dist/global-skills/vybekiitReferences/backend/platform-skills/mongodb-vybekiit.md +34 -0
  177. package/dist/global-skills/vybekiitReferences/backend/platform-skills/railway-postgres-vybekiit.md +24 -0
  178. package/dist/global-skills/vybekiitReferences/extension/AGENTS.md +88 -0
  179. package/dist/global-skills/vybekiitReferences/extension/agent/goal-index.md +27 -0
  180. package/dist/global-skills/vybekiitReferences/extension/agent/goal-routes.json +239 -0
  181. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-agent.json +14 -0
  182. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-posthog.json +17 -0
  183. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-sentry.json +7 -0
  184. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-setup.md +111 -0
  185. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-twilio-alpha.json +13 -0
  186. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-twilio-docs.json +7 -0
  187. package/dist/global-skills/vybekiitReferences/extension/agent/session-bootstrap.md +44 -0
  188. package/dist/global-skills/vybekiitReferences/extension/agent/tech-references.md +28 -0
  189. package/dist/global-skills/vybekiitReferences/extension/agent/ui-sources.md +33 -0
  190. package/dist/global-skills/vybekiitReferences/extension/language.md +348 -0
  191. package/dist/global-skills/vybekiitReferences/extension/platform-skills/README.md +32 -0
  192. package/dist/global-skills/vybekiitReferences/extension/platform-skills/browser-automation-vybekiit.md +44 -0
  193. package/dist/global-skills/vybekiitReferences/extension/platform-skills/chrome-extension-vybekiit.md +28 -0
  194. package/dist/global-skills/vybekiitReferences/extension/platform-skills/ci-vybekiit.md +26 -0
  195. package/dist/global-skills/vybekiitReferences/extension/platform-skills/client-state-vybekiit.md +25 -0
  196. package/dist/global-skills/vybekiitReferences/extension/platform-skills/code-hygiene-vybekiit.md +38 -0
  197. package/dist/global-skills/vybekiitReferences/extension/platform-skills/data-model-vybekiit.md +29 -0
  198. package/dist/global-skills/vybekiitReferences/extension/platform-skills/env-secrets-vybekiit.md +21 -0
  199. package/dist/global-skills/vybekiitReferences/extension/platform-skills/extend-capabilities-vybekiit.md +127 -0
  200. package/dist/global-skills/vybekiitReferences/extension/platform-skills/format-lint-vybekiit.md +33 -0
  201. package/dist/global-skills/vybekiitReferences/extension/platform-skills/github-vybekiit.md +47 -0
  202. package/dist/global-skills/vybekiitReferences/extension/platform-skills/i18n-vybekiit.md +39 -0
  203. package/dist/global-skills/vybekiitReferences/extension/platform-skills/mcp-tools-vybekiit.md +87 -0
  204. package/dist/global-skills/vybekiitReferences/extension/platform-skills/observability-vybekiit.md +36 -0
  205. package/dist/global-skills/vybekiitReferences/extension/platform-skills/planning-vybekiit.md +59 -0
  206. package/dist/global-skills/vybekiitReferences/extension/platform-skills/playwright-vybekiit.md +42 -0
  207. package/dist/global-skills/vybekiitReferences/extension/platform-skills/react-patterns-vybekiit.md +45 -0
  208. package/dist/global-skills/vybekiitReferences/extension/platform-skills/responsive-vybekiit.md +27 -0
  209. package/dist/global-skills/vybekiitReferences/extension/platform-skills/sentry-vybekiit.md +33 -0
  210. package/dist/global-skills/vybekiitReferences/extension/platform-skills/ship-via-pr-vybekiit.md +49 -0
  211. package/dist/global-skills/vybekiitReferences/extension/platform-skills/testing-vybekiit.md +33 -0
  212. package/dist/global-skills/vybekiitReferences/extension/platform-skills/ui-consistency-vybekiit.md +33 -0
  213. package/dist/global-skills/vybekiitReferences/mobile/AGENTS.md +475 -0
  214. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-index.md +32 -0
  215. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-routes.json +279 -0
  216. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-agent.json +14 -0
  217. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-firebase.json +8 -0
  218. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-neon.json +8 -0
  219. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-paypal.json +8 -0
  220. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-posthog.json +17 -0
  221. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-sentry.json +7 -0
  222. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-setup.md +112 -0
  223. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-stripe.json +7 -0
  224. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-supabase.json +7 -0
  225. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-twilio-alpha.json +13 -0
  226. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-twilio-docs.json +7 -0
  227. package/dist/global-skills/vybekiitReferences/mobile/agent/session-bootstrap.md +44 -0
  228. package/dist/global-skills/vybekiitReferences/mobile/agent/tech-references.md +28 -0
  229. package/dist/global-skills/vybekiitReferences/mobile/agent/ui-catalog-index.mobile.json +36294 -0
  230. package/dist/global-skills/vybekiitReferences/mobile/agent/ui-sources.mobile.md +36 -0
  231. package/dist/global-skills/vybekiitReferences/mobile/language.md +352 -0
  232. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/README.md +43 -0
  233. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ci-vybekiit.md +26 -0
  234. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/client-state-vybekiit.md +25 -0
  235. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/code-hygiene-vybekiit.md +38 -0
  236. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/data-model-vybekiit.md +29 -0
  237. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/env-secrets-vybekiit.md +21 -0
  238. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/extend-capabilities-vybekiit.md +127 -0
  239. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/format-lint-vybekiit.md +33 -0
  240. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/github-vybekiit.md +47 -0
  241. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/i18n-vybekiit.md +41 -0
  242. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/launch-store-vybekiit.md +26 -0
  243. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/mcp-tools-vybekiit.md +87 -0
  244. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/observability-vybekiit.md +36 -0
  245. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/planning-vybekiit.md +59 -0
  246. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/playwright-vybekiit.md +42 -0
  247. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/react-patterns-vybekiit.md +45 -0
  248. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/sentry-vybekiit.md +33 -0
  249. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ship-via-pr-vybekiit.md +49 -0
  250. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/testing-vybekiit.md +33 -0
  251. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ui-consistency-vybekiit.md +33 -0
  252. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ui-port-from-web-vybekiit.md +44 -0
  253. package/dist/global-skills/vybekiitReferences/spa/AGENTS.md +91 -0
  254. package/dist/global-skills/vybekiitReferences/spa/agent/goal-index.md +30 -0
  255. package/dist/global-skills/vybekiitReferences/spa/agent/goal-routes.json +267 -0
  256. package/dist/global-skills/vybekiitReferences/spa/agent/mcp-agent.json +14 -0
  257. package/dist/global-skills/vybekiitReferences/spa/agent/mcp-setup.md +63 -0
  258. package/dist/global-skills/vybekiitReferences/spa/agent/session-bootstrap.md +44 -0
  259. package/dist/global-skills/vybekiitReferences/spa/agent/ui-sources.md +63 -0
  260. package/dist/global-skills/vybekiitReferences/spa/language.md +217 -0
  261. package/dist/global-skills/vybekiitReferences/spa/platform-skills/mcp-tools-vybekiit.md +87 -0
  262. package/dist/global-skills/vybekiitReferences/web/AGENTS.md +138 -0
  263. package/dist/global-skills/vybekiitReferences/web/agent/goal-index.md +54 -0
  264. package/dist/global-skills/vybekiitReferences/web/agent/goal-routes.json +366 -0
  265. package/dist/global-skills/vybekiitReferences/web/agent/mcp-agent.json +14 -0
  266. package/dist/global-skills/vybekiitReferences/web/agent/mcp-firebase.json +8 -0
  267. package/dist/global-skills/vybekiitReferences/web/agent/mcp-mongodb.json +12 -0
  268. package/dist/global-skills/vybekiitReferences/web/agent/mcp-neon.json +8 -0
  269. package/dist/global-skills/vybekiitReferences/web/agent/mcp-paypal.json +8 -0
  270. package/dist/global-skills/vybekiitReferences/web/agent/mcp-posthog.json +17 -0
  271. package/dist/global-skills/vybekiitReferences/web/agent/mcp-railway-local.json +8 -0
  272. package/dist/global-skills/vybekiitReferences/web/agent/mcp-railway-remote.json +7 -0
  273. package/dist/global-skills/vybekiitReferences/web/agent/mcp-sentry.json +7 -0
  274. package/dist/global-skills/vybekiitReferences/web/agent/mcp-setup.md +174 -0
  275. package/dist/global-skills/vybekiitReferences/web/agent/mcp-stripe.json +7 -0
  276. package/dist/global-skills/vybekiitReferences/web/agent/mcp-supabase.json +7 -0
  277. package/dist/global-skills/vybekiitReferences/web/agent/mcp-twilio-alpha.json +13 -0
  278. package/dist/global-skills/vybekiitReferences/web/agent/mcp-twilio-docs.json +7 -0
  279. package/dist/global-skills/vybekiitReferences/web/agent/session-bootstrap.md +44 -0
  280. package/dist/global-skills/vybekiitReferences/web/agent/tech-references.md +28 -0
  281. package/dist/global-skills/vybekiitReferences/web/agent/ui-catalog-index.json +36294 -0
  282. package/dist/global-skills/vybekiitReferences/web/agent/ui-catalog-index.mobile.json +36294 -0
  283. package/dist/global-skills/vybekiitReferences/web/agent/ui-sources.md +104 -0
  284. package/dist/global-skills/vybekiitReferences/web/language.md +348 -0
  285. package/dist/global-skills/vybekiitReferences/web/platform-skills/README.md +66 -0
  286. package/dist/global-skills/vybekiitReferences/web/platform-skills/ai-vybekiit.md +3 -0
  287. package/dist/global-skills/vybekiitReferences/web/platform-skills/analytics-vybekiit.md +20 -0
  288. package/dist/global-skills/vybekiitReferences/web/platform-skills/assets-vybekiit.md +31 -0
  289. package/dist/global-skills/vybekiitReferences/web/platform-skills/aws-vybekiit.md +25 -0
  290. package/dist/global-skills/vybekiitReferences/web/platform-skills/better-auth-vybekiit.md +21 -0
  291. package/dist/global-skills/vybekiitReferences/web/platform-skills/browser-automation-vybekiit.md +48 -0
  292. package/dist/global-skills/vybekiitReferences/web/platform-skills/ci-vybekiit.md +26 -0
  293. package/dist/global-skills/vybekiitReferences/web/platform-skills/client-state-vybekiit.md +25 -0
  294. package/dist/global-skills/vybekiitReferences/web/platform-skills/cloudflare-email-vybekiit.md +42 -0
  295. package/dist/global-skills/vybekiitReferences/web/platform-skills/cms-vybekiit.md +3 -0
  296. package/dist/global-skills/vybekiitReferences/web/platform-skills/code-hygiene-vybekiit.md +38 -0
  297. package/dist/global-skills/vybekiitReferences/web/platform-skills/compliance-vybekiit.md +3 -0
  298. package/dist/global-skills/vybekiitReferences/web/platform-skills/data-model-vybekiit.md +29 -0
  299. package/dist/global-skills/vybekiitReferences/web/platform-skills/db-presets-vybekiit.md +46 -0
  300. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-cloudflare-vybekiit.md +22 -0
  301. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-github-pages-vybekiit.md +25 -0
  302. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-railway-vybekiit.md +26 -0
  303. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-vercel-vybekiit.md +23 -0
  304. package/dist/global-skills/vybekiitReferences/web/platform-skills/env-secrets-vybekiit.md +21 -0
  305. package/dist/global-skills/vybekiitReferences/web/platform-skills/extend-capabilities-vybekiit.md +127 -0
  306. package/dist/global-skills/vybekiitReferences/web/platform-skills/firebase-vybekiit.md +27 -0
  307. package/dist/global-skills/vybekiitReferences/web/platform-skills/format-lint-vybekiit.md +33 -0
  308. package/dist/global-skills/vybekiitReferences/web/platform-skills/github-vybekiit.md +47 -0
  309. package/dist/global-skills/vybekiitReferences/web/platform-skills/i18n-vybekiit.md +3 -0
  310. package/dist/global-skills/vybekiitReferences/web/platform-skills/jobs-vybekiit.md +3 -0
  311. package/dist/global-skills/vybekiitReferences/web/platform-skills/kv-vybekiit.md +3 -0
  312. package/dist/global-skills/vybekiitReferences/web/platform-skills/lemon-squeezy-vybekiit.md +30 -0
  313. package/dist/global-skills/vybekiitReferences/web/platform-skills/mcp-tools-vybekiit.md +87 -0
  314. package/dist/global-skills/vybekiitReferences/web/platform-skills/mongodb-vybekiit.md +39 -0
  315. package/dist/global-skills/vybekiitReferences/web/platform-skills/neon-vybekiit.md +33 -0
  316. package/dist/global-skills/vybekiitReferences/web/platform-skills/nextjs-vybekiit.md +20 -0
  317. package/dist/global-skills/vybekiitReferences/web/platform-skills/notifications-vybekiit.md +3 -0
  318. package/dist/global-skills/vybekiitReferences/web/platform-skills/observability-vybekiit.md +36 -0
  319. package/dist/global-skills/vybekiitReferences/web/platform-skills/paypal-vybekiit.md +25 -0
  320. package/dist/global-skills/vybekiitReferences/web/platform-skills/planning-vybekiit.md +59 -0
  321. package/dist/global-skills/vybekiitReferences/web/platform-skills/playwright-vybekiit.md +42 -0
  322. package/dist/global-skills/vybekiitReferences/web/platform-skills/railway-postgres-vybekiit.md +24 -0
  323. package/dist/global-skills/vybekiitReferences/web/platform-skills/react-patterns-vybekiit.md +45 -0
  324. package/dist/global-skills/vybekiitReferences/web/platform-skills/realtime-vybekiit.md +3 -0
  325. package/dist/global-skills/vybekiitReferences/web/platform-skills/registrar-vybekiit.md +36 -0
  326. package/dist/global-skills/vybekiitReferences/web/platform-skills/resend-vybekiit.md +20 -0
  327. package/dist/global-skills/vybekiitReferences/web/platform-skills/responsive-vybekiit.md +27 -0
  328. package/dist/global-skills/vybekiitReferences/web/platform-skills/search-vybekiit.md +3 -0
  329. package/dist/global-skills/vybekiitReferences/web/platform-skills/sentry-vybekiit.md +33 -0
  330. package/dist/global-skills/vybekiitReferences/web/platform-skills/seo-vybekiit.md +29 -0
  331. package/dist/global-skills/vybekiitReferences/web/platform-skills/ses-vybekiit.md +19 -0
  332. package/dist/global-skills/vybekiitReferences/web/platform-skills/shadcn-vybekiit.md +25 -0
  333. package/dist/global-skills/vybekiitReferences/web/platform-skills/ship-via-pr-vybekiit.md +49 -0
  334. package/dist/global-skills/vybekiitReferences/web/platform-skills/stripe-vybekiit.md +26 -0
  335. package/dist/global-skills/vybekiitReferences/web/platform-skills/supabase-vybekiit.md +31 -0
  336. package/dist/global-skills/vybekiitReferences/web/platform-skills/tenancy-vybekiit.md +3 -0
  337. package/dist/global-skills/vybekiitReferences/web/platform-skills/testing-vybekiit.md +33 -0
  338. package/dist/global-skills/vybekiitReferences/web/platform-skills/ui-consistency-vybekiit.md +34 -0
  339. package/dist/global-skills/vybekiitReferences/web/platform-skills/ui-routing-vybekiit.md +41 -0
  340. package/dist/global-skills/watch-my-app/SKILL.md +6 -0
  341. package/dist/global-skills/web-to-native/SKILL.md +1 -0
  342. package/dist/global-skills/wire-auth/SKILL.md +6 -0
  343. package/dist/global-skills/wire-database/SKILL.md +15 -1
  344. package/dist/global-skills/wire-email/SKILL.md +6 -0
  345. package/dist/global-skills/wire-payments/SKILL.md +6 -0
  346. package/dist/global-skills/workers-best-practices/SKILL.md +4 -3
  347. package/dist/global-skills/workers-best-practices/references/configuration.md +1 -1
  348. package/dist/global-skills/workers-best-practices/references/platform-apis.md +5 -5
  349. package/dist/global-skills/workers-best-practices/references/runtime-patterns.md +1 -1
  350. package/dist/global-skills/wrangler/SKILL.md +27 -24
  351. package/dist/global-skills/xcode-project-setup/SKILL.md +1 -0
  352. package/package.json +12 -9
@@ -0,0 +1,676 @@
1
+ # Client-Side Text-to-Speech (TTS) Generation with Gemini
2
+
3
+ Firebase AI Logic enables client-side Text-to-Speech (TTS) generation directly
4
+ from your mobile and web applications without maintaining custom backend speech
5
+ services. Using specialized Gemini TTS models, apps can synthesize natural,
6
+ expressive audio with custom voice personas, multi-speaker dialogues, and
7
+ in-flight audio streaming.
8
+
9
+ ______________________________________________________________________
10
+
11
+ ## Supported Models
12
+
13
+ Always specify a dedicated Gemini TTS model when generating audio:
14
+
15
+ | Model ID | Description |
16
+ | :----------------------------- | :--------------------------------------------------------------------------------- |
17
+ | `gemini-3.1-flash-tts-preview` | Low-latency speech synthesis (preview); supports single- and multi-speaker output. |
18
+
19
+ > [!WARNING] Always verify currently supported model availability in the
20
+ > [Firebase AI Logic Models documentation](https://firebase.google.com/docs/ai-logic/models.md.txt).
21
+
22
+ ______________________________________________________________________
23
+
24
+ ## Core Concepts & Configurations
25
+
26
+ ### 1. Response Modality
27
+
28
+ To instruct Gemini to synthesize and return audio, configure
29
+ `responseModalities` in the generation configuration to include audio:
30
+
31
+ - **Swift**: `generationConfig = GenerationConfig(responseModalities: [.audio])`
32
+ - **Kotlin**:
33
+ `generationConfig { responseModalities = listOf(ResponseModality.AUDIO) }`
34
+ - **Web (JS/TS)**: `generationConfig: { responseModalities: ["AUDIO"] }`
35
+
36
+ ### 2. Single-Speaker `SpeechConfig`
37
+
38
+ Configure voice persona and optional language code (`languageCode`, e.g.
39
+ `"en-US"`, `"es-ES"`, `"ja-JP"`) using `SpeechConfig`. Voice names map to Google
40
+ prebuilt neural voices (for example: `Puck`, `Charon`, `Kore`, `Fenrir`,
41
+ `Aoede`):
42
+
43
+ - **Swift**:
44
+ ```swift
45
+ let speechConfig = SpeechConfig(
46
+ voiceConfig: VoiceConfig(
47
+ prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Puck")
48
+ ),
49
+ languageCode: "en-US"
50
+ )
51
+ ```
52
+ - **Kotlin**:
53
+ ```kotlin
54
+ val speechConfig = speechConfig {
55
+ voiceConfig = voiceConfig {
56
+ prebuiltVoiceConfig = prebuiltVoiceConfig {
57
+ voiceName = "Puck"
58
+ }
59
+ }
60
+ languageCode = "en-US"
61
+ }
62
+ ```
63
+ - **Web**:
64
+ ```javascript
65
+ speechConfig: {
66
+ voiceConfig: {
67
+ prebuiltVoiceConfig: {
68
+ voiceName: "Puck"
69
+ }
70
+ },
71
+ languageCode: "en-US"
72
+ }
73
+ ```
74
+
75
+ ### 3. Multi-Speaker `MultiSpeakerVoiceConfig` (2-Speaker Dialogues)
76
+
77
+ For scripts with two distinct characters or roles (e.g., host and guest,
78
+ narrator and character), configure `MultiSpeakerVoiceConfig` with
79
+ `speakerVoiceConfigs` linking speaker names to specific voices:
80
+
81
+ - **Swift**:
82
+ ```swift
83
+ let multiSpeakerConfig = SpeechConfig(
84
+ multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
85
+ speakerVoiceConfigs: [
86
+ SpeakerVoiceConfig(
87
+ speaker: "Host",
88
+ voiceConfig: VoiceConfig(
89
+ prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Puck")
90
+ )
91
+ ),
92
+ SpeakerVoiceConfig(
93
+ speaker: "Guest",
94
+ voiceConfig: VoiceConfig(
95
+ prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Aoede")
96
+ )
97
+ )
98
+ ]
99
+ )
100
+ )
101
+ ```
102
+ - **Kotlin**:
103
+ ```kotlin
104
+ val multiSpeakerConfig = speechConfig {
105
+ multiSpeakerVoiceConfig = multiSpeakerVoiceConfig {
106
+ speakerVoiceConfigs = listOf(
107
+ speakerVoiceConfig {
108
+ speaker = "Host"
109
+ voiceConfig = voiceConfig {
110
+ prebuiltVoiceConfig = prebuiltVoiceConfig { voiceName = "Puck" }
111
+ }
112
+ },
113
+ speakerVoiceConfig {
114
+ speaker = "Guest"
115
+ voiceConfig = voiceConfig {
116
+ prebuiltVoiceConfig = prebuiltVoiceConfig { voiceName = "Aoede" }
117
+ }
118
+ }
119
+ )
120
+ }
121
+ }
122
+ ```
123
+ - **Web**:
124
+ ```javascript
125
+ speechConfig: {
126
+ multiSpeakerVoiceConfig: {
127
+ speakerVoiceConfigs: [
128
+ {
129
+ speaker: "Host",
130
+ voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } }
131
+ },
132
+ {
133
+ speaker: "Guest",
134
+ voiceConfig: { prebuiltVoiceConfig: { voiceName: "Aoede" } }
135
+ }
136
+ ]
137
+ }
138
+ }
139
+ ```
140
+
141
+ ______________________________________________________________________
142
+
143
+ ## Audio Directives and Emotional Tags
144
+
145
+ Gemini TTS models accept natural-language directives and inline tags in prompts
146
+ to control tone, cadence, pacing, and emotional expression.
147
+
148
+ ### Directives
149
+
150
+ Include directives at the start of your prompt to set the overall tone and
151
+ scene:
152
+
153
+ - `[Audio Profile: Warm, conversational podcast co-host with energetic delivery]`
154
+ - `[Scene: Quiet bedtime story in a calm room]`
155
+ - `[Director's Note: Speak deliberately, pausing for reflection after major questions]`
156
+
157
+ ### Emotional Tags & Delivery Cues
158
+
159
+ Embed delivery markers inline within dialogue or narration:
160
+
161
+ - `[whispers]` — Soft, confidential whisper.
162
+ - `[laughs]` / `[chuckles]` — Lighthearted laughter during delivery.
163
+ - `[sighs]` — Expressive exhale.
164
+ - `[slowly]` — Reduced tempo for emphasis or dramatic effect.
165
+ - `[excited]` — Higher energy and faster pacing.
166
+ - `[pause]` — Deliberate silence.
167
+
168
+ ### Multi-Speaker Prompt Example
169
+
170
+ ```text
171
+ [Scene: A lively coffee-shop tech discussion]
172
+ [Director's Note: Host is upbeat and curious; Guest is thoughtful and explanatory]
173
+
174
+ Host: Welcome back! [excited] Today we are diving into client-side audio.
175
+ Guest: [laughs] It's about time! No servers in between means virtually zero latency.
176
+ Host: [whispers] Tell us the secret... how does it stream?
177
+ Guest: [slowly] Pure linear PCM, chunk by chunk, directly to your device's audio engine.
178
+ ```
179
+
180
+ ______________________________________________________________________
181
+
182
+ ## Audio Decoding and Playback
183
+
184
+ ### Format Specifications
185
+
186
+ Gemini TTS audio format depends on whether the request is unary or streaming:
187
+
188
+ - **Unary Requests (`generateContent`)**: Returns complete **WAV (`audio/wav`)**
189
+ audio with a standard 44-byte RIFF header included by default (24 kHz, mono,
190
+ 16-bit signed little-endian PCM). These bytes can be passed directly to
191
+ standard media players (`AVAudioPlayer`, `MediaPlayer`, `<audio>`).
192
+
193
+ - **Streaming Requests (`generateContentStream`)**: Returns headerless raw
194
+ **Linear PCM (`audio/l16; rate=24000; channels=1`)** chunks (24 kHz, mono,
195
+ 16-bit signed little-endian PCM) so chunks can be streamed or concatenated
196
+ continuously without per-chunk container headers.
197
+
198
+ - **Audio Parameters**:
199
+
200
+ - **Sample Rate**: 24,000 Hz (24 kHz)
201
+ - **Channels**: 1 channel (mono)
202
+ - **Bit Depth**: 16-bit linear PCM (little-endian signed integer)
203
+ - **MIME Types**: `audio/l16` (streaming chunks) or `audio/wav` /
204
+ `audio/x-wav` (unary)
205
+
206
+ ### Playback Approaches
207
+
208
+ 1. **Direct Low-Latency PCM Streaming**:
209
+ - Stream raw PCM chunks directly into low-level audio renderers without
210
+ waiting for the full response:
211
+ - **iOS**: `AVAudioEngine` + `AVAudioPlayerNode` scheduling
212
+ `AVAudioPCMBuffer`.
213
+ - **Android**: `AudioTrack` configured with `ENCODING_PCM_16BIT` and
214
+ `CHANNEL_OUT_MONO`.
215
+ - **Web**: Web Audio API (`AudioContext`) scheduling PCM chunks into
216
+ `AudioBufferSourceNode`.
217
+ 1. **WAV Container Format**:
218
+ - Standard media players (`AVAudioPlayer` on iOS, `MediaPlayer` on Android,
219
+ `<audio>` on Web) expect a container header (RIFF/WAV).
220
+ - For unary responses, the RIFF header is already present. For assembled
221
+ streaming PCM chunks, prepend a standard **44-byte RIFF header** to make
222
+ the complete audio immediately playable or saveable as `.wav`.
223
+
224
+ #### Standard 44-Byte WAV (RIFF) Header Construction
225
+
226
+ ```
227
+ Offset Size Field Value
228
+ 0 4 ChunkID "RIFF"
229
+ 4 4 ChunkSize 36 + Subchunk2Size (file size - 8)
230
+ 8 4 Format "WAVE"
231
+ 12 4 Subchunk1ID "fmt "
232
+ 16 4 Subchunk1Size 16 (for PCM)
233
+ 20 2 AudioFormat 1 (PCM linear)
234
+ 22 2 NumChannels 1 (Mono)
235
+ 24 4 SampleRate 24000
236
+ 28 4 ByteRate 48000 (SampleRate * NumChannels * BitsPerSample / 8)
237
+ 32 2 BlockAlign 2 (NumChannels * BitsPerSample / 8)
238
+ 34 2 BitsPerSample 16
239
+ 36 4 Subchunk2ID "data"
240
+ 40 4 Subchunk2Size Number of PCM bytes
241
+ 44+ N Data Raw PCM bytes
242
+ ```
243
+
244
+ ______________________________________________________________________
245
+
246
+ ## Platform Code Snippets
247
+
248
+ ### Swift (iOS)
249
+
250
+ #### 1. Streaming Playback with `AVAudioEngine`
251
+
252
+ ```swift
253
+ import AVFoundation
254
+ import FirebaseAILogic
255
+
256
+ @MainActor
257
+ final class SpeechStreamingManager {
258
+ private let audioEngine = AVAudioEngine()
259
+ private let playerNode = AVAudioPlayerNode()
260
+
261
+ // 24 kHz, 16-bit Mono PCM
262
+ private let audioFormat = AVAudioFormat(
263
+ commonFormat: .pcmFormatInt16,
264
+ sampleRate: 24000,
265
+ channels: 1,
266
+ interleaved: false
267
+ )!
268
+
269
+ init() {
270
+ audioEngine.attach(playerNode)
271
+ audioEngine.connect(playerNode, to: audioEngine.mainMixerNode, format: audioFormat)
272
+ }
273
+
274
+ func streamSpeech(prompt: String) async throws {
275
+ let ai = FirebaseAI.firebaseAI()
276
+
277
+ let speechConfig = SpeechConfig(
278
+ voiceConfig: VoiceConfig(
279
+ prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Puck")
280
+ )
281
+ )
282
+
283
+ let genConfig = GenerationConfig(
284
+ responseModalities: [.audio],
285
+ speechConfig: speechConfig
286
+ )
287
+
288
+ let model = ai.generativeModel(
289
+ modelName: "gemini-3.1-flash-tts-preview",
290
+ generationConfig: genConfig
291
+ )
292
+
293
+ if !audioEngine.isRunning {
294
+ try audioEngine.start()
295
+ }
296
+ playerNode.play()
297
+
298
+ let stream = model.generateContentStream(prompt)
299
+ for try await chunk in stream {
300
+ for part in chunk.candidates.first?.content.parts ?? [] {
301
+ if let inlineData = part as? InlineDataPart,
302
+ inlineData.mimeType.contains("audio/pcm") || inlineData.mimeType.contains("audio/l16") {
303
+ schedulePCMBuffer(data: inlineData.data)
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+ private func schedulePCMBuffer(data: Data) {
310
+ let frameCount = UInt32(data.count) / audioFormat.streamDescription.pointee.mBytesPerFrame
311
+ guard frameCount > 0,
312
+ let buffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: frameCount) else {
313
+ return
314
+ }
315
+ buffer.frameLength = frameCount
316
+
317
+ data.withUnsafeBytes { rawBufferPointer in
318
+ guard let src = rawBufferPointer.baseAddress else { return }
319
+ if let dest = buffer.int16ChannelData?[0] {
320
+ UnsafeMutableRawPointer(dest).copyMemory(from: src, byteCount: data.count)
321
+ }
322
+ }
323
+
324
+ playerNode.scheduleBuffer(buffer)
325
+ }
326
+
327
+ func stop() {
328
+ playerNode.stop()
329
+ audioEngine.stop()
330
+ }
331
+ }
332
+ ```
333
+
334
+ #### 2. WAV Converter for `AVAudioPlayer`
335
+
336
+ ```swift
337
+ func addWavHeader(to pcmData: Data, sampleRate: Int = 24000, channels: Int = 1, bitDepth: Int = 16) -> Data {
338
+ var header = Data()
339
+ let byteRate = sampleRate * channels * bitDepth / 8
340
+ let blockAlign = channels * bitDepth / 8
341
+ let totalDataLen = Int32(pcmData.count)
342
+ let totalLength = totalDataLen + 36
343
+
344
+ header.append(contentsOf: "RIFF".utf8)
345
+ header.append(Data(from: totalLength.littleEndian))
346
+ header.append(contentsOf: "WAVE".utf8)
347
+ header.append(contentsOf: "fmt ".utf8)
348
+ header.append(Data(from: Int32(16).littleEndian)) // Subchunk1Size for PCM
349
+ header.append(Data(from: Int16(1).littleEndian)) // AudioFormat 1 = PCM
350
+ header.append(Data(from: Int16(channels).littleEndian))
351
+ header.append(Data(from: Int32(sampleRate).littleEndian))
352
+ header.append(Data(from: Int32(byteRate).littleEndian))
353
+ header.append(Data(from: Int16(blockAlign).littleEndian))
354
+ header.append(Data(from: Int16(bitDepth).littleEndian))
355
+ header.append(contentsOf: "data".utf8)
356
+ header.append(Data(from: totalDataLen.littleEndian))
357
+
358
+ return header + pcmData
359
+ }
360
+
361
+ private extension Data {
362
+ init<T>(from value: T) {
363
+ var val = value
364
+ self = Swift.withUnsafeBytes(of: &val) { Data($0) }
365
+ }
366
+ }
367
+ ```
368
+
369
+ ______________________________________________________________________
370
+
371
+ ### Kotlin (Android)
372
+
373
+ #### Streaming Playback with `AudioTrack`
374
+
375
+ ```kotlin
376
+ import android.media.AudioAttributes
377
+ import android.media.AudioFormat
378
+ import android.media.AudioTrack
379
+ import com.google.firebase.ai.FirebaseAI
380
+ import com.google.firebase.ai.type.ResponseModality
381
+ import com.google.firebase.ai.type.generationConfig
382
+ import com.google.firebase.ai.type.prebuiltVoiceConfig
383
+ import com.google.firebase.ai.type.speechConfig
384
+ import com.google.firebase.ai.type.voiceConfig
385
+ import kotlinx.coroutines.Dispatchers
386
+ import kotlinx.coroutines.withContext
387
+
388
+ class SpeechStreamingManager {
389
+ private val sampleRate = 24000
390
+ private val minBufferSize = AudioTrack.getMinBufferSize(
391
+ sampleRate,
392
+ AudioFormat.CHANNEL_OUT_MONO,
393
+ AudioFormat.ENCODING_PCM_16BIT
394
+ )
395
+
396
+ private val audioTrack = AudioTrack.Builder()
397
+ .setAudioAttributes(
398
+ AudioAttributes.Builder()
399
+ .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
400
+ .setUsage(AudioAttributes.USAGE_MEDIA)
401
+ .build()
402
+ )
403
+ .setAudioFormat(
404
+ AudioFormat.Builder()
405
+ .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
406
+ .setSampleRate(sampleRate)
407
+ .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
408
+ .build()
409
+ )
410
+ .setBufferSizeInBytes(minBufferSize * 2)
411
+ .setTransferMode(AudioTrack.MODE_STREAM)
412
+ .build()
413
+
414
+ suspend fun streamSpeech(prompt: String) = withContext(Dispatchers.IO) {
415
+ val config = generationConfig {
416
+ responseModalities = listOf(ResponseModality.AUDIO)
417
+ speechConfig = speechConfig {
418
+ voiceConfig = voiceConfig {
419
+ prebuiltVoiceConfig = prebuiltVoiceConfig {
420
+ voiceName = "Puck"
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+ val generativeModel = FirebaseAI.getInstance().getGenerativeModel(
427
+ modelName = "gemini-3.1-flash-tts-preview",
428
+ generationConfig = config
429
+ )
430
+
431
+ audioTrack.play()
432
+ try {
433
+ val responseStream = generativeModel.generateContentStream(prompt)
434
+ responseStream.collect { chunk ->
435
+ chunk.candidates.firstOrNull()?.content?.parts?.forEach { part ->
436
+ if (part is com.google.firebase.ai.type.InlineDataPart) {
437
+ val audioBytes = part.data
438
+ audioTrack.write(audioBytes, 0, audioBytes.size)
439
+ }
440
+ }
441
+ }
442
+ } finally {
443
+ audioTrack.stop()
444
+ }
445
+ }
446
+
447
+ fun release() {
448
+ audioTrack.release()
449
+ }
450
+ }
451
+ ```
452
+
453
+ #### 2. Convert PCM to WAV for `MediaPlayer`
454
+
455
+ ```kotlin
456
+ import android.content.Context
457
+ import android.media.MediaPlayer
458
+ import java.io.File
459
+ import java.io.FileOutputStream
460
+ import java.nio.ByteBuffer
461
+ import java.nio.ByteOrder
462
+
463
+ fun addWavHeader(
464
+ pcmBytes: ByteArray,
465
+ sampleRate: Int = 24000,
466
+ channels: Short = 1,
467
+ bitDepth: Short = 16
468
+ ): ByteArray {
469
+ val totalDataLen = pcmBytes.size
470
+ val totalLength = totalDataLen + 36
471
+ val byteRate = sampleRate * channels * bitDepth / 8
472
+ val blockAlign = (channels * bitDepth / 8).toShort()
473
+
474
+ val header = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN).apply {
475
+ put("RIFF".toByteArray())
476
+ putInt(totalLength)
477
+ put("WAVE".toByteArray())
478
+ put("fmt ".toByteArray())
479
+ putInt(16) // Subchunk1Size
480
+ putShort(1) // AudioFormat 1 = PCM
481
+ putShort(channels)
482
+ putInt(sampleRate)
483
+ putInt(byteRate)
484
+ putShort(blockAlign)
485
+ putShort(bitDepth)
486
+ put("data".toByteArray())
487
+ putInt(totalDataLen)
488
+ }.array()
489
+
490
+ return header + pcmBytes
491
+ }
492
+
493
+ fun playWavAudio(context: Context, wavBytes: ByteArray) {
494
+ val tempFile = File.createTempFile("tts_", ".wav", context.cacheDir).apply {
495
+ deleteOnExit()
496
+ FileOutputStream(this).use { it.write(wavBytes) }
497
+ }
498
+
499
+ val mediaPlayer = MediaPlayer()
500
+ try {
501
+ mediaPlayer.setDataSource(tempFile.absolutePath)
502
+ mediaPlayer.prepare()
503
+ mediaPlayer.start()
504
+ mediaPlayer.setOnCompletionListener {
505
+ it.release()
506
+ tempFile.delete()
507
+ }
508
+ } catch (e: Exception) {
509
+ mediaPlayer.release()
510
+ tempFile.delete()
511
+ throw e
512
+ }
513
+ }
514
+ ```
515
+
516
+ ______________________________________________________________________
517
+
518
+ ### Web (JavaScript/TypeScript)
519
+
520
+ #### 1. Streaming Playback with Web Audio API
521
+
522
+ ```typescript
523
+ import { initializeApp } from "firebase/app";
524
+ import { getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";
525
+
526
+ const firebaseConfig = {
527
+ // your firebase configuration
528
+ };
529
+
530
+ const app = initializeApp(firebaseConfig);
531
+ const ai = getAI(app, { backend: new GoogleAIBackend() });
532
+
533
+ const model = getGenerativeModel(ai, {
534
+ model: "gemini-3.1-flash-tts-preview",
535
+ generationConfig: {
536
+ responseModalities: ["AUDIO"],
537
+ speechConfig: {
538
+ voiceConfig: {
539
+ prebuiltVoiceConfig: {
540
+ voiceName: "Puck",
541
+ },
542
+ },
543
+ },
544
+ },
545
+ });
546
+
547
+ export class WebSpeechPlayer {
548
+ private audioCtx: AudioContext | null = null;
549
+ private nextStartTime: number = 0;
550
+
551
+ private getAudioContext(): AudioContext {
552
+ if (!this.audioCtx) {
553
+ if (typeof window === "undefined") {
554
+ throw new Error("AudioContext is only available in browser environments.");
555
+ }
556
+ const AudioContextClass =
557
+ window.AudioContext ||
558
+ (window as unknown as { webkitAudioContext: typeof AudioContext })
559
+ .webkitAudioContext;
560
+ this.audioCtx = new AudioContextClass({ sampleRate: 24000 });
561
+ }
562
+ return this.audioCtx;
563
+ }
564
+
565
+ async playSpeechStream(prompt: string) {
566
+ const ctx = this.getAudioContext();
567
+ if (ctx.state === "suspended") {
568
+ await ctx.resume();
569
+ }
570
+ this.nextStartTime = ctx.currentTime;
571
+
572
+ const responseStream = await model.generateContentStream(prompt);
573
+
574
+ for await (const chunk of responseStream.stream) {
575
+ const candidates = chunk.candidates || [];
576
+ for (const candidate of candidates) {
577
+ for (const part of candidate.content?.parts || []) {
578
+ if ("inlineData" in part && part.inlineData?.data) {
579
+ const rawPcm = this.base64ToArrayBuffer(part.inlineData.data);
580
+ this.queuePcmChunk(rawPcm, ctx);
581
+ }
582
+ }
583
+ }
584
+ }
585
+ }
586
+
587
+ private queuePcmChunk(pcmData: ArrayBuffer, ctx: AudioContext) {
588
+ const int16Array = new Int16Array(pcmData);
589
+ const float32Array = new Float32Array(int16Array.length);
590
+
591
+ // Convert 16-bit PCM integer samples to -1.0 .. 1.0 float samples
592
+ for (let i = 0; i < int16Array.length; i++) {
593
+ float32Array[i] = int16Array[i] / 32768.0;
594
+ }
595
+
596
+ const audioBuffer = ctx.createBuffer(1, float32Array.length, 24000);
597
+ audioBuffer.copyToChannel(float32Array, 0);
598
+
599
+ const source = ctx.createBufferSource();
600
+ source.buffer = audioBuffer;
601
+ source.connect(ctx.destination);
602
+
603
+ const startTime = Math.max(this.nextStartTime, ctx.currentTime);
604
+ source.start(startTime);
605
+ this.nextStartTime = startTime + audioBuffer.duration;
606
+ }
607
+
608
+ private base64ToArrayBuffer(base64: string): ArrayBuffer {
609
+ const binaryString = window.atob(base64);
610
+ const len = binaryString.length;
611
+ const bytes = new Uint8Array(len);
612
+ for (let i = 0; i < len; i++) {
613
+ bytes[i] = binaryString.charCodeAt(i);
614
+ }
615
+ return bytes.buffer;
616
+ }
617
+ }
618
+ ```
619
+
620
+ #### 2. Convert PCM Base64 to Playable WAV Blob for `<audio>` Elements
621
+
622
+ ```typescript
623
+ export function pcmToWavBlob(pcmBytes: Uint8Array, sampleRate = 24000): Blob {
624
+ const header = new ArrayBuffer(44);
625
+ const view = new DataView(header);
626
+
627
+ const numChannels = 1;
628
+ const bitsPerSample = 16;
629
+ const byteRate = (sampleRate * numChannels * bitsPerSample) / 8;
630
+ const blockAlign = (numChannels * bitsPerSample) / 8;
631
+ const dataSize = pcmBytes.byteLength;
632
+
633
+ // RIFF identifier
634
+ writeString(view, 0, "RIFF");
635
+ view.setUint32(4, 36 + dataSize, true);
636
+ writeString(view, 8, "WAVE");
637
+
638
+ // fmt subchunk
639
+ writeString(view, 12, "fmt ");
640
+ view.setUint32(16, 16, true); // Subchunk1Size
641
+ view.setUint16(20, 1, true); // AudioFormat (PCM = 1)
642
+ view.setUint16(22, numChannels, true);
643
+ view.setUint32(24, sampleRate, true);
644
+ view.setUint32(28, byteRate, true);
645
+ view.setUint16(32, blockAlign, true);
646
+ view.setUint16(34, bitsPerSample, true);
647
+
648
+ // data subchunk
649
+ writeString(view, 36, "data");
650
+ view.setUint32(40, dataSize, true);
651
+
652
+ return new Blob([header, pcmBytes], { type: "audio/wav" });
653
+ }
654
+
655
+ function writeString(view: DataView, offset: number, string: string) {
656
+ for (let i = 0; i < string.length; i++) {
657
+ view.setUint8(offset + i, string.charCodeAt(i));
658
+ }
659
+ }
660
+ ```
661
+
662
+ ______________________________________________________________________
663
+
664
+ ## Best Practices & Troubleshooting
665
+
666
+ - **Audio Session & Permissions**: On iOS and Android, make sure the app's audio
667
+ session/category is configured to allow playback (e.g.,
668
+ `AVAudioSessionCategoryPlayback`).
669
+ - **Buffering & Jitter Prevention**: When streaming audio chunks via
670
+ `generateContentStream`, queue buffers sequentially with exact timestamps or
671
+ frame offsets to avoid audio stutter or gaps.
672
+ - **Model Compatibility**: TTS features require Gemini models with dedicated
673
+ audio synthesis capabilities (`gemini-3.1-flash-tts-preview`). Do not use
674
+ standard text-only model IDs.
675
+ - **App Check Protection**: Generating audio consumes quota. Protect your API
676
+ endpoints by enforcing App Check on every client build.
@@ -4,6 +4,7 @@ description: >-
4
4
  Deploys and manages full-stack web applications (Next.js, Angular) with Server-Side Rendering (SSR) using Firebase App Hosting. Use when deploying Next.js/Angular apps, configuring apphosting.yaml or firebase.json apphosting blocks, managing secrets, setting up GitHub CI/CD, or configuring Blaze billing requirements. Don't use for classic static web hosting, Auth, Firestore, Crashlytics, or Xcode.
5
5
  metadata:
6
6
  category: Serverless
7
+ disable-model-invocation: true
7
8
  ---
8
9
 
9
10
  # App Hosting Basics