vybekiit 0.4.0 → 0.6.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 (665) hide show
  1. package/dist/bin.js +840 -296
  2. package/dist/global-skills/add-ai/SKILL.md +53 -0
  3. package/dist/global-skills/add-analytics/SKILL.md +65 -0
  4. package/dist/global-skills/add-app-clip/SKILL.md +280 -0
  5. package/dist/global-skills/add-app-clip/agents/openai.yaml +4 -0
  6. package/dist/global-skills/add-app-clip/references/native-module.md +96 -0
  7. package/dist/global-skills/add-blog/SKILL.md +49 -0
  8. package/dist/global-skills/add-crud/SKILL.md +28 -0
  9. package/dist/global-skills/add-files/SKILL.md +65 -0
  10. package/dist/global-skills/add-images/SKILL.md +64 -0
  11. package/dist/global-skills/add-language/SKILL.md +44 -0
  12. package/dist/global-skills/add-notifications/SKILL.md +61 -0
  13. package/dist/global-skills/add-realtime/SKILL.md +49 -0
  14. package/dist/global-skills/add-route/SKILL.md +28 -0
  15. package/dist/global-skills/add-search/SKILL.md +43 -0
  16. package/dist/global-skills/add-signin/SKILL.md +78 -0
  17. package/dist/global-skills/add-teams/SKILL.md +64 -0
  18. package/dist/global-skills/add-upload/SKILL.md +27 -0
  19. package/dist/global-skills/aws-cdk/SKILL.md +72 -0
  20. package/dist/global-skills/aws-cdk/references/bootstrap-and-project-setup.md +257 -0
  21. package/dist/global-skills/aws-cdk/references/compliance-and-drift.md +193 -0
  22. package/dist/global-skills/aws-cdk/references/construct-patterns.md +315 -0
  23. package/dist/global-skills/aws-cdk/references/import-and-migrate.md +184 -0
  24. package/dist/global-skills/aws-cdk/references/refactor-and-prevent-replacement.md +198 -0
  25. package/dist/global-skills/aws-cdk/references/troubleshooting-credentials.md +183 -0
  26. package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +293 -0
  27. package/dist/global-skills/aws-cdk/references/troubleshooting-synth.md +274 -0
  28. package/dist/global-skills/aws-cdk/references/v1-to-v2-migration.md +119 -0
  29. package/dist/global-skills/aws-cloudformation/SKILL.md +88 -0
  30. package/dist/global-skills/aws-cloudformation/references/author-cloudformation-best-practices.script.md +179 -0
  31. package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +159 -0
  32. package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +217 -0
  33. package/dist/global-skills/aws-cloudformation/references/deploy-with-express-mode.script.md +271 -0
  34. package/dist/global-skills/aws-cloudformation/references/lookup-resource-properties.script.md +130 -0
  35. package/dist/global-skills/aws-cloudformation/references/troubleshoot-deployment.script.md +200 -0
  36. package/dist/global-skills/aws-cloudformation/references/validate-cloudformation-template.script.md +135 -0
  37. package/dist/global-skills/aws-serverless/SKILL.md +51 -0
  38. package/dist/global-skills/aws-serverless/assets/powertools-handler.py +49 -0
  39. package/dist/global-skills/aws-serverless/references/api-gateway.md +553 -0
  40. package/dist/global-skills/aws-serverless/references/architecture.md +262 -0
  41. package/dist/global-skills/aws-serverless/references/concurrency.md +200 -0
  42. package/dist/global-skills/aws-serverless/references/deployment.md +94 -0
  43. package/dist/global-skills/aws-serverless/references/event-sources.md +484 -0
  44. package/dist/global-skills/aws-serverless/references/lambda.md +548 -0
  45. package/dist/global-skills/aws-serverless/references/orchestration.md +449 -0
  46. package/dist/global-skills/aws-serverless/references/production.md +493 -0
  47. package/dist/global-skills/aws-serverless/references/troubleshooting.md +711 -0
  48. package/dist/global-skills/back-up-my-code/SKILL.md +48 -0
  49. package/dist/global-skills/better-auth-best-practices/SKILL.md +182 -0
  50. package/dist/global-skills/better-auth-security-best-practices/SKILL.md +432 -0
  51. package/dist/global-skills/building-native-ui/SKILL.md +377 -0
  52. package/dist/global-skills/building-native-ui/agents/openai.yaml +4 -0
  53. package/dist/global-skills/building-native-ui/references/animations.md +220 -0
  54. package/dist/global-skills/building-native-ui/references/controls.md +270 -0
  55. package/dist/global-skills/building-native-ui/references/form-sheet.md +253 -0
  56. package/dist/global-skills/building-native-ui/references/gradients.md +106 -0
  57. package/dist/global-skills/building-native-ui/references/icons.md +213 -0
  58. package/dist/global-skills/building-native-ui/references/media.md +198 -0
  59. package/dist/global-skills/building-native-ui/references/route-structure.md +229 -0
  60. package/dist/global-skills/building-native-ui/references/search.md +248 -0
  61. package/dist/global-skills/building-native-ui/references/storage.md +121 -0
  62. package/dist/global-skills/building-native-ui/references/tabs.md +433 -0
  63. package/dist/global-skills/building-native-ui/references/toolbar-and-headers.md +284 -0
  64. package/dist/global-skills/building-native-ui/references/visual-effects.md +197 -0
  65. package/dist/global-skills/building-native-ui/references/webgpu-three.md +605 -0
  66. package/dist/global-skills/building-native-ui/references/zoom-transitions.md +158 -0
  67. package/dist/global-skills/buy-domain/SKILL.md +64 -0
  68. package/dist/global-skills/check-safety/SKILL.md +94 -0
  69. package/dist/global-skills/claimable-postgres/SKILL.md +249 -0
  70. package/dist/global-skills/configure-capabilities/SKILL.md +38 -0
  71. package/dist/global-skills/connect-account/SKILL.md +64 -0
  72. package/dist/global-skills/connect-account-backend/SKILL.md +41 -0
  73. package/dist/global-skills/create-auth-skill/SKILL.md +321 -0
  74. package/dist/global-skills/design-my-data/SKILL.md +48 -0
  75. package/dist/global-skills/doctor/SKILL.md +84 -0
  76. package/dist/global-skills/eas-app-stores/SKILL.md +152 -0
  77. package/dist/global-skills/eas-app-stores/agents/openai.yaml +4 -0
  78. package/dist/global-skills/eas-app-stores/references/app-store-metadata.md +497 -0
  79. package/dist/global-skills/eas-app-stores/references/ios-app-store.md +371 -0
  80. package/dist/global-skills/eas-app-stores/references/play-store.md +246 -0
  81. package/dist/global-skills/eas-app-stores/references/testflight.md +58 -0
  82. package/dist/global-skills/eas-app-stores/references/workflows.md +120 -0
  83. package/dist/global-skills/eas-hosting/SKILL.md +423 -0
  84. package/dist/global-skills/eas-hosting/agents/openai.yaml +4 -0
  85. package/dist/global-skills/eas-observe/SKILL.md +32 -0
  86. package/dist/global-skills/eas-observe/agents/openai.yaml +4 -0
  87. package/dist/global-skills/eas-observe/references/metrics.md +47 -0
  88. package/dist/global-skills/eas-observe/references/queries.md +342 -0
  89. package/dist/global-skills/eas-observe/references/setup.md +317 -0
  90. package/dist/global-skills/eas-simulator/SKILL.md +156 -0
  91. package/dist/global-skills/eas-simulator/agents/openai.yaml +4 -0
  92. package/dist/global-skills/eas-simulator/references/controllers.md +67 -0
  93. package/dist/global-skills/eas-simulator/references/run-your-app.md +185 -0
  94. package/dist/global-skills/eas-simulator/references/troubleshooting.md +38 -0
  95. package/dist/global-skills/eas-update-insights/SKILL.md +230 -0
  96. package/dist/global-skills/eas-update-insights/agents/openai.yaml +4 -0
  97. package/dist/global-skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  98. package/dist/global-skills/eas-update-insights/references/update-insights-schema.md +69 -0
  99. package/dist/global-skills/eas-workflows/SKILL.md +94 -0
  100. package/dist/global-skills/eas-workflows/agents/openai.yaml +4 -0
  101. package/dist/global-skills/eas-workflows/scripts/fetch.js +109 -0
  102. package/dist/global-skills/eas-workflows/scripts/package.json +11 -0
  103. package/dist/global-skills/eas-workflows/scripts/validate.js +84 -0
  104. package/dist/global-skills/email-best-practices/SKILL.md +73 -0
  105. package/dist/global-skills/expo-api-routes/SKILL.md +368 -0
  106. package/dist/global-skills/expo-api-routes/agents/openai.yaml +4 -0
  107. package/dist/global-skills/expo-app-clip/SKILL.md +282 -0
  108. package/dist/global-skills/expo-app-clip/agents/openai.yaml +4 -0
  109. package/dist/global-skills/expo-app-clip/references/native-module.md +96 -0
  110. package/dist/global-skills/expo-brownfield/SKILL.md +54 -0
  111. package/dist/global-skills/expo-brownfield/agents/openai.yaml +4 -0
  112. package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +526 -0
  113. package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +402 -0
  114. package/dist/global-skills/expo-brownfield/references/comparison.md +63 -0
  115. package/dist/global-skills/expo-brownfield/references/troubleshooting.md +88 -0
  116. package/dist/global-skills/expo-cicd-workflows/SKILL.md +92 -0
  117. package/dist/global-skills/expo-cicd-workflows/agents/openai.yaml +4 -0
  118. package/dist/global-skills/expo-cicd-workflows/scripts/fetch.js +109 -0
  119. package/dist/global-skills/expo-cicd-workflows/scripts/package.json +11 -0
  120. package/dist/global-skills/expo-cicd-workflows/scripts/validate.js +84 -0
  121. package/dist/global-skills/expo-data-fetching/SKILL.md +449 -0
  122. package/dist/global-skills/expo-data-fetching/agents/openai.yaml +4 -0
  123. package/dist/global-skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
  124. package/dist/global-skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
  125. package/dist/global-skills/expo-deployment/SKILL.md +167 -0
  126. package/dist/global-skills/expo-deployment/agents/openai.yaml +4 -0
  127. package/dist/global-skills/expo-deployment/references/app-store-metadata.md +497 -0
  128. package/dist/global-skills/expo-deployment/references/ios-app-store.md +371 -0
  129. package/dist/global-skills/expo-deployment/references/play-store.md +246 -0
  130. package/dist/global-skills/expo-deployment/references/testflight.md +58 -0
  131. package/dist/global-skills/expo-deployment/references/workflows.md +160 -0
  132. package/dist/global-skills/expo-dev-client/SKILL.md +174 -0
  133. package/dist/global-skills/expo-dev-client/agents/openai.yaml +4 -0
  134. package/dist/global-skills/expo-dom/SKILL.md +417 -0
  135. package/dist/global-skills/expo-dom/agents/openai.yaml +4 -0
  136. package/dist/global-skills/expo-examples/SKILL.md +99 -0
  137. package/dist/global-skills/expo-examples/agents/openai.yaml +4 -0
  138. package/dist/global-skills/expo-examples/references/catalog.md +105 -0
  139. package/dist/global-skills/expo-module/SKILL.md +141 -0
  140. package/dist/global-skills/expo-module/agents/openai.yaml +4 -0
  141. package/dist/global-skills/expo-module/references/config-plugin.md +90 -0
  142. package/dist/global-skills/expo-module/references/create-expo-module.md +206 -0
  143. package/dist/global-skills/expo-module/references/lifecycle.md +127 -0
  144. package/dist/global-skills/expo-module/references/module-config.md +48 -0
  145. package/dist/global-skills/expo-module/references/native-module.md +286 -0
  146. package/dist/global-skills/expo-module/references/native-view.md +171 -0
  147. package/dist/global-skills/expo-native-ui/SKILL.md +181 -0
  148. package/dist/global-skills/expo-native-ui/agents/openai.yaml +4 -0
  149. package/dist/global-skills/expo-native-ui/references/animations.md +220 -0
  150. package/dist/global-skills/expo-native-ui/references/controls.md +270 -0
  151. package/dist/global-skills/expo-native-ui/references/gradients.md +106 -0
  152. package/dist/global-skills/expo-native-ui/references/icons.md +213 -0
  153. package/dist/global-skills/expo-native-ui/references/media.md +198 -0
  154. package/dist/global-skills/expo-native-ui/references/storage.md +121 -0
  155. package/dist/global-skills/expo-native-ui/references/visual-effects.md +197 -0
  156. package/dist/global-skills/expo-native-ui/references/webgpu-three.md +605 -0
  157. package/dist/global-skills/expo-observe/SKILL.md +30 -0
  158. package/dist/global-skills/expo-observe/references/metrics.md +47 -0
  159. package/dist/global-skills/expo-observe/references/queries.md +342 -0
  160. package/dist/global-skills/expo-observe/references/setup.md +317 -0
  161. package/dist/global-skills/expo-router/SKILL.md +230 -0
  162. package/dist/global-skills/expo-router/agents/openai.yaml +4 -0
  163. package/dist/global-skills/expo-router/references/form-sheet.md +253 -0
  164. package/dist/global-skills/expo-router/references/route-structure.md +229 -0
  165. package/dist/global-skills/expo-router/references/search.md +248 -0
  166. package/dist/global-skills/expo-router/references/tabs.md +433 -0
  167. package/dist/global-skills/expo-router/references/toolbar-and-headers.md +284 -0
  168. package/dist/global-skills/expo-router/references/zoom-transitions.md +158 -0
  169. package/dist/global-skills/expo-skill-eval/SKILL.md +314 -0
  170. package/dist/global-skills/expo-skill-eval/agents/visual-grader.md +52 -0
  171. package/dist/global-skills/expo-skill-eval/references/design-rubric.md +45 -0
  172. package/dist/global-skills/expo-skill-eval/references/runtime-matrix.md +34 -0
  173. package/dist/global-skills/expo-skill-eval/scripts/check-static.sh +64 -0
  174. package/dist/global-skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
  175. package/dist/global-skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
  176. package/dist/global-skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
  177. package/dist/global-skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
  178. package/dist/global-skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
  179. package/dist/global-skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
  180. package/dist/global-skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
  181. package/dist/global-skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
  182. package/dist/global-skills/expo-skill-feedback/SKILL.md +54 -0
  183. package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +4 -0
  184. package/dist/global-skills/expo-skill-feedback/scripts/skill-event.cjs +180 -0
  185. package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +118 -0
  186. package/dist/global-skills/expo-skill-feedback/scripts/telemetry.cjs +65 -0
  187. package/dist/global-skills/expo-skill-feedback/scripts/telemetry_common.cjs +171 -0
  188. package/dist/global-skills/expo-tailwind-setup/SKILL.md +480 -0
  189. package/dist/global-skills/expo-tailwind-setup/agents/openai.yaml +4 -0
  190. package/dist/global-skills/expo-ui/SKILL.md +47 -0
  191. package/dist/global-skills/expo-ui/agents/openai.yaml +4 -0
  192. package/dist/global-skills/expo-ui/references/drop-in-replacements.md +27 -0
  193. package/dist/global-skills/expo-ui/references/jetpack-compose.md +73 -0
  194. package/dist/global-skills/expo-ui/references/swift-ui.md +73 -0
  195. package/dist/global-skills/expo-ui/references/universal.md +73 -0
  196. package/dist/global-skills/expo-ui/scripts/list-components.js +193 -0
  197. package/dist/global-skills/expo-upgrade/SKILL.md +134 -0
  198. package/dist/global-skills/expo-upgrade/agents/openai.yaml +4 -0
  199. package/dist/global-skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
  200. package/dist/global-skills/expo-upgrade/references/expo-av-to-video.md +160 -0
  201. package/dist/global-skills/expo-upgrade/references/native-tabs.md +124 -0
  202. package/dist/global-skills/expo-upgrade/references/new-architecture.md +79 -0
  203. package/dist/global-skills/expo-upgrade/references/react-19.md +79 -0
  204. package/dist/global-skills/expo-upgrade/references/react-compiler.md +59 -0
  205. package/dist/global-skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
  206. package/dist/global-skills/expo-web-to-native/SKILL.md +83 -0
  207. package/dist/global-skills/expo-web-to-native/agents/openai.yaml +4 -0
  208. package/dist/global-skills/expo-web-to-native/references/false-friends.md +119 -0
  209. package/dist/global-skills/expo-web-to-native/references/native-patterns.md +39 -0
  210. package/dist/global-skills/expo-web-to-native/references/run-as-goal.md +48 -0
  211. package/dist/global-skills/expo-web-to-native/references/verify-on-device.md +45 -0
  212. package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +165 -0
  213. package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +95 -0
  214. package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +156 -0
  215. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +157 -0
  216. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +186 -0
  217. package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +73 -0
  218. package/dist/global-skills/firebase-app-hosting-basics/references/cli_commands.md +85 -0
  219. package/dist/global-skills/firebase-app-hosting-basics/references/configuration.md +59 -0
  220. package/dist/global-skills/firebase-app-hosting-basics/references/emulation.md +59 -0
  221. package/dist/global-skills/firebase-auth-basics/SKILL.md +118 -0
  222. package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +160 -0
  223. package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +301 -0
  224. package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +149 -0
  225. package/dist/global-skills/firebase-auth-basics/references/ios_setup.md +87 -0
  226. package/dist/global-skills/firebase-auth-basics/references/security_rules.md +49 -0
  227. package/dist/global-skills/firebase-basics/SKILL.md +148 -0
  228. package/dist/global-skills/firebase-basics/references/android_setup.md +41 -0
  229. package/dist/global-skills/firebase-basics/references/firebase-cli-guide.md +18 -0
  230. package/dist/global-skills/firebase-basics/references/firebase-service-init.md +20 -0
  231. package/dist/global-skills/firebase-basics/references/flutter_setup.md +143 -0
  232. package/dist/global-skills/firebase-basics/references/ios_setup.md +113 -0
  233. package/dist/global-skills/firebase-basics/references/local-env-setup.md +80 -0
  234. package/dist/global-skills/firebase-basics/references/refresh/android_studio.md +41 -0
  235. package/dist/global-skills/firebase-basics/references/refresh/antigravity.md +64 -0
  236. package/dist/global-skills/firebase-basics/references/refresh/claude.md +12 -0
  237. package/dist/global-skills/firebase-basics/references/refresh/gemini-cli.md +13 -0
  238. package/dist/global-skills/firebase-basics/references/refresh/other-agents.md +67 -0
  239. package/dist/global-skills/firebase-basics/references/setup/android_studio.md +23 -0
  240. package/dist/global-skills/firebase-basics/references/setup/antigravity.md +98 -0
  241. package/dist/global-skills/firebase-basics/references/setup/claude_code.md +45 -0
  242. package/dist/global-skills/firebase-basics/references/setup/cursor.md +93 -0
  243. package/dist/global-skills/firebase-basics/references/setup/gemini_cli.md +53 -0
  244. package/dist/global-skills/firebase-basics/references/setup/github_copilot.md +104 -0
  245. package/dist/global-skills/firebase-basics/references/setup/other_agents.md +99 -0
  246. package/dist/global-skills/firebase-basics/references/web_setup.md +77 -0
  247. package/dist/global-skills/firebase-crashlytics/SKILL.md +42 -0
  248. package/dist/global-skills/firebase-crashlytics/references/android_setup.md +152 -0
  249. package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +115 -0
  250. package/dist/global-skills/firebase-data-connect/SKILL.md +191 -0
  251. package/dist/global-skills/firebase-data-connect/examples.md +638 -0
  252. package/dist/global-skills/firebase-data-connect/reference/cloud_functions.md +184 -0
  253. package/dist/global-skills/firebase-data-connect/reference/config.md +271 -0
  254. package/dist/global-skills/firebase-data-connect/reference/data_seeding.md +185 -0
  255. package/dist/global-skills/firebase-data-connect/reference/native_sql.md +170 -0
  256. package/dist/global-skills/firebase-data-connect/reference/operations.md +385 -0
  257. package/dist/global-skills/firebase-data-connect/reference/realtime.md +210 -0
  258. package/dist/global-skills/firebase-data-connect/reference/schema.md +290 -0
  259. package/dist/global-skills/firebase-data-connect/reference/sdk_admin_node.md +141 -0
  260. package/dist/global-skills/firebase-data-connect/reference/sdk_android.md +126 -0
  261. package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +134 -0
  262. package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +157 -0
  263. package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +146 -0
  264. package/dist/global-skills/firebase-data-connect/reference/search.md +264 -0
  265. package/dist/global-skills/firebase-data-connect/reference/security.md +295 -0
  266. package/dist/global-skills/firebase-data-connect/templates.md +318 -0
  267. package/dist/global-skills/firebase-firestore/SKILL.md +89 -0
  268. package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +230 -0
  269. package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +66 -0
  270. package/dist/global-skills/firebase-firestore/references/enterprise/flutter_setup.md +180 -0
  271. package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +135 -0
  272. package/dist/global-skills/firebase-firestore/references/enterprise/ios_setup.md +189 -0
  273. package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +118 -0
  274. package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +138 -0
  275. package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +577 -0
  276. package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +127 -0
  277. package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +193 -0
  278. package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +176 -0
  279. package/dist/global-skills/firebase-firestore/references/standard/indexes.md +113 -0
  280. package/dist/global-skills/firebase-firestore/references/standard/ios_setup.md +174 -0
  281. package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +110 -0
  282. package/dist/global-skills/firebase-firestore/references/standard/security_rules.md +577 -0
  283. package/dist/global-skills/firebase-firestore/references/standard/web_sdk_usage.md +192 -0
  284. package/dist/global-skills/firebase-hosting-basics/SKILL.md +64 -0
  285. package/dist/global-skills/firebase-hosting-basics/references/configuration.md +115 -0
  286. package/dist/global-skills/firebase-hosting-basics/references/deploying.md +48 -0
  287. package/dist/global-skills/firebase-remote-config-basics/SKILL.md +124 -0
  288. package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +91 -0
  289. package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +89 -0
  290. package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +70 -0
  291. package/dist/global-skills/go-live/SKILL.md +90 -0
  292. package/dist/global-skills/harden/SKILL.md +101 -0
  293. package/dist/global-skills/instrument-feature-flags/SKILL.md +88 -0
  294. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +3578 -0
  295. package/dist/global-skills/instrument-feature-flags/references/android.md +146 -0
  296. package/dist/global-skills/instrument-feature-flags/references/api.md +194 -0
  297. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +231 -0
  298. package/dist/global-skills/instrument-feature-flags/references/django.md +263 -0
  299. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +763 -0
  300. package/dist/global-skills/instrument-feature-flags/references/elixir.md +47 -0
  301. package/dist/global-skills/instrument-feature-flags/references/flask.md +131 -0
  302. package/dist/global-skills/instrument-feature-flags/references/flutter.md +212 -0
  303. package/dist/global-skills/instrument-feature-flags/references/go.md +208 -0
  304. package/dist/global-skills/instrument-feature-flags/references/ios.md +146 -0
  305. package/dist/global-skills/instrument-feature-flags/references/java.md +94 -0
  306. package/dist/global-skills/instrument-feature-flags/references/laravel.md +170 -0
  307. package/dist/global-skills/instrument-feature-flags/references/next-js.md +383 -0
  308. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +216 -0
  309. package/dist/global-skills/instrument-feature-flags/references/php.md +187 -0
  310. package/dist/global-skills/instrument-feature-flags/references/python.md +191 -0
  311. package/dist/global-skills/instrument-feature-flags/references/react-native.md +166 -0
  312. package/dist/global-skills/instrument-feature-flags/references/react.md +302 -0
  313. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +604 -0
  314. package/dist/global-skills/instrument-feature-flags/references/ruby.md +200 -0
  315. package/dist/global-skills/instrument-feature-flags/references/rust.md +222 -0
  316. package/dist/global-skills/instrument-feature-flags/references/usage.md +600 -0
  317. package/dist/global-skills/instrument-feature-flags/references/web.md +193 -0
  318. package/dist/global-skills/instrument-product-analytics/SKILL.md +139 -0
  319. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-android.md +1639 -0
  320. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-angular.md +944 -0
  321. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +1001 -0
  322. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +1004 -0
  323. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +720 -0
  324. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +810 -0
  325. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +1167 -0
  326. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-expo.md +1412 -0
  327. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +1585 -0
  328. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +1208 -0
  329. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-laravel.md +2267 -0
  330. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-next-app-router.md +712 -0
  331. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-next-pages-router.md +767 -0
  332. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +939 -0
  333. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +1078 -0
  334. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-php.md +527 -0
  335. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-python.md +481 -0
  336. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-native.md +1823 -0
  337. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-6.md +582 -0
  338. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-data.md +892 -0
  339. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-declarative.md +649 -0
  340. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +1218 -0
  341. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-tanstack-router-code-based.md +793 -0
  342. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-tanstack-router-file-based.md +780 -0
  343. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +1320 -0
  344. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby.md +452 -0
  345. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-sveltekit.md +854 -0
  346. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-swift.md +665 -0
  347. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +1199 -0
  348. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-vue-3.md +910 -0
  349. package/dist/global-skills/instrument-product-analytics/references/android.md +811 -0
  350. package/dist/global-skills/instrument-product-analytics/references/angular.md +376 -0
  351. package/dist/global-skills/instrument-product-analytics/references/astro.md +165 -0
  352. package/dist/global-skills/instrument-product-analytics/references/configuration.md +299 -0
  353. package/dist/global-skills/instrument-product-analytics/references/django.md +263 -0
  354. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +763 -0
  355. package/dist/global-skills/instrument-product-analytics/references/elixir.md +414 -0
  356. package/dist/global-skills/instrument-product-analytics/references/flask.md +131 -0
  357. package/dist/global-skills/instrument-product-analytics/references/flutter.md +845 -0
  358. package/dist/global-skills/instrument-product-analytics/references/go.md +567 -0
  359. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +272 -0
  360. package/dist/global-skills/instrument-product-analytics/references/ios.md +154 -0
  361. package/dist/global-skills/instrument-product-analytics/references/laravel.md +170 -0
  362. package/dist/global-skills/instrument-product-analytics/references/next-js.md +383 -0
  363. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +244 -0
  364. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +253 -0
  365. package/dist/global-skills/instrument-product-analytics/references/php.md +646 -0
  366. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +1675 -0
  367. package/dist/global-skills/instrument-product-analytics/references/python.md +898 -0
  368. package/dist/global-skills/instrument-product-analytics/references/react-native.md +1338 -0
  369. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +376 -0
  370. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +364 -0
  371. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +376 -0
  372. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +479 -0
  373. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +604 -0
  374. package/dist/global-skills/instrument-product-analytics/references/ruby.md +759 -0
  375. package/dist/global-skills/instrument-product-analytics/references/svelte.md +234 -0
  376. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +193 -0
  377. package/dist/global-skills/instrument-product-analytics/references/usage.md +600 -0
  378. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +306 -0
  379. package/dist/global-skills/manifest.json +125 -0
  380. package/dist/global-skills/mongodb-atlas-stream-processing/SKILL.md +284 -0
  381. package/dist/global-skills/mongodb-atlas-stream-processing/references/connection-configs.md +298 -0
  382. package/dist/global-skills/mongodb-atlas-stream-processing/references/development-workflow.md +304 -0
  383. package/dist/global-skills/mongodb-atlas-stream-processing/references/mcp-troubleshooting.md +55 -0
  384. package/dist/global-skills/mongodb-atlas-stream-processing/references/output-diagnostics.md +150 -0
  385. package/dist/global-skills/mongodb-atlas-stream-processing/references/pipeline-patterns.md +457 -0
  386. package/dist/global-skills/mongodb-atlas-stream-processing/references/sizing-and-parallelism.md +178 -0
  387. package/dist/global-skills/mongodb-connection/SKILL.md +201 -0
  388. package/dist/global-skills/mongodb-connection/references/monitoring-guide.md +191 -0
  389. package/dist/global-skills/mongodb-mcp-setup/SKILL.md +324 -0
  390. package/dist/global-skills/mongodb-natural-language-querying/SKILL.md +195 -0
  391. package/dist/global-skills/mongodb-query-optimizer/SKILL.md +150 -0
  392. package/dist/global-skills/mongodb-query-optimizer/references/aggregation-optimization.md +210 -0
  393. package/dist/global-skills/mongodb-query-optimizer/references/antipattern-examples.md +74 -0
  394. package/dist/global-skills/mongodb-query-optimizer/references/core-indexing-principles.md +134 -0
  395. package/dist/global-skills/mongodb-query-optimizer/references/update-query-examples.md +39 -0
  396. package/dist/global-skills/mongodb-schema-design/SKILL.md +181 -0
  397. package/dist/global-skills/mongodb-schema-design/references/antipattern-excessive-lookups.md +84 -0
  398. package/dist/global-skills/mongodb-schema-design/references/antipattern-unnecessary-collections.md +91 -0
  399. package/dist/global-skills/mongodb-schema-design/references/antipattern-unnecessary-indexes.md +95 -0
  400. package/dist/global-skills/mongodb-schema-design/references/fundamental-document-model.md +91 -0
  401. package/dist/global-skills/mongodb-schema-design/references/fundamental-document-size.md +226 -0
  402. package/dist/global-skills/mongodb-schema-design/references/fundamental-embed-vs-reference.md +418 -0
  403. package/dist/global-skills/mongodb-schema-design/references/fundamental-schema-validation.md +131 -0
  404. package/dist/global-skills/mongodb-schema-design/references/pattern-approximation.md +80 -0
  405. package/dist/global-skills/mongodb-schema-design/references/pattern-archive.md +143 -0
  406. package/dist/global-skills/mongodb-schema-design/references/pattern-attribute.md +77 -0
  407. package/dist/global-skills/mongodb-schema-design/references/pattern-bucket.md +102 -0
  408. package/dist/global-skills/mongodb-schema-design/references/pattern-computed.md +162 -0
  409. package/dist/global-skills/mongodb-schema-design/references/pattern-document-versioning.md +166 -0
  410. package/dist/global-skills/mongodb-schema-design/references/pattern-extended-reference.md +72 -0
  411. package/dist/global-skills/mongodb-schema-design/references/pattern-outlier.md +159 -0
  412. package/dist/global-skills/mongodb-schema-design/references/pattern-polymorphic.md +167 -0
  413. package/dist/global-skills/mongodb-schema-design/references/pattern-schema-versioning.md +273 -0
  414. package/dist/global-skills/mongodb-schema-design/references/pattern-time-series-collections.md +190 -0
  415. package/dist/global-skills/mongodb-schema-design/references/source-query-stats.md +123 -0
  416. package/dist/global-skills/mongodb-schema-design/references/source-slow-query-logs.md +63 -0
  417. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +142 -0
  418. package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +697 -0
  419. package/dist/global-skills/mongodb-search-and-ai/references/lexical-search-indexing.md +584 -0
  420. package/dist/global-skills/mongodb-search-and-ai/references/lexical-search-querying.md +636 -0
  421. package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +746 -0
  422. package/dist/global-skills/native-data-fetching/SKILL.md +505 -0
  423. package/dist/global-skills/native-data-fetching/agents/openai.yaml +4 -0
  424. package/dist/global-skills/native-data-fetching/references/expo-router-loaders.md +341 -0
  425. package/dist/global-skills/neon/SKILL.md +343 -0
  426. package/dist/global-skills/neon-ai-gateway/SKILL.md +236 -0
  427. package/dist/global-skills/neon-functions/SKILL.md +490 -0
  428. package/dist/global-skills/neon-functions/references/ai-sdk.md +139 -0
  429. package/dist/global-skills/neon-functions/references/hono-websockets.md +145 -0
  430. package/dist/global-skills/neon-functions/references/mastra-studio.md +127 -0
  431. package/dist/global-skills/neon-functions/references/mcp.md +137 -0
  432. package/dist/global-skills/neon-functions/references/sentry.md +131 -0
  433. package/dist/global-skills/neon-functions/references/sse.md +143 -0
  434. package/dist/global-skills/neon-object-storage/SKILL.md +197 -0
  435. package/dist/global-skills/neon-postgres/SKILL.md +376 -0
  436. package/dist/global-skills/neon-postgres-branches/SKILL.md +281 -0
  437. package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +247 -0
  438. package/dist/global-skills/onboarding/SKILL.md +101 -0
  439. package/dist/global-skills/plan-my-idea/SKILL.md +67 -0
  440. package/dist/global-skills/publish-app/SKILL.md +72 -0
  441. package/dist/global-skills/publish-extension/SKILL.md +47 -0
  442. package/dist/global-skills/resend/SKILL.md +294 -0
  443. package/dist/global-skills/resend/references/api-keys.md +98 -0
  444. package/dist/global-skills/resend/references/automations.md +228 -0
  445. package/dist/global-skills/resend/references/broadcasts.md +125 -0
  446. package/dist/global-skills/resend/references/contact-properties.md +111 -0
  447. package/dist/global-skills/resend/references/contacts.md +174 -0
  448. package/dist/global-skills/resend/references/domains.md +179 -0
  449. package/dist/global-skills/resend/references/events.md +119 -0
  450. package/dist/global-skills/resend/references/fetch-all-templates.mjs +37 -0
  451. package/dist/global-skills/resend/references/installation.md +142 -0
  452. package/dist/global-skills/resend/references/logs.md +161 -0
  453. package/dist/global-skills/resend/references/receiving.md +287 -0
  454. package/dist/global-skills/resend/references/segments.md +77 -0
  455. package/dist/global-skills/resend/references/sending/batch-email-examples.md +807 -0
  456. package/dist/global-skills/resend/references/sending/best-practices.md +453 -0
  457. package/dist/global-skills/resend/references/sending/email-management.md +135 -0
  458. package/dist/global-skills/resend/references/sending/overview.md +209 -0
  459. package/dist/global-skills/resend/references/sending/single-email-examples.md +470 -0
  460. package/dist/global-skills/resend/references/templates.md +202 -0
  461. package/dist/global-skills/resend/references/topics.md +104 -0
  462. package/dist/global-skills/resend/references/webhooks.md +317 -0
  463. package/dist/global-skills/reset-password/SKILL.md +59 -0
  464. package/dist/global-skills/save-data/SKILL.md +70 -0
  465. package/dist/global-skills/sentry-sdk-setup/SKILL.md +116 -0
  466. package/dist/global-skills/sentry-workflow/SKILL.md +32 -0
  467. package/dist/global-skills/setup-email/SKILL.md +69 -0
  468. package/dist/global-skills/setup-payments/SKILL.md +82 -0
  469. package/dist/global-skills/setup-sms/SKILL.md +51 -0
  470. package/dist/global-skills/sign-in-with-email-link/SKILL.md +53 -0
  471. package/dist/global-skills/sign-in-with-google/SKILL.md +68 -0
  472. package/dist/global-skills/sign-in-with-phone/SKILL.md +53 -0
  473. package/dist/global-skills/stripe-best-practices/SKILL.md +48 -0
  474. package/dist/global-skills/stripe-best-practices/references/billing.md +58 -0
  475. package/dist/global-skills/stripe-best-practices/references/connect.md +173 -0
  476. package/dist/global-skills/stripe-best-practices/references/payments.md +79 -0
  477. package/dist/global-skills/stripe-best-practices/references/security.md +109 -0
  478. package/dist/global-skills/stripe-best-practices/references/tax.md +37 -0
  479. package/dist/global-skills/stripe-best-practices/references/treasury.md +16 -0
  480. package/dist/global-skills/supabase/CHANGELOG.md +53 -0
  481. package/dist/global-skills/supabase/SKILL.md +145 -0
  482. package/dist/global-skills/supabase/assets/feedback-issue-template.md +17 -0
  483. package/dist/global-skills/supabase/references/skill-feedback.md +17 -0
  484. package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +43 -0
  485. package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +64 -0
  486. package/dist/global-skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
  487. package/dist/global-skills/supabase-postgres-best-practices/references/_sections.md +39 -0
  488. package/dist/global-skills/supabase-postgres-best-practices/references/_template.md +34 -0
  489. package/dist/global-skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  490. package/dist/global-skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  491. package/dist/global-skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  492. package/dist/global-skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  493. package/dist/global-skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  494. package/dist/global-skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  495. package/dist/global-skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  496. package/dist/global-skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  497. package/dist/global-skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  498. package/dist/global-skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  499. package/dist/global-skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  500. package/dist/global-skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  501. package/dist/global-skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  502. package/dist/global-skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  503. package/dist/global-skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  504. package/dist/global-skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  505. package/dist/global-skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  506. package/dist/global-skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  507. package/dist/global-skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  508. package/dist/global-skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  509. package/dist/global-skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  510. package/dist/global-skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  511. package/dist/global-skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  512. package/dist/global-skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  513. package/dist/global-skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  514. package/dist/global-skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  515. package/dist/global-skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  516. package/dist/global-skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  517. package/dist/global-skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  518. package/dist/global-skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  519. package/dist/global-skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
  520. package/dist/global-skills/track-errors/SKILL.md +67 -0
  521. package/dist/global-skills/update-kit/SKILL.md +75 -0
  522. package/dist/global-skills/upgrading-expo/SKILL.md +134 -0
  523. package/dist/global-skills/upgrading-expo/agents/openai.yaml +4 -0
  524. package/dist/global-skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
  525. package/dist/global-skills/upgrading-expo/references/expo-av-to-video.md +160 -0
  526. package/dist/global-skills/upgrading-expo/references/native-tabs.md +124 -0
  527. package/dist/global-skills/upgrading-expo/references/new-architecture.md +79 -0
  528. package/dist/global-skills/upgrading-expo/references/react-19.md +79 -0
  529. package/dist/global-skills/upgrading-expo/references/react-compiler.md +59 -0
  530. package/dist/global-skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
  531. package/dist/global-skills/use-dom/SKILL.md +417 -0
  532. package/dist/global-skills/use-dom/agents/openai.yaml +4 -0
  533. package/dist/global-skills/use-kit-mcp/SKILL.md +100 -0
  534. package/dist/global-skills/use-railway/SKILL.md +357 -0
  535. package/dist/global-skills/use-railway/references/analyze-db-mongo.md +84 -0
  536. package/dist/global-skills/use-railway/references/analyze-db-mysql.md +254 -0
  537. package/dist/global-skills/use-railway/references/analyze-db-postgres.md +479 -0
  538. package/dist/global-skills/use-railway/references/analyze-db-redis.md +208 -0
  539. package/dist/global-skills/use-railway/references/analyze-db.md +344 -0
  540. package/dist/global-skills/use-railway/references/configure.md +359 -0
  541. package/dist/global-skills/use-railway/references/deploy.md +225 -0
  542. package/dist/global-skills/use-railway/references/feature-flags.md +89 -0
  543. package/dist/global-skills/use-railway/references/iac.md +108 -0
  544. package/dist/global-skills/use-railway/references/operate.md +273 -0
  545. package/dist/global-skills/use-railway/references/request.md +262 -0
  546. package/dist/global-skills/use-railway/references/sandbox.md +167 -0
  547. package/dist/global-skills/use-railway/references/setup.md +364 -0
  548. package/dist/global-skills/use-railway/scripts/analyze-mongo.py +1549 -0
  549. package/dist/global-skills/use-railway/scripts/analyze-mysql.py +1195 -0
  550. package/dist/global-skills/use-railway/scripts/analyze-postgres.py +3058 -0
  551. package/dist/global-skills/use-railway/scripts/analyze-redis.py +1090 -0
  552. package/dist/global-skills/use-railway/scripts/dal.py +671 -0
  553. package/dist/global-skills/use-railway/scripts/enable-pg-stats.py +170 -0
  554. package/dist/global-skills/use-railway/scripts/pg-extensions.py +370 -0
  555. package/dist/global-skills/use-railway/scripts/railway-api.sh +52 -0
  556. package/dist/global-skills/vercel-composition-patterns/AGENTS.md +946 -0
  557. package/dist/global-skills/vercel-composition-patterns/README.md +60 -0
  558. package/dist/global-skills/vercel-composition-patterns/SKILL.md +89 -0
  559. package/dist/global-skills/vercel-composition-patterns/metadata.json +11 -0
  560. package/dist/global-skills/vercel-composition-patterns/rules/_sections.md +29 -0
  561. package/dist/global-skills/vercel-composition-patterns/rules/_template.md +24 -0
  562. package/dist/global-skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  563. package/dist/global-skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  564. package/dist/global-skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  565. package/dist/global-skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  566. package/dist/global-skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  567. package/dist/global-skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  568. package/dist/global-skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  569. package/dist/global-skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  570. package/dist/global-skills/vercel-react-best-practices/AGENTS.md +3810 -0
  571. package/dist/global-skills/vercel-react-best-practices/README.md +123 -0
  572. package/dist/global-skills/vercel-react-best-practices/SKILL.md +149 -0
  573. package/dist/global-skills/vercel-react-best-practices/metadata.json +15 -0
  574. package/dist/global-skills/vercel-react-best-practices/rules/_sections.md +46 -0
  575. package/dist/global-skills/vercel-react-best-practices/rules/_template.md +28 -0
  576. package/dist/global-skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
  577. package/dist/global-skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  578. package/dist/global-skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  579. package/dist/global-skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  580. package/dist/global-skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  581. package/dist/global-skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  582. package/dist/global-skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
  583. package/dist/global-skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  584. package/dist/global-skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  585. package/dist/global-skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  586. package/dist/global-skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md +63 -0
  587. package/dist/global-skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
  588. package/dist/global-skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  589. package/dist/global-skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  590. package/dist/global-skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  591. package/dist/global-skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  592. package/dist/global-skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  593. package/dist/global-skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  594. package/dist/global-skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  595. package/dist/global-skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  596. package/dist/global-skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  597. package/dist/global-skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  598. package/dist/global-skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  599. package/dist/global-skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  600. package/dist/global-skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  601. package/dist/global-skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  602. package/dist/global-skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
  603. package/dist/global-skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  604. package/dist/global-skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  605. package/dist/global-skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  606. package/dist/global-skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  607. package/dist/global-skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
  608. package/dist/global-skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  609. package/dist/global-skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  610. package/dist/global-skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  611. package/dist/global-skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  612. package/dist/global-skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  613. package/dist/global-skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  614. package/dist/global-skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  615. package/dist/global-skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  616. package/dist/global-skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  617. package/dist/global-skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
  618. package/dist/global-skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
  619. package/dist/global-skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  620. package/dist/global-skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  621. package/dist/global-skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  622. package/dist/global-skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  623. package/dist/global-skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  624. package/dist/global-skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  625. package/dist/global-skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  626. package/dist/global-skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  627. package/dist/global-skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  628. package/dist/global-skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  629. package/dist/global-skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  630. package/dist/global-skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
  631. package/dist/global-skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  632. package/dist/global-skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  633. package/dist/global-skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  634. package/dist/global-skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  635. package/dist/global-skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  636. package/dist/global-skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  637. package/dist/global-skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  638. package/dist/global-skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  639. package/dist/global-skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  640. package/dist/global-skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  641. package/dist/global-skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
  642. package/dist/global-skills/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
  643. package/dist/global-skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  644. package/dist/global-skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
  645. package/dist/global-skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  646. package/dist/global-skills/web-to-native/SKILL.md +83 -0
  647. package/dist/global-skills/web-to-native/references/false-friends.md +119 -0
  648. package/dist/global-skills/web-to-native/references/native-patterns.md +39 -0
  649. package/dist/global-skills/web-to-native/references/run-as-goal.md +48 -0
  650. package/dist/global-skills/web-to-native/references/verify-on-device.md +45 -0
  651. package/dist/global-skills/wire-auth/SKILL.md +28 -0
  652. package/dist/global-skills/wire-database/SKILL.md +28 -0
  653. package/dist/global-skills/wire-email/SKILL.md +27 -0
  654. package/dist/global-skills/wire-payments/SKILL.md +27 -0
  655. package/dist/global-skills/workers-best-practices/SKILL.md +127 -0
  656. package/dist/global-skills/workers-best-practices/references/review.md +174 -0
  657. package/dist/global-skills/workers-best-practices/references/rules.md +463 -0
  658. package/dist/global-skills/wrangler/SKILL.md +922 -0
  659. package/dist/global-skills/xcode-project-setup/SKILL.md +140 -0
  660. package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Package.resolved +41 -0
  661. package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Package.swift +17 -0
  662. package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +232 -0
  663. package/package.json +21 -20
  664. package/LICENSE.md +0 -47
  665. package/dist/index.js +0 -21593
@@ -0,0 +1,1639 @@
1
+ # PostHog android Example Project
2
+
3
+ Repository: https://github.com/PostHog/context-mill
4
+ Path: example-apps/android
5
+
6
+ ---
7
+
8
+ ## README.md
9
+
10
+ # PostHog Android example
11
+
12
+ This is an Android example demonstrating PostHog integration with product analytics, session replay, and error tracking using Kotlin and Jetpack Compose.
13
+
14
+ This example uses the PostHog Android SDK (`posthog-android`) to provide automatic PostHog integration with built-in error tracking, session replay, and simplified configuration.
15
+
16
+ ## Features
17
+
18
+ - **Product Analytics**: Track user events and behaviors
19
+ - **Session Replay**: Record and replay user sessions
20
+ - **Error Tracking**: Automatic error capture and crash reporting
21
+ - **User Authentication**: Demo login system with PostHog user identification
22
+ - **Event Tracking**: Examples of custom event tracking throughout the app
23
+
24
+ ## Getting Started
25
+
26
+ ### 1. Prerequisites
27
+
28
+ - Android Studio (latest stable version)
29
+ - Android SDK (API level 24 or higher)
30
+ - JDK 11 or higher
31
+ - Gradle 8.0 or higher
32
+ - A [PostHog account](https://app.posthog.com/signup)
33
+
34
+ ### 2. Configure Environment Variables
35
+
36
+ The PostHog configuration is stored in `local.properties` (this file is gitignored):
37
+
38
+ ```properties
39
+ # PostHog configuration
40
+ posthog.apiKey=your_posthog_project_token
41
+ posthog.host=https://us.i.posthog.com
42
+ ```
43
+
44
+ Alternatively, you can configure PostHog in your `build.gradle` file:
45
+
46
+ ```gradle
47
+ android {
48
+ defaultConfig {
49
+ buildConfigField "String", "POSTHOG_PROJECT_TOKEN", "\"your_posthog_project_token\""
50
+ buildConfigField "String", "POSTHOG_HOST", "\"https://us.i.posthog.com\""
51
+ }
52
+ }
53
+ ```
54
+
55
+ Get your PostHog project token from your [PostHog project settings](https://app.posthog.com/project/settings).
56
+
57
+ ### 3. Build and Run
58
+
59
+ 1. Open the project in Android Studio
60
+ 2. Sync Gradle files
61
+ 3. Run the app on an emulator or physical device
62
+
63
+ ## Project Structure
64
+
65
+ ```
66
+ ├── app/
67
+ │ ├── src/
68
+ │ │ ├── main/
69
+ │ │ │ ├── java/com/example/posthog/
70
+ │ │ │ │ ├── BurritoApplication.kt # Application class with PostHog initialization
71
+ │ │ │ │ ├── MainActivity.kt # Main activity
72
+ │ │ │ │ ├── ui/
73
+ │ │ │ │ │ ├── screens/
74
+ │ │ │ │ │ │ ├── LoginScreen.kt # Login screen with user identification
75
+ │ │ │ │ │ │ ├── BurritoScreen.kt # Demo feature screen with event tracking
76
+ │ │ │ │ │ │ └── ProfileScreen.kt # User profile with error tracking demo
77
+ │ │ │ │ │ └── components/ # Reusable UI components
78
+ │ │ │ │ └── utils/
79
+ │ │ │ │ └── PostHogHelper.kt # PostHog utility functions
80
+ │ │ │ ├── res/ # Resources (layouts, strings, etc.)
81
+ │ │ │ └── AndroidManifest.xml # App manifest
82
+ │ │ └── test/ # Unit tests
83
+ │ └── build.gradle # App-level Gradle configuration
84
+ ├── build.gradle # Project-level Gradle configuration
85
+ ├── settings.gradle # Gradle settings
86
+ └── local.properties # Local configuration (gitignored)
87
+ ```
88
+
89
+ ## Key Integration Points
90
+
91
+ ### Application Initialization (BurritoApplication.kt)
92
+
93
+ PostHog is initialized in the `Application` class to ensure it's available throughout the app lifecycle:
94
+
95
+ ```kotlin
96
+ class BurritoApplication : Application() {
97
+ override fun onCreate() {
98
+ super.onCreate()
99
+
100
+ val posthogConfig = PostHogConfig(
101
+ apiKey = BuildConfig.POSTHOG_PROJECT_TOKEN,
102
+ host = BuildConfig.POSTHOG_HOST
103
+ ).apply {
104
+ // Enable session replay
105
+ sessionReplay = true
106
+
107
+ // Enable automatic exception capture
108
+ captureApplicationLifecycleEvents = true
109
+ captureDeepLinks = true
110
+ captureScreenViews = true
111
+ }
112
+
113
+ PostHog.setup(this, posthogConfig)
114
+ }
115
+ }
116
+ ```
117
+
118
+ **Key Points:**
119
+ - PostHog is initialized in `onCreate()` to ensure it's initialized as early as possible
120
+ - Configuration is loaded from `BuildConfig` (set in `build.gradle`)
121
+ - Session replay, lifecycle events, and screen views are enabled
122
+ - The Application class must be registered in `AndroidManifest.xml`
123
+
124
+ ### User Identification (LoginScreen.kt)
125
+
126
+ Users are identified when they log in:
127
+
128
+ ```kotlin
129
+ val posthog = PostHog.getInstance()
130
+
131
+ fun handleLogin(username: String, password: String) {
132
+ // Authenticate user
133
+ val success = authenticateUser(username, password)
134
+
135
+ if (success) {
136
+ // Identify the user once on login/sign up
137
+ posthog.identify(
138
+ distinctId = username,
139
+ properties = mapOf(
140
+ "username" to username,
141
+ "login_method" to "password"
142
+ )
143
+ )
144
+
145
+ // Capture login event
146
+ posthog.capture("user_logged_in", mapOf(
147
+ "username" to username
148
+ ))
149
+ }
150
+ }
151
+ ```
152
+
153
+ **Key Points:**
154
+ - `identify()` is called once when the user logs in or signs up
155
+ - User properties can be set during identification
156
+ - Events are captured using `capture()` with event names and properties
157
+ - The `distinctId` should be a unique identifier for the user
158
+
159
+ ### Event Tracking (BurritoScreen.kt)
160
+
161
+ Custom events are tracked throughout the app:
162
+
163
+ ```kotlin
164
+ val posthog = PostHog.getInstance()
165
+
166
+ fun handleBurritoConsideration() {
167
+ // Track custom event
168
+ posthog.capture("burrito_considered", mapOf(
169
+ "total_considerations" to considerationCount,
170
+ "username" to currentUser.username,
171
+ "timestamp" to System.currentTimeMillis()
172
+ ))
173
+
174
+ // Update user properties
175
+ posthog.setUserProperties(mapOf(
176
+ "last_burrito_consideration" to System.currentTimeMillis(),
177
+ "total_burrito_considerations" to considerationCount
178
+ ))
179
+ }
180
+ ```
181
+
182
+ **Key Points:**
183
+ - Events are captured with `capture()` method
184
+ - Event properties provide context about the event
185
+ - User properties can be updated with `setUserProperties()`
186
+ - Properties can be strings, numbers, booleans, or dates
187
+
188
+ ### Error Tracking
189
+
190
+ Errors are captured automatically and can also be tracked manually:
191
+
192
+ **Automatic Error Capture:**
193
+ PostHog automatically captures uncaught exceptions when configured:
194
+
195
+ ```kotlin
196
+ val posthogConfig = PostHogConfig(
197
+ apiKey = BuildConfig.POSTHOG_PROJECT_TOKEN,
198
+ host = BuildConfig.POSTHOG_HOST
199
+ ).apply {
200
+ // Automatic exception capture is enabled by default
201
+ captureApplicationLifecycleEvents = true
202
+ }
203
+ ```
204
+
205
+ **Manual Error Capture:**
206
+ ```kotlin
207
+ val posthog = PostHog.getInstance()
208
+
209
+ try {
210
+ // Risky operation
211
+ performRiskyOperation()
212
+ } catch (e: Exception) {
213
+ // Capture exception manually
214
+ posthog.captureException(e, mapOf(
215
+ "context" to "burrito_consideration",
216
+ "user_id" to currentUser.id
217
+ ))
218
+ }
219
+ ```
220
+
221
+ ### Screen View Tracking
222
+
223
+ Screen views are automatically tracked when `captureScreenViews` is enabled. You can also manually track screen views:
224
+
225
+ ```kotlin
226
+ val posthog = PostHog.getInstance()
227
+
228
+ // Manual screen view tracking
229
+ posthog.screen("BurritoScreen", mapOf(
230
+ "screen_category" to "features",
231
+ "user_type" to "premium"
232
+ ))
233
+ ```
234
+
235
+ ### Session Replay
236
+
237
+ Session replay is enabled in the PostHog configuration:
238
+
239
+ ```kotlin
240
+ val posthogConfig = PostHogConfig(
241
+ apiKey = BuildConfig.POSTHOG_PROJECT_TOKEN,
242
+ host = BuildConfig.POSTHOG_HOST
243
+ ).apply {
244
+ sessionReplay = true
245
+ sessionReplayConfig = SessionReplayConfig(
246
+ maskAllInputs = false, // Set to true to mask all input fields
247
+ maskAllText = false // Set to true to mask all text
248
+ )
249
+ }
250
+ ```
251
+
252
+ ### Accessing PostHog in Components
253
+
254
+ PostHog is accessed via the singleton instance:
255
+
256
+ ```kotlin
257
+ val posthog = PostHog.getInstance()
258
+ posthog.capture("event_name", mapOf("property" to "value"))
259
+ ```
260
+
261
+ The instance is available throughout your application after initialization.
262
+
263
+ ## Gradle Configuration
264
+
265
+ ### App-level build.gradle
266
+
267
+ ```gradle
268
+ android {
269
+ defaultConfig {
270
+ // PostHog configuration
271
+ buildConfigField "String", "POSTHOG_PROJECT_TOKEN", "\"${project.findProperty("posthog.apiKey") ?: ""}\""
272
+ buildConfigField "String", "POSTHOG_HOST", "\"${project.findProperty("posthog.host") ?: "https://us.i.posthog.com"}\""
273
+ }
274
+ }
275
+
276
+ dependencies {
277
+ // PostHog Android SDK
278
+ implementation 'com.posthog:posthog-android:3.+'
279
+
280
+ // Other dependencies...
281
+ }
282
+ ```
283
+
284
+ ### Reading from local.properties
285
+
286
+ The `local.properties` file is automatically read by Gradle:
287
+
288
+ ```gradle
289
+ def localProperties = new Properties()
290
+ localProperties.load(new FileInputStream(rootProject.file("local.properties")))
291
+
292
+ android {
293
+ defaultConfig {
294
+ buildConfigField "String", "POSTHOG_PROJECT_TOKEN", "\"${localProperties.getProperty("posthog.apiKey", "")}\""
295
+ buildConfigField "String", "POSTHOG_HOST", "\"${localProperties.getProperty("posthog.host", "https://us.i.posthog.com")}\""
296
+ }
297
+ }
298
+ ```
299
+
300
+ ## Best Practices
301
+
302
+ 1. **Initialize Early**: Initialize PostHog in your `Application.onCreate()` method
303
+ 2. **Identify Once**: Call `identify()` once when the user logs in or signs up
304
+ 3. **Use Meaningful Event Names**: Use clear, descriptive event names (e.g., `user_logged_in` instead of `login`)
305
+ 4. **Include Context**: Add relevant properties to events for better analysis
306
+ 5. **Handle Errors Gracefully**: Don't let PostHog errors break your app
307
+ 6. **Test in Development**: Use a separate PostHog project for development/testing
308
+ 7. **Respect Privacy**: Be mindful of PII (Personally Identifiable Information) in events and properties
309
+
310
+ ## Learn More
311
+
312
+ - [PostHog Documentation](https://posthog.com/docs)
313
+ - [Android Documentation](https://developer.android.com)
314
+ - [PostHog Android Integration Guide](https://posthog.com/docs/libraries/android)
315
+ - [PostHog Android SDK](https://github.com/PostHog/posthog-android)
316
+
317
+ ---
318
+
319
+ ## app/src/main/java/com/example/posthog/BurritoApp.kt
320
+
321
+ ```kt
322
+ package com.example.posthog
323
+
324
+ import android.app.Application
325
+ import com.posthog.android.PostHogAndroid
326
+ import com.posthog.android.PostHogAndroidConfig
327
+
328
+ class BurritoApplication : Application() {
329
+ override fun onCreate() {
330
+ super.onCreate()
331
+
332
+ // Initialize PostHog early in Application lifecycle
333
+ val config = PostHogAndroidConfig(
334
+ apiKey = BuildConfig.POSTHOG_PROJECT_TOKEN,
335
+ host = BuildConfig.POSTHOG_HOST,
336
+ ).apply {
337
+ debug = true
338
+ errorTrackingConfig.autoCapture = true
339
+ }
340
+
341
+ PostHogAndroid.setup(this, config)
342
+ }
343
+ }
344
+
345
+ ```
346
+
347
+ ---
348
+
349
+ ## app/src/main/java/com/example/posthog/data/User.kt
350
+
351
+ ```kt
352
+ package com.example.posthog.data
353
+
354
+ data class User(
355
+ val username: String,
356
+ val burritoConsiderations: Int = 0
357
+ )
358
+
359
+ ```
360
+
361
+ ---
362
+
363
+ ## app/src/main/java/com/example/posthog/data/UserRepository.kt
364
+
365
+ ```kt
366
+ package com.example.posthog.data
367
+
368
+ import android.content.Context
369
+ import android.content.SharedPreferences
370
+ import org.json.JSONObject
371
+
372
+ class UserRepository(context: Context) {
373
+
374
+ private val prefs: SharedPreferences = context.getSharedPreferences(
375
+ PREFS_NAME, Context.MODE_PRIVATE
376
+ )
377
+
378
+ companion object {
379
+ private const val PREFS_NAME = "burrito_app_prefs"
380
+ private const val KEY_CURRENT_USERNAME = "current_username"
381
+ private const val KEY_USER_DATA_PREFIX = "user_data_"
382
+ }
383
+
384
+ fun getCurrentUsername(): String? {
385
+ return prefs.getString(KEY_CURRENT_USERNAME, null)
386
+ }
387
+
388
+ fun getUser(username: String): User? {
389
+ val json = prefs.getString("$KEY_USER_DATA_PREFIX$username", null) ?: return null
390
+ return try {
391
+ val obj = JSONObject(json)
392
+ User(
393
+ username = obj.getString("username"),
394
+ burritoConsiderations = obj.getInt("burritoConsiderations")
395
+ )
396
+ } catch (e: Exception) {
397
+ null
398
+ }
399
+ }
400
+
401
+ fun saveUser(user: User) {
402
+ val json = JSONObject().apply {
403
+ put("username", user.username)
404
+ put("burritoConsiderations", user.burritoConsiderations)
405
+ }.toString()
406
+
407
+ prefs.edit()
408
+ .putString("$KEY_USER_DATA_PREFIX${user.username}", json)
409
+ .putString(KEY_CURRENT_USERNAME, user.username)
410
+ .apply()
411
+ }
412
+
413
+ fun clearCurrentUser() {
414
+ prefs.edit()
415
+ .remove(KEY_CURRENT_USERNAME)
416
+ .apply()
417
+ }
418
+
419
+ fun getCurrentUser(): User? {
420
+ val username = getCurrentUsername() ?: return null
421
+ return getUser(username)
422
+ }
423
+ }
424
+
425
+ ```
426
+
427
+ ---
428
+
429
+ ## app/src/main/java/com/example/posthog/MainActivity.kt
430
+
431
+ ```kt
432
+ package com.example.posthog
433
+
434
+ import android.os.Bundle
435
+ import androidx.activity.ComponentActivity
436
+ import androidx.activity.compose.setContent
437
+ import androidx.activity.enableEdgeToEdge
438
+ import androidx.compose.foundation.background
439
+ import androidx.compose.foundation.layout.Box
440
+ import androidx.compose.foundation.layout.fillMaxSize
441
+ import androidx.compose.foundation.layout.padding
442
+ import androidx.compose.material3.Scaffold
443
+ import androidx.compose.runtime.Composable
444
+ import androidx.compose.runtime.collectAsState
445
+ import androidx.compose.runtime.getValue
446
+ import androidx.compose.ui.Modifier
447
+ import androidx.lifecycle.viewmodel.compose.viewModel
448
+ import androidx.navigation.compose.currentBackStackEntryAsState
449
+ import androidx.navigation.compose.rememberNavController
450
+ import com.example.posthog.navigation.NavGraph
451
+ import com.example.posthog.navigation.Screen
452
+ import com.example.posthog.ui.components.AppHeader
453
+ import com.example.posthog.ui.components.BottomNavBar
454
+ import com.example.posthog.ui.theme.BackgroundGray
455
+ import com.example.posthog.ui.theme.PostHogTheme
456
+ import com.example.posthog.viewmodel.AuthViewModel
457
+
458
+ class MainActivity : ComponentActivity() {
459
+ override fun onCreate(savedInstanceState: Bundle?) {
460
+ super.onCreate(savedInstanceState)
461
+ enableEdgeToEdge()
462
+ setContent {
463
+ PostHogTheme {
464
+ BurritoApp()
465
+ }
466
+ }
467
+ }
468
+ }
469
+
470
+ @Composable
471
+ fun BurritoApp() {
472
+ val navController = rememberNavController()
473
+ val viewModel: AuthViewModel = viewModel()
474
+
475
+ val isAuthenticated by viewModel.isAuthenticated.collectAsState()
476
+ val currentUser by viewModel.currentUser.collectAsState()
477
+
478
+ val navBackStackEntry by navController.currentBackStackEntryAsState()
479
+ val currentRoute = navBackStackEntry?.destination?.route
480
+
481
+ Scaffold(
482
+ modifier = Modifier.fillMaxSize(),
483
+ topBar = {
484
+ AppHeader(
485
+ isAuthenticated = isAuthenticated,
486
+ username = currentUser?.username,
487
+ currentRoute = currentRoute,
488
+ onNavigate = { route ->
489
+ navController.navigate(route) {
490
+ popUpTo(Screen.Home.route)
491
+ launchSingleTop = true
492
+ }
493
+ },
494
+ onLogout = {
495
+ viewModel.logout()
496
+ navController.navigate(Screen.Home.route) {
497
+ popUpTo(Screen.Home.route) { inclusive = true }
498
+ }
499
+ }
500
+ )
501
+ },
502
+ bottomBar = {
503
+ BottomNavBar(
504
+ isAuthenticated = isAuthenticated,
505
+ currentRoute = currentRoute,
506
+ onNavigate = { route ->
507
+ navController.navigate(route) {
508
+ popUpTo(Screen.Home.route)
509
+ launchSingleTop = true
510
+ }
511
+ }
512
+ )
513
+ },
514
+ containerColor = BackgroundGray
515
+ ) { innerPadding ->
516
+ Box(
517
+ modifier = Modifier
518
+ .fillMaxSize()
519
+ .background(BackgroundGray)
520
+ .padding(innerPadding)
521
+ ) {
522
+ NavGraph(
523
+ navController = navController,
524
+ viewModel = viewModel
525
+ )
526
+ }
527
+ }
528
+ }
529
+
530
+ ```
531
+
532
+ ---
533
+
534
+ ## app/src/main/java/com/example/posthog/navigation/NavGraph.kt
535
+
536
+ ```kt
537
+ package com.example.posthog.navigation
538
+
539
+ import androidx.compose.runtime.Composable
540
+ import androidx.compose.runtime.LaunchedEffect
541
+ import androidx.compose.runtime.collectAsState
542
+ import androidx.compose.runtime.getValue
543
+ import androidx.navigation.NavHostController
544
+ import androidx.navigation.compose.NavHost
545
+ import androidx.navigation.compose.composable
546
+ import com.example.posthog.ui.screens.BurritoScreen
547
+ import com.example.posthog.ui.screens.HomeScreen
548
+ import com.example.posthog.ui.screens.ProfileScreen
549
+ import com.example.posthog.viewmodel.AuthViewModel
550
+
551
+ sealed class Screen(val route: String) {
552
+ object Home : Screen("home")
553
+ object Burrito : Screen("burrito")
554
+ object Profile : Screen("profile")
555
+ }
556
+
557
+ @Composable
558
+ fun NavGraph(
559
+ navController: NavHostController,
560
+ viewModel: AuthViewModel
561
+ ) {
562
+ val isAuthenticated by viewModel.isAuthenticated.collectAsState()
563
+ val currentUser by viewModel.currentUser.collectAsState()
564
+
565
+ NavHost(
566
+ navController = navController,
567
+ startDestination = Screen.Home.route
568
+ ) {
569
+ composable(Screen.Home.route) {
570
+ HomeScreen(
571
+ isAuthenticated = isAuthenticated,
572
+ username = currentUser?.username,
573
+ onLogin = { username -> viewModel.login(username) }
574
+ )
575
+ }
576
+
577
+ composable(Screen.Burrito.route) {
578
+ if (!isAuthenticated) {
579
+ LaunchedEffect(Unit) {
580
+ navController.navigate(Screen.Home.route) {
581
+ popUpTo(Screen.Home.route) { inclusive = true }
582
+ }
583
+ }
584
+ } else {
585
+ BurritoScreen(
586
+ burritoCount = currentUser?.burritoConsiderations ?: 0,
587
+ onConsiderBurrito = { viewModel.incrementBurritoCount() }
588
+ )
589
+ }
590
+ }
591
+
592
+ composable(Screen.Profile.route) {
593
+ if (!isAuthenticated) {
594
+ LaunchedEffect(Unit) {
595
+ navController.navigate(Screen.Home.route) {
596
+ popUpTo(Screen.Home.route) { inclusive = true }
597
+ }
598
+ }
599
+ } else {
600
+ ProfileScreen(
601
+ username = currentUser?.username ?: "",
602
+ burritoCount = currentUser?.burritoConsiderations ?: 0
603
+ )
604
+ }
605
+ }
606
+ }
607
+ }
608
+
609
+ ```
610
+
611
+ ---
612
+
613
+ ## app/src/main/java/com/example/posthog/ui/components/AppHeader.kt
614
+
615
+ ```kt
616
+ package com.example.posthog.ui.components
617
+
618
+ import androidx.compose.foundation.background
619
+ import androidx.compose.foundation.layout.Arrangement
620
+ import androidx.compose.foundation.layout.Box
621
+ import androidx.compose.foundation.layout.PaddingValues
622
+ import androidx.compose.foundation.layout.Row
623
+ import androidx.compose.foundation.layout.fillMaxWidth
624
+ import androidx.compose.foundation.layout.padding
625
+ import androidx.compose.foundation.shape.RoundedCornerShape
626
+ import androidx.compose.material3.Button
627
+ import androidx.compose.material3.ButtonDefaults
628
+ import androidx.compose.material3.Text
629
+ import androidx.compose.runtime.Composable
630
+ import androidx.compose.ui.Alignment
631
+ import androidx.compose.ui.Modifier
632
+ import androidx.compose.ui.unit.dp
633
+ import androidx.compose.ui.unit.sp
634
+ import com.example.posthog.ui.theme.DarkHeader
635
+ import com.example.posthog.ui.theme.ErrorRed
636
+ import com.example.posthog.ui.theme.White
637
+
638
+ @Composable
639
+ fun AppHeader(
640
+ isAuthenticated: Boolean,
641
+ username: String?,
642
+ currentRoute: String?,
643
+ onNavigate: (String) -> Unit,
644
+ onLogout: () -> Unit
645
+ ) {
646
+ Box(
647
+ modifier = Modifier
648
+ .fillMaxWidth()
649
+ .background(DarkHeader)
650
+ .padding(horizontal = 16.dp, vertical = 12.dp)
651
+ ) {
652
+ Row(
653
+ modifier = Modifier.fillMaxWidth(),
654
+ horizontalArrangement = Arrangement.SpaceBetween,
655
+ verticalAlignment = Alignment.CenterVertically
656
+ ) {
657
+ // App title
658
+ Text(
659
+ text = "Burrito App",
660
+ color = White,
661
+ fontSize = 18.sp
662
+ )
663
+
664
+ // User section (right side)
665
+ if (isAuthenticated && username != null) {
666
+ Row(
667
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
668
+ verticalAlignment = Alignment.CenterVertically
669
+ ) {
670
+ Text(
671
+ text = username,
672
+ color = White,
673
+ fontSize = 14.sp
674
+ )
675
+
676
+ Button(
677
+ onClick = onLogout,
678
+ colors = ButtonDefaults.buttonColors(
679
+ containerColor = ErrorRed
680
+ ),
681
+ shape = RoundedCornerShape(4.dp),
682
+ contentPadding = PaddingValues(horizontal = 12.dp, vertical = 6.dp)
683
+ ) {
684
+ Text(
685
+ text = "Logout",
686
+ color = White,
687
+ fontSize = 14.sp
688
+ )
689
+ }
690
+ }
691
+ }
692
+ }
693
+ }
694
+ }
695
+
696
+ ```
697
+
698
+ ---
699
+
700
+ ## app/src/main/java/com/example/posthog/ui/components/BottomNavBar.kt
701
+
702
+ ```kt
703
+ package com.example.posthog.ui.components
704
+
705
+ import androidx.compose.foundation.layout.size
706
+ import androidx.compose.material.icons.Icons
707
+ import androidx.compose.material.icons.filled.Home
708
+ import androidx.compose.material.icons.filled.Person
709
+ import androidx.compose.material.icons.outlined.Home
710
+ import androidx.compose.material.icons.outlined.Person
711
+ import androidx.compose.material3.Icon
712
+ import androidx.compose.material3.NavigationBar
713
+ import androidx.compose.material3.NavigationBarItem
714
+ import androidx.compose.material3.NavigationBarItemDefaults
715
+ import androidx.compose.material3.Text
716
+ import androidx.compose.runtime.Composable
717
+ import androidx.compose.ui.Modifier
718
+ import androidx.compose.ui.graphics.vector.ImageVector
719
+ import androidx.compose.ui.unit.dp
720
+ import androidx.compose.ui.unit.sp
721
+ import com.example.posthog.navigation.Screen
722
+ import com.example.posthog.ui.theme.PrimaryBlue
723
+ import com.example.posthog.ui.theme.TextGray
724
+ import com.example.posthog.ui.theme.White
725
+
726
+ sealed class BottomNavItem(
727
+ val route: String,
728
+ val label: String,
729
+ val selectedIcon: ImageVector?,
730
+ val unselectedIcon: ImageVector?
731
+ ) {
732
+ object Home : BottomNavItem(
733
+ route = Screen.Home.route,
734
+ label = "Home",
735
+ selectedIcon = Icons.Filled.Home,
736
+ unselectedIcon = Icons.Outlined.Home
737
+ )
738
+
739
+ object Burrito : BottomNavItem(
740
+ route = Screen.Burrito.route,
741
+ label = "Burrito",
742
+ selectedIcon = null, // We'll use a custom icon or emoji
743
+ unselectedIcon = null
744
+ )
745
+
746
+ object Profile : BottomNavItem(
747
+ route = Screen.Profile.route,
748
+ label = "Profile",
749
+ selectedIcon = Icons.Filled.Person,
750
+ unselectedIcon = Icons.Outlined.Person
751
+ )
752
+ }
753
+
754
+ @Composable
755
+ fun BottomNavBar(
756
+ isAuthenticated: Boolean,
757
+ currentRoute: String?,
758
+ onNavigate: (String) -> Unit
759
+ ) {
760
+ val items = if (isAuthenticated) {
761
+ listOf(BottomNavItem.Home, BottomNavItem.Burrito, BottomNavItem.Profile)
762
+ } else {
763
+ listOf(BottomNavItem.Home)
764
+ }
765
+
766
+ NavigationBar(
767
+ containerColor = White
768
+ ) {
769
+ items.forEach { item ->
770
+ val selected = currentRoute == item.route
771
+
772
+ NavigationBarItem(
773
+ selected = selected,
774
+ onClick = { onNavigate(item.route) },
775
+ icon = {
776
+ if (item.selectedIcon != null && item.unselectedIcon != null) {
777
+ Icon(
778
+ imageVector = if (selected) item.selectedIcon else item.unselectedIcon,
779
+ contentDescription = item.label,
780
+ modifier = Modifier.size(24.dp)
781
+ )
782
+ } else {
783
+ // For Burrito, use text emoji as icon
784
+ Text(
785
+ text = "🌯",
786
+ fontSize = 24.sp
787
+ )
788
+ }
789
+ },
790
+ label = {
791
+ Text(
792
+ text = item.label,
793
+ fontSize = 12.sp
794
+ )
795
+ },
796
+ colors = NavigationBarItemDefaults.colors(
797
+ selectedIconColor = PrimaryBlue,
798
+ selectedTextColor = PrimaryBlue,
799
+ unselectedIconColor = TextGray,
800
+ unselectedTextColor = TextGray,
801
+ indicatorColor = PrimaryBlue.copy(alpha = 0.1f)
802
+ )
803
+ )
804
+ }
805
+ }
806
+ }
807
+
808
+ ```
809
+
810
+ ---
811
+
812
+ ## app/src/main/java/com/example/posthog/ui/components/StatsCard.kt
813
+
814
+ ```kt
815
+ package com.example.posthog.ui.components
816
+
817
+ import androidx.compose.foundation.background
818
+ import androidx.compose.foundation.layout.Column
819
+ import androidx.compose.foundation.layout.Spacer
820
+ import androidx.compose.foundation.layout.fillMaxWidth
821
+ import androidx.compose.foundation.layout.height
822
+ import androidx.compose.foundation.layout.padding
823
+ import androidx.compose.foundation.shape.RoundedCornerShape
824
+ import androidx.compose.material3.Text
825
+ import androidx.compose.runtime.Composable
826
+ import androidx.compose.ui.Modifier
827
+ import androidx.compose.ui.text.font.FontWeight
828
+ import androidx.compose.ui.unit.dp
829
+ import androidx.compose.ui.unit.sp
830
+ import com.example.posthog.ui.theme.LightGray
831
+ import com.example.posthog.ui.theme.TextDark
832
+ import com.example.posthog.ui.theme.TextGray
833
+
834
+ @Composable
835
+ fun StatsCard(
836
+ title: String,
837
+ value: String,
838
+ modifier: Modifier = Modifier
839
+ ) {
840
+ Column(
841
+ modifier = modifier
842
+ .fillMaxWidth()
843
+ .background(
844
+ color = LightGray,
845
+ shape = RoundedCornerShape(4.dp)
846
+ )
847
+ .padding(16.dp)
848
+ ) {
849
+ Text(
850
+ text = title,
851
+ color = TextGray,
852
+ fontSize = 14.sp
853
+ )
854
+ Spacer(modifier = Modifier.height(4.dp))
855
+ Text(
856
+ text = value,
857
+ color = TextDark,
858
+ fontSize = 24.sp,
859
+ fontWeight = FontWeight.Bold
860
+ )
861
+ }
862
+ }
863
+
864
+ ```
865
+
866
+ ---
867
+
868
+ ## app/src/main/java/com/example/posthog/ui/screens/BurritoScreen.kt
869
+
870
+ ```kt
871
+ package com.example.posthog.ui.screens
872
+
873
+ import androidx.compose.foundation.background
874
+ import androidx.compose.foundation.layout.Box
875
+ import androidx.compose.foundation.layout.Column
876
+ import androidx.compose.foundation.layout.Spacer
877
+ import androidx.compose.foundation.layout.fillMaxSize
878
+ import androidx.compose.foundation.layout.fillMaxWidth
879
+ import androidx.compose.foundation.layout.height
880
+ import androidx.compose.foundation.layout.padding
881
+ import androidx.compose.foundation.layout.widthIn
882
+ import androidx.compose.foundation.rememberScrollState
883
+ import androidx.compose.foundation.shape.RoundedCornerShape
884
+ import androidx.compose.foundation.verticalScroll
885
+ import androidx.compose.material3.Button
886
+ import androidx.compose.material3.ButtonDefaults
887
+ import androidx.compose.material3.Text
888
+ import androidx.compose.runtime.Composable
889
+ import androidx.compose.runtime.LaunchedEffect
890
+ import androidx.compose.runtime.getValue
891
+ import androidx.compose.runtime.mutableStateOf
892
+ import androidx.compose.runtime.remember
893
+ import androidx.compose.runtime.setValue
894
+ import androidx.compose.ui.Alignment
895
+ import androidx.compose.ui.Modifier
896
+ import androidx.compose.ui.draw.shadow
897
+ import androidx.compose.ui.text.font.FontWeight
898
+ import androidx.compose.ui.text.style.TextAlign
899
+ import androidx.compose.ui.unit.dp
900
+ import androidx.compose.ui.unit.sp
901
+ import com.example.posthog.ui.components.StatsCard
902
+ import com.example.posthog.ui.theme.BackgroundGray
903
+ import com.example.posthog.ui.theme.SuccessGreen
904
+ import com.example.posthog.ui.theme.TextDark
905
+ import com.example.posthog.ui.theme.TextGray
906
+ import com.example.posthog.ui.theme.White
907
+ import kotlinx.coroutines.delay
908
+
909
+ @Composable
910
+ fun BurritoScreen(
911
+ burritoCount: Int,
912
+ onConsiderBurrito: () -> Unit
913
+ ) {
914
+ var showSuccess by remember { mutableStateOf(false) }
915
+
916
+ LaunchedEffect(showSuccess) {
917
+ if (showSuccess) {
918
+ delay(2000)
919
+ showSuccess = false
920
+ }
921
+ }
922
+
923
+ Box(
924
+ modifier = Modifier
925
+ .fillMaxSize()
926
+ .background(BackgroundGray)
927
+ .padding(horizontal = 16.dp)
928
+ .verticalScroll(rememberScrollState()),
929
+ contentAlignment = Alignment.TopCenter
930
+ ) {
931
+ Column(
932
+ modifier = Modifier
933
+ .widthIn(max = 600.dp)
934
+ .padding(vertical = 16.dp),
935
+ horizontalAlignment = Alignment.CenterHorizontally
936
+ ) {
937
+ // Main content card
938
+ Column(
939
+ modifier = Modifier
940
+ .fillMaxWidth()
941
+ .shadow(
942
+ elevation = 4.dp,
943
+ shape = RoundedCornerShape(8.dp),
944
+ ambientColor = TextDark.copy(alpha = 0.1f),
945
+ spotColor = TextDark.copy(alpha = 0.1f)
946
+ )
947
+ .background(
948
+ color = White,
949
+ shape = RoundedCornerShape(8.dp)
950
+ )
951
+ .padding(24.dp),
952
+ horizontalAlignment = Alignment.CenterHorizontally
953
+ ) {
954
+ Text(
955
+ text = "Burrito consideration zone",
956
+ fontSize = 24.sp,
957
+ fontWeight = FontWeight.SemiBold,
958
+ color = TextDark,
959
+ textAlign = TextAlign.Center
960
+ )
961
+
962
+ Spacer(modifier = Modifier.height(16.dp))
963
+
964
+ Text(
965
+ text = "Take a moment to truly consider the burrito.",
966
+ fontSize = 16.sp,
967
+ color = TextGray,
968
+ textAlign = TextAlign.Center,
969
+ lineHeight = 26.sp
970
+ )
971
+
972
+ Spacer(modifier = Modifier.height(24.dp))
973
+
974
+ Button(
975
+ onClick = {
976
+ onConsiderBurrito()
977
+ showSuccess = true
978
+ },
979
+ modifier = Modifier
980
+ .fillMaxWidth()
981
+ .height(56.dp),
982
+ colors = ButtonDefaults.buttonColors(
983
+ containerColor = SuccessGreen
984
+ ),
985
+ shape = RoundedCornerShape(4.dp)
986
+ ) {
987
+ Text(
988
+ text = "Consider the Burrito",
989
+ fontSize = 18.sp,
990
+ color = White
991
+ )
992
+ }
993
+
994
+ if (showSuccess) {
995
+ Spacer(modifier = Modifier.height(16.dp))
996
+
997
+ Text(
998
+ text = "You have considered the burrito. Well done!",
999
+ color = SuccessGreen,
1000
+ fontSize = 16.sp,
1001
+ textAlign = TextAlign.Center
1002
+ )
1003
+ }
1004
+
1005
+ Spacer(modifier = Modifier.height(24.dp))
1006
+
1007
+ Text(
1008
+ text = "Consideration stats",
1009
+ fontSize = 20.sp,
1010
+ fontWeight = FontWeight.SemiBold,
1011
+ color = TextDark,
1012
+ modifier = Modifier.fillMaxWidth()
1013
+ )
1014
+
1015
+ Spacer(modifier = Modifier.height(16.dp))
1016
+
1017
+ StatsCard(
1018
+ title = "Total Burrito Considerations",
1019
+ value = burritoCount.toString()
1020
+ )
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+
1026
+ ```
1027
+
1028
+ ---
1029
+
1030
+ ## app/src/main/java/com/example/posthog/ui/screens/HomeScreen.kt
1031
+
1032
+ ```kt
1033
+ package com.example.posthog.ui.screens
1034
+
1035
+ import androidx.compose.foundation.background
1036
+ import androidx.compose.foundation.layout.Arrangement
1037
+ import androidx.compose.foundation.layout.Box
1038
+ import androidx.compose.foundation.layout.Column
1039
+ import androidx.compose.foundation.layout.Spacer
1040
+ import androidx.compose.foundation.layout.fillMaxSize
1041
+ import androidx.compose.foundation.layout.fillMaxWidth
1042
+ import androidx.compose.foundation.layout.height
1043
+ import androidx.compose.foundation.layout.padding
1044
+ import androidx.compose.foundation.layout.widthIn
1045
+ import androidx.compose.foundation.rememberScrollState
1046
+ import androidx.compose.foundation.shape.RoundedCornerShape
1047
+ import androidx.compose.foundation.text.KeyboardOptions
1048
+ import androidx.compose.foundation.verticalScroll
1049
+ import androidx.compose.material3.Button
1050
+ import androidx.compose.material3.ButtonDefaults
1051
+ import androidx.compose.material3.OutlinedTextField
1052
+ import androidx.compose.material3.OutlinedTextFieldDefaults
1053
+ import androidx.compose.material3.Text
1054
+ import androidx.compose.runtime.Composable
1055
+ import androidx.compose.runtime.getValue
1056
+ import androidx.compose.runtime.mutableStateOf
1057
+ import androidx.compose.runtime.remember
1058
+ import androidx.compose.runtime.setValue
1059
+ import androidx.compose.ui.Alignment
1060
+ import androidx.compose.ui.Modifier
1061
+ import androidx.compose.ui.draw.shadow
1062
+ import androidx.compose.ui.text.font.FontWeight
1063
+ import androidx.compose.ui.text.input.KeyboardType
1064
+ import androidx.compose.ui.text.input.PasswordVisualTransformation
1065
+ import androidx.compose.ui.text.style.TextAlign
1066
+ import androidx.compose.ui.unit.dp
1067
+ import androidx.compose.ui.unit.sp
1068
+ import com.example.posthog.ui.theme.BackgroundGray
1069
+ import com.example.posthog.ui.theme.BorderGray
1070
+ import com.example.posthog.ui.theme.PrimaryBlue
1071
+ import com.example.posthog.ui.theme.TextDark
1072
+ import com.example.posthog.ui.theme.TextGray
1073
+ import com.example.posthog.ui.theme.White
1074
+
1075
+ @Composable
1076
+ fun HomeScreen(
1077
+ isAuthenticated: Boolean,
1078
+ username: String?,
1079
+ onLogin: (String) -> Unit
1080
+ ) {
1081
+ Box(
1082
+ modifier = Modifier
1083
+ .fillMaxSize()
1084
+ .background(BackgroundGray)
1085
+ .padding(horizontal = 16.dp)
1086
+ .verticalScroll(rememberScrollState()),
1087
+ contentAlignment = if (isAuthenticated) Alignment.TopCenter else Alignment.Center
1088
+ ) {
1089
+ Column(
1090
+ modifier = Modifier
1091
+ .widthIn(max = 600.dp)
1092
+ .padding(vertical = 16.dp),
1093
+ horizontalAlignment = Alignment.CenterHorizontally
1094
+ ) {
1095
+ if (isAuthenticated && username != null) {
1096
+ LoggedInContent(username = username)
1097
+ } else {
1098
+ LoginForm(onLogin = onLogin)
1099
+ }
1100
+ }
1101
+ }
1102
+ }
1103
+
1104
+ @Composable
1105
+ private fun LoggedInContent(username: String) {
1106
+ ContentCard {
1107
+ Text(
1108
+ text = "Welcome back, $username!",
1109
+ fontSize = 24.sp,
1110
+ fontWeight = FontWeight.SemiBold,
1111
+ color = TextDark
1112
+ )
1113
+
1114
+ Spacer(modifier = Modifier.height(16.dp))
1115
+
1116
+ Text(
1117
+ text = "Ready to consider some burritos?",
1118
+ fontSize = 16.sp,
1119
+ color = TextGray,
1120
+ lineHeight = 26.sp
1121
+ )
1122
+ }
1123
+ }
1124
+
1125
+ @Composable
1126
+ private fun LoginForm(onLogin: (String) -> Unit) {
1127
+ var username by remember { mutableStateOf("") }
1128
+ var password by remember { mutableStateOf("") }
1129
+
1130
+ ContentCard {
1131
+ Text(
1132
+ text = "Welcome to Burrito Consideration App",
1133
+ fontSize = 24.sp,
1134
+ fontWeight = FontWeight.SemiBold,
1135
+ color = TextDark,
1136
+ textAlign = TextAlign.Center
1137
+ )
1138
+
1139
+ Spacer(modifier = Modifier.height(24.dp))
1140
+
1141
+ // Username field
1142
+ Column(modifier = Modifier.fillMaxWidth()) {
1143
+ Text(
1144
+ text = "Username",
1145
+ fontSize = 16.sp,
1146
+ fontWeight = FontWeight.Medium,
1147
+ color = TextDark,
1148
+ modifier = Modifier.padding(bottom = 8.dp)
1149
+ )
1150
+ OutlinedTextField(
1151
+ value = username,
1152
+ onValueChange = { username = it },
1153
+ modifier = Modifier.fillMaxWidth(),
1154
+ singleLine = true,
1155
+ shape = RoundedCornerShape(4.dp),
1156
+ colors = OutlinedTextFieldDefaults.colors(
1157
+ unfocusedBorderColor = BorderGray,
1158
+ focusedBorderColor = PrimaryBlue,
1159
+ unfocusedContainerColor = White,
1160
+ focusedContainerColor = White
1161
+ )
1162
+ )
1163
+ }
1164
+
1165
+ Spacer(modifier = Modifier.height(16.dp))
1166
+
1167
+ // Password field
1168
+ Column(modifier = Modifier.fillMaxWidth()) {
1169
+ Text(
1170
+ text = "Password",
1171
+ fontSize = 16.sp,
1172
+ fontWeight = FontWeight.Medium,
1173
+ color = TextDark,
1174
+ modifier = Modifier.padding(bottom = 8.dp)
1175
+ )
1176
+ OutlinedTextField(
1177
+ value = password,
1178
+ onValueChange = { password = it },
1179
+ modifier = Modifier.fillMaxWidth(),
1180
+ singleLine = true,
1181
+ visualTransformation = PasswordVisualTransformation(),
1182
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
1183
+ shape = RoundedCornerShape(4.dp),
1184
+ colors = OutlinedTextFieldDefaults.colors(
1185
+ unfocusedBorderColor = BorderGray,
1186
+ focusedBorderColor = PrimaryBlue,
1187
+ unfocusedContainerColor = White,
1188
+ focusedContainerColor = White
1189
+ )
1190
+ )
1191
+ }
1192
+
1193
+ Spacer(modifier = Modifier.height(16.dp))
1194
+
1195
+ Button(
1196
+ onClick = {
1197
+ if (username.isNotBlank()) {
1198
+ onLogin(username)
1199
+ }
1200
+ },
1201
+ modifier = Modifier
1202
+ .fillMaxWidth()
1203
+ .height(48.dp),
1204
+ colors = ButtonDefaults.buttonColors(
1205
+ containerColor = PrimaryBlue
1206
+ ),
1207
+ shape = RoundedCornerShape(4.dp)
1208
+ ) {
1209
+ Text(
1210
+ text = "Sign In",
1211
+ fontSize = 16.sp,
1212
+ color = White
1213
+ )
1214
+ }
1215
+
1216
+ Spacer(modifier = Modifier.height(24.dp))
1217
+
1218
+ Text(
1219
+ text = "Note: This is a demo app. Enter any username to sign in.",
1220
+ fontSize = 14.sp,
1221
+ color = TextGray,
1222
+ textAlign = TextAlign.Center,
1223
+ lineHeight = 21.sp
1224
+ )
1225
+ }
1226
+ }
1227
+
1228
+ @Composable
1229
+ private fun ContentCard(
1230
+ content: @Composable () -> Unit
1231
+ ) {
1232
+ Column(
1233
+ modifier = Modifier
1234
+ .fillMaxWidth()
1235
+ .shadow(
1236
+ elevation = 4.dp,
1237
+ shape = RoundedCornerShape(8.dp),
1238
+ ambientColor = TextDark.copy(alpha = 0.1f),
1239
+ spotColor = TextDark.copy(alpha = 0.1f)
1240
+ )
1241
+ .background(
1242
+ color = White,
1243
+ shape = RoundedCornerShape(8.dp)
1244
+ )
1245
+ .padding(24.dp),
1246
+ horizontalAlignment = Alignment.CenterHorizontally
1247
+ ) {
1248
+ content()
1249
+ }
1250
+ }
1251
+
1252
+ ```
1253
+
1254
+ ---
1255
+
1256
+ ## app/src/main/java/com/example/posthog/ui/screens/ProfileScreen.kt
1257
+
1258
+ ```kt
1259
+ package com.example.posthog.ui.screens
1260
+
1261
+ import androidx.compose.foundation.background
1262
+ import androidx.compose.foundation.layout.Box
1263
+ import androidx.compose.foundation.layout.Column
1264
+ import androidx.compose.foundation.layout.Spacer
1265
+ import androidx.compose.foundation.layout.fillMaxSize
1266
+ import androidx.compose.foundation.layout.fillMaxWidth
1267
+ import androidx.compose.foundation.layout.height
1268
+ import androidx.compose.foundation.layout.padding
1269
+ import androidx.compose.foundation.layout.widthIn
1270
+ import androidx.compose.foundation.rememberScrollState
1271
+ import androidx.compose.foundation.shape.RoundedCornerShape
1272
+ import androidx.compose.foundation.verticalScroll
1273
+ import androidx.compose.material3.Text
1274
+ import androidx.compose.runtime.Composable
1275
+ import androidx.compose.ui.Alignment
1276
+ import androidx.compose.ui.Modifier
1277
+ import androidx.compose.ui.draw.shadow
1278
+ import androidx.compose.ui.text.font.FontWeight
1279
+ import androidx.compose.ui.text.style.TextAlign
1280
+ import androidx.compose.ui.unit.dp
1281
+ import androidx.compose.ui.unit.sp
1282
+ import com.example.posthog.ui.components.StatsCard
1283
+ import com.example.posthog.ui.theme.BackgroundGray
1284
+ import com.example.posthog.ui.theme.TextDark
1285
+ import com.example.posthog.ui.theme.TextGray
1286
+ import com.example.posthog.ui.theme.White
1287
+
1288
+ @Composable
1289
+ fun ProfileScreen(
1290
+ username: String,
1291
+ burritoCount: Int
1292
+ ) {
1293
+ Box(
1294
+ modifier = Modifier
1295
+ .fillMaxSize()
1296
+ .background(BackgroundGray)
1297
+ .padding(horizontal = 16.dp)
1298
+ .verticalScroll(rememberScrollState()),
1299
+ contentAlignment = Alignment.TopCenter
1300
+ ) {
1301
+ Column(
1302
+ modifier = Modifier
1303
+ .widthIn(max = 600.dp)
1304
+ .padding(vertical = 16.dp),
1305
+ horizontalAlignment = Alignment.CenterHorizontally
1306
+ ) {
1307
+ // Main content card
1308
+ Column(
1309
+ modifier = Modifier
1310
+ .fillMaxWidth()
1311
+ .shadow(
1312
+ elevation = 4.dp,
1313
+ shape = RoundedCornerShape(8.dp),
1314
+ ambientColor = TextDark.copy(alpha = 0.1f),
1315
+ spotColor = TextDark.copy(alpha = 0.1f)
1316
+ )
1317
+ .background(
1318
+ color = White,
1319
+ shape = RoundedCornerShape(8.dp)
1320
+ )
1321
+ .padding(24.dp),
1322
+ horizontalAlignment = Alignment.CenterHorizontally
1323
+ ) {
1324
+ Text(
1325
+ text = "User Profile",
1326
+ fontSize = 24.sp,
1327
+ fontWeight = FontWeight.SemiBold,
1328
+ color = TextDark
1329
+ )
1330
+
1331
+ Spacer(modifier = Modifier.height(24.dp))
1332
+
1333
+ // Your Information section
1334
+ Text(
1335
+ text = "Your Information",
1336
+ fontSize = 24.sp,
1337
+ fontWeight = FontWeight.SemiBold,
1338
+ color = TextDark,
1339
+ modifier = Modifier.fillMaxWidth()
1340
+ )
1341
+
1342
+ Spacer(modifier = Modifier.height(16.dp))
1343
+
1344
+ // Username display
1345
+ Column(modifier = Modifier.fillMaxWidth()) {
1346
+ Text(
1347
+ text = "Username",
1348
+ fontSize = 14.sp,
1349
+ color = TextGray
1350
+ )
1351
+ Text(
1352
+ text = username,
1353
+ fontSize = 20.sp,
1354
+ fontWeight = FontWeight.SemiBold,
1355
+ color = TextDark
1356
+ )
1357
+ }
1358
+
1359
+ Spacer(modifier = Modifier.height(24.dp))
1360
+
1361
+ // Stats card
1362
+ StatsCard(
1363
+ title = "Total Burrito Considerations",
1364
+ value = burritoCount.toString()
1365
+ )
1366
+
1367
+ Spacer(modifier = Modifier.height(24.dp))
1368
+
1369
+ // Your Burrito Journey section
1370
+ Text(
1371
+ text = "Your Burrito Journey",
1372
+ fontSize = 20.sp,
1373
+ fontWeight = FontWeight.SemiBold,
1374
+ color = TextDark,
1375
+ modifier = Modifier.fillMaxWidth()
1376
+ )
1377
+
1378
+ Spacer(modifier = Modifier.height(8.dp))
1379
+
1380
+ Text(
1381
+ text = getJourneyMessage(burritoCount),
1382
+ fontSize = 16.sp,
1383
+ color = TextGray,
1384
+ textAlign = TextAlign.Start,
1385
+ lineHeight = 26.sp,
1386
+ modifier = Modifier.fillMaxWidth()
1387
+ )
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+
1393
+ private fun getJourneyMessage(count: Int): String = when {
1394
+ count == 0 -> "You haven't considered any burritos yet. Start your journey!"
1395
+ count == 1 -> "You've considered the burrito potential once. The journey begins!"
1396
+ count in 2..4 -> "You're getting the hang of burrito consideration!"
1397
+ count in 5..9 -> "You're becoming a burrito consideration expert!"
1398
+ else -> "You are a true burrito consideration master!"
1399
+ }
1400
+
1401
+ ```
1402
+
1403
+ ---
1404
+
1405
+ ## app/src/main/java/com/example/posthog/ui/theme/Color.kt
1406
+
1407
+ ```kt
1408
+ package com.example.posthog.ui.theme
1409
+
1410
+ import androidx.compose.ui.graphics.Color
1411
+
1412
+ val PrimaryBlue = Color(0xFF0070F3)
1413
+ val PrimaryBlueHover = Color(0xFF0051CC)
1414
+ val SuccessGreen = Color(0xFF28A745)
1415
+ val SuccessGreenHover = Color(0xFF218838)
1416
+ val ErrorRed = Color(0xFFDC3545)
1417
+ val ErrorRedHover = Color(0xFFC82333)
1418
+ val DarkHeader = Color(0xFF333333)
1419
+ val DarkHeaderHover = Color(0xFF555555)
1420
+ val LightGray = Color(0xFFF8F9FA)
1421
+ val BorderGray = Color(0xFFDDDDDD)
1422
+ val TextGray = Color(0xFF666666)
1423
+ val BackgroundGray = Color(0xFFF5F5F5)
1424
+ val TextDark = Color(0xFF333333)
1425
+ val White = Color(0xFFFFFFFF)
1426
+
1427
+ ```
1428
+
1429
+ ---
1430
+
1431
+ ## app/src/main/java/com/example/posthog/ui/theme/Theme.kt
1432
+
1433
+ ```kt
1434
+ package com.example.posthog.ui.theme
1435
+
1436
+ import androidx.compose.material3.MaterialTheme
1437
+ import androidx.compose.material3.lightColorScheme
1438
+ import androidx.compose.runtime.Composable
1439
+
1440
+ private val LightColorScheme = lightColorScheme(
1441
+ primary = PrimaryBlue,
1442
+ secondary = SuccessGreen,
1443
+ tertiary = DarkHeader,
1444
+ background = BackgroundGray,
1445
+ surface = White,
1446
+ onPrimary = White,
1447
+ onSecondary = White,
1448
+ onTertiary = White,
1449
+ onBackground = TextDark,
1450
+ onSurface = TextDark
1451
+ )
1452
+
1453
+ @Composable
1454
+ fun PostHogTheme(
1455
+ content: @Composable () -> Unit
1456
+ ) {
1457
+ MaterialTheme(
1458
+ colorScheme = LightColorScheme,
1459
+ typography = Typography,
1460
+ content = content
1461
+ )
1462
+ }
1463
+ ```
1464
+
1465
+ ---
1466
+
1467
+ ## app/src/main/java/com/example/posthog/ui/theme/Type.kt
1468
+
1469
+ ```kt
1470
+ package com.example.posthog.ui.theme
1471
+
1472
+ import androidx.compose.material3.Typography
1473
+ import androidx.compose.ui.text.TextStyle
1474
+ import androidx.compose.ui.text.font.FontFamily
1475
+ import androidx.compose.ui.text.font.FontWeight
1476
+ import androidx.compose.ui.unit.sp
1477
+
1478
+ // Typography based on design specification
1479
+ // Uses system font stack (FontFamily.Default maps to Roboto on Android)
1480
+ val Typography = Typography(
1481
+ // H1 - Page titles (32sp)
1482
+ displayLarge = TextStyle(
1483
+ fontFamily = FontFamily.Default,
1484
+ fontWeight = FontWeight.SemiBold,
1485
+ fontSize = 32.sp,
1486
+ lineHeight = 40.sp,
1487
+ letterSpacing = 0.sp
1488
+ ),
1489
+ // H2 - Section titles (24sp)
1490
+ displayMedium = TextStyle(
1491
+ fontFamily = FontFamily.Default,
1492
+ fontWeight = FontWeight.SemiBold,
1493
+ fontSize = 24.sp,
1494
+ lineHeight = 32.sp,
1495
+ letterSpacing = 0.sp
1496
+ ),
1497
+ // H3 - Subsection titles (20sp)
1498
+ displaySmall = TextStyle(
1499
+ fontFamily = FontFamily.Default,
1500
+ fontWeight = FontWeight.SemiBold,
1501
+ fontSize = 20.sp,
1502
+ lineHeight = 26.sp,
1503
+ letterSpacing = 0.sp
1504
+ ),
1505
+ // Body text (16sp with 1.6 line height = 25.6sp)
1506
+ bodyLarge = TextStyle(
1507
+ fontFamily = FontFamily.Default,
1508
+ fontWeight = FontWeight.Normal,
1509
+ fontSize = 16.sp,
1510
+ lineHeight = 26.sp,
1511
+ letterSpacing = 0.sp
1512
+ ),
1513
+ // Small/Note text (14sp)
1514
+ bodySmall = TextStyle(
1515
+ fontFamily = FontFamily.Default,
1516
+ fontWeight = FontWeight.Normal,
1517
+ fontSize = 14.sp,
1518
+ lineHeight = 21.sp,
1519
+ letterSpacing = 0.sp
1520
+ ),
1521
+ // Labels (16sp, medium weight)
1522
+ labelLarge = TextStyle(
1523
+ fontFamily = FontFamily.Default,
1524
+ fontWeight = FontWeight.Medium,
1525
+ fontSize = 16.sp,
1526
+ lineHeight = 24.sp,
1527
+ letterSpacing = 0.sp
1528
+ ),
1529
+ // Button text - Burrito button (18sp)
1530
+ titleLarge = TextStyle(
1531
+ fontFamily = FontFamily.Default,
1532
+ fontWeight = FontWeight.Normal,
1533
+ fontSize = 18.sp,
1534
+ lineHeight = 24.sp,
1535
+ letterSpacing = 0.sp
1536
+ ),
1537
+ // Button text - Primary/Logout (16sp/14sp)
1538
+ titleMedium = TextStyle(
1539
+ fontFamily = FontFamily.Default,
1540
+ fontWeight = FontWeight.Normal,
1541
+ fontSize = 16.sp,
1542
+ lineHeight = 24.sp,
1543
+ letterSpacing = 0.sp
1544
+ ),
1545
+ titleSmall = TextStyle(
1546
+ fontFamily = FontFamily.Default,
1547
+ fontWeight = FontWeight.Normal,
1548
+ fontSize = 14.sp,
1549
+ lineHeight = 20.sp,
1550
+ letterSpacing = 0.sp
1551
+ )
1552
+ )
1553
+ ```
1554
+
1555
+ ---
1556
+
1557
+ ## app/src/main/java/com/example/posthog/viewmodel/AuthViewModel.kt
1558
+
1559
+ ```kt
1560
+ package com.example.posthog.viewmodel
1561
+
1562
+ import android.app.Application
1563
+ import androidx.lifecycle.AndroidViewModel
1564
+ import androidx.lifecycle.viewModelScope
1565
+ import com.example.posthog.data.User
1566
+ import com.example.posthog.data.UserRepository
1567
+ import com.posthog.PostHog
1568
+ import kotlinx.coroutines.flow.MutableStateFlow
1569
+ import kotlinx.coroutines.flow.StateFlow
1570
+ import kotlinx.coroutines.flow.asStateFlow
1571
+ import kotlinx.coroutines.launch
1572
+
1573
+ class AuthViewModel(application: Application) : AndroidViewModel(application) {
1574
+
1575
+ private val repository = UserRepository(application)
1576
+
1577
+ private val _currentUser = MutableStateFlow<User?>(null)
1578
+ val currentUser: StateFlow<User?> = _currentUser.asStateFlow()
1579
+
1580
+ private val _isAuthenticated = MutableStateFlow(false)
1581
+ val isAuthenticated: StateFlow<Boolean> = _isAuthenticated.asStateFlow()
1582
+
1583
+ init {
1584
+ loadCurrentUser()
1585
+ }
1586
+
1587
+ private fun loadCurrentUser() {
1588
+ viewModelScope.launch {
1589
+ val user = repository.getCurrentUser()
1590
+ _currentUser.value = user
1591
+ _isAuthenticated.value = user != null
1592
+ }
1593
+ }
1594
+
1595
+ fun login(username: String) {
1596
+ viewModelScope.launch {
1597
+ val existingUser = repository.getUser(username)
1598
+ val user = existingUser ?: User(username = username, burritoConsiderations = 0)
1599
+ repository.saveUser(user)
1600
+ _currentUser.value = user
1601
+ _isAuthenticated.value = true
1602
+
1603
+ PostHog.identify(username)
1604
+ PostHog.capture(event = "user_logged_in")
1605
+ }
1606
+ }
1607
+
1608
+ fun logout() {
1609
+ viewModelScope.launch {
1610
+ PostHog.capture("user_logged_out")
1611
+ PostHog.reset()
1612
+ repository.clearCurrentUser()
1613
+ _currentUser.value = null
1614
+ _isAuthenticated.value = false
1615
+ }
1616
+ }
1617
+
1618
+ fun incrementBurritoCount() {
1619
+ viewModelScope.launch {
1620
+ val user = _currentUser.value ?: return@launch
1621
+ val updatedUser = user.copy(burritoConsiderations = user.burritoConsiderations + 1)
1622
+ repository.saveUser(updatedUser)
1623
+ _currentUser.value = updatedUser
1624
+
1625
+ PostHog.capture(
1626
+ event = "burrito_considered",
1627
+ properties = mapOf(
1628
+ "total_considerations" to updatedUser.burritoConsiderations,
1629
+ "username" to updatedUser.username
1630
+ )
1631
+ )
1632
+ }
1633
+ }
1634
+ }
1635
+
1636
+ ```
1637
+
1638
+ ---
1639
+