opencode-skills-collection 3.0.51 → 3.1.1

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 (287) hide show
  1. package/README.md +44 -12
  2. package/bundled-skills/.antigravity-install-manifest.json +84 -1
  3. package/bundled-skills/android-ui-journey-testing/SKILL.md +191 -0
  4. package/bundled-skills/ask-matt/SKILL.md +92 -0
  5. package/bundled-skills/bugs-are-annoying/SKILL.md +137 -0
  6. package/bundled-skills/codebase-design/DEEPENING.md +37 -0
  7. package/bundled-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  8. package/bundled-skills/codebase-design/SKILL.md +145 -0
  9. package/bundled-skills/competitor-analysis/LICENSE.txt +21 -0
  10. package/bundled-skills/competitor-analysis/SKILL.md +434 -0
  11. package/bundled-skills/competitor-analysis/references/battle-card-subagent.md +127 -0
  12. package/bundled-skills/competitor-analysis/references/battle-card.md +91 -0
  13. package/bundled-skills/competitor-analysis/references/example-research.md +130 -0
  14. package/bundled-skills/competitor-analysis/references/report-template.html +127 -0
  15. package/bundled-skills/competitor-analysis/references/research-patterns.md +217 -0
  16. package/bundled-skills/competitor-analysis/references/workflow.md +434 -0
  17. package/bundled-skills/competitor-analysis/scripts/capture_screenshots.mjs +142 -0
  18. package/bundled-skills/competitor-analysis/scripts/compile_report.mjs +929 -0
  19. package/bundled-skills/competitor-analysis/scripts/extract_vs_names.mjs +140 -0
  20. package/bundled-skills/competitor-analysis/scripts/gate_candidates.mjs +194 -0
  21. package/bundled-skills/competitor-analysis/scripts/list_urls.mjs +90 -0
  22. package/bundled-skills/competitor-analysis/scripts/md_utils.mjs +50 -0
  23. package/bundled-skills/competitor-analysis/scripts/merge_partials.mjs +291 -0
  24. package/bundled-skills/competitor-analysis/scripts/package.json +6 -0
  25. package/bundled-skills/design-it/3d-ui/SKILL.md +259 -0
  26. package/bundled-skills/design-it/SKILL.md +170 -0
  27. package/bundled-skills/design-it/ai-native-ui/SKILL.md +295 -0
  28. package/bundled-skills/design-it/aurora-ui/SKILL.md +307 -0
  29. package/bundled-skills/design-it/bento-ui/SKILL.md +314 -0
  30. package/bundled-skills/design-it/brutalism/SKILL.md +270 -0
  31. package/bundled-skills/design-it/brutalist-typography/SKILL.md +287 -0
  32. package/bundled-skills/design-it/card-based-design/SKILL.md +262 -0
  33. package/bundled-skills/design-it/claymorphism/SKILL.md +287 -0
  34. package/bundled-skills/design-it/color-blocking/SKILL.md +278 -0
  35. package/bundled-skills/design-it/command-center-ui/SKILL.md +345 -0
  36. package/bundled-skills/design-it/cyber-y2k/SKILL.md +312 -0
  37. package/bundled-skills/design-it/cyberpunk-ui/SKILL.md +262 -0
  38. package/bundled-skills/design-it/dark-mode/SKILL.md +289 -0
  39. package/bundled-skills/design-it/dashboard-design/SKILL.md +331 -0
  40. package/bundled-skills/design-it/data-dense-design/SKILL.md +322 -0
  41. package/bundled-skills/design-it/duotone-design/SKILL.md +248 -0
  42. package/bundled-skills/design-it/editorial-design/SKILL.md +328 -0
  43. package/bundled-skills/design-it/flat-design/SKILL.md +221 -0
  44. package/bundled-skills/design-it/flat-design-2/SKILL.md +240 -0
  45. package/bundled-skills/design-it/floating-ui/SKILL.md +299 -0
  46. package/bundled-skills/design-it/frutiger-aero/SKILL.md +274 -0
  47. package/bundled-skills/design-it/glassmorphism/SKILL.md +272 -0
  48. package/bundled-skills/design-it/gradient-design/SKILL.md +309 -0
  49. package/bundled-skills/design-it/high-contrast/SKILL.md +288 -0
  50. package/bundled-skills/design-it/holographic-ui/SKILL.md +310 -0
  51. package/bundled-skills/design-it/isometric-design/SKILL.md +228 -0
  52. package/bundled-skills/design-it/layered-design/SKILL.md +247 -0
  53. package/bundled-skills/design-it/material-design/SKILL.md +275 -0
  54. package/bundled-skills/design-it/maximalism/SKILL.md +297 -0
  55. package/bundled-skills/design-it/minimalism/SKILL.md +267 -0
  56. package/bundled-skills/design-it/monochromatic-ui/SKILL.md +296 -0
  57. package/bundled-skills/design-it/neo-brutalism/SKILL.md +270 -0
  58. package/bundled-skills/design-it/neumorphism/SKILL.md +248 -0
  59. package/bundled-skills/design-it/retro-design/SKILL.md +283 -0
  60. package/bundled-skills/design-it/retro-futurism/SKILL.md +259 -0
  61. package/bundled-skills/design-it/sci-fi-interface/SKILL.md +309 -0
  62. package/bundled-skills/design-it/skeuomorphism/SKILL.md +280 -0
  63. package/bundled-skills/design-it/soft-pastel/SKILL.md +307 -0
  64. package/bundled-skills/design-it/spatial-computing-ui/SKILL.md +300 -0
  65. package/bundled-skills/design-it/spatial-design/SKILL.md +268 -0
  66. package/bundled-skills/design-it/swiss-design/SKILL.md +293 -0
  67. package/bundled-skills/design-it/synthwave/SKILL.md +257 -0
  68. package/bundled-skills/design-it/tile-design/SKILL.md +297 -0
  69. package/bundled-skills/design-it/typography-first/SKILL.md +247 -0
  70. package/bundled-skills/design-it/vaporwave/SKILL.md +331 -0
  71. package/bundled-skills/design-it/vibrant-maximalism/SKILL.md +291 -0
  72. package/bundled-skills/design-it/widget-based-design/SKILL.md +274 -0
  73. package/bundled-skills/design-it/y2k-design/SKILL.md +268 -0
  74. package/bundled-skills/diagnosing-bugs/SKILL.md +165 -0
  75. package/bundled-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  76. package/bundled-skills/docs/contributors/skill-scoring.md +235 -0
  77. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  78. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  79. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  80. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  81. package/bundled-skills/docs/users/bundles.md +1 -1
  82. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  83. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  84. package/bundled-skills/docs/users/getting-started.md +1 -1
  85. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  86. package/bundled-skills/docs/users/usage.md +4 -4
  87. package/bundled-skills/docs/users/visual-guide.md +4 -4
  88. package/bundled-skills/domain-modeling/ADR-FORMAT.md +47 -0
  89. package/bundled-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  90. package/bundled-skills/domain-modeling/SKILL.md +105 -0
  91. package/bundled-skills/grill-me/SKILL.md +36 -0
  92. package/bundled-skills/grill-with-docs/SKILL.md +36 -0
  93. package/bundled-skills/grilling/SKILL.md +39 -0
  94. package/bundled-skills/handoff/SKILL.md +45 -0
  95. package/bundled-skills/image-generator/.env.example +7 -0
  96. package/bundled-skills/image-generator/SKILL.md +509 -0
  97. package/bundled-skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
  98. package/bundled-skills/improve-codebase-architecture/SKILL.md +97 -0
  99. package/bundled-skills/learn/SKILL.md +156 -0
  100. package/bundled-skills/lesson-generator/SKILL.md +90 -0
  101. package/bundled-skills/llm-council/.env.example +7 -0
  102. package/bundled-skills/llm-council/SKILL.md +602 -0
  103. package/bundled-skills/loop-library/SKILL.md +205 -0
  104. package/bundled-skills/loop-library/agents/openai.yaml +4 -0
  105. package/bundled-skills/loop-library/references/catalog.md +270 -0
  106. package/bundled-skills/mailtrap-managing-contacts/SKILL.md +112 -0
  107. package/bundled-skills/mailtrap-sending-emails/SKILL.md +167 -0
  108. package/bundled-skills/mailtrap-setting-up-sending-domain/SKILL.md +77 -0
  109. package/bundled-skills/mailtrap-testing-with-sandbox/SKILL.md +110 -0
  110. package/bundled-skills/prototype/LOGIC.md +79 -0
  111. package/bundled-skills/prototype/SKILL.md +62 -0
  112. package/bundled-skills/prototype/UI.md +112 -0
  113. package/bundled-skills/setup-matt-pocock-skills/SKILL.md +158 -0
  114. package/bundled-skills/setup-matt-pocock-skills/domain.md +51 -0
  115. package/bundled-skills/setup-matt-pocock-skills/issue-tracker-github.md +34 -0
  116. package/bundled-skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +35 -0
  117. package/bundled-skills/setup-matt-pocock-skills/issue-tracker-local.md +19 -0
  118. package/bundled-skills/setup-matt-pocock-skills/triage-labels.md +15 -0
  119. package/bundled-skills/survey-generator/LICENSE +21 -0
  120. package/bundled-skills/survey-generator/SKILL.md +143 -0
  121. package/bundled-skills/survey-generator/build_artifact.py +208 -0
  122. package/bundled-skills/survey-generator/examples/agentic-engineering/research_bundle.json +1196 -0
  123. package/bundled-skills/survey-generator/examples/agentic-engineering/survey.html +706 -0
  124. package/bundled-skills/survey-generator/style_spec.json +85 -0
  125. package/bundled-skills/survey-generator/templates/research_bundle_template.json +69 -0
  126. package/bundled-skills/tdd/SKILL.md +139 -0
  127. package/bundled-skills/tdd/mocking.md +59 -0
  128. package/bundled-skills/tdd/refactoring.md +10 -0
  129. package/bundled-skills/tdd/tests.md +61 -0
  130. package/bundled-skills/teach/GLOSSARY-FORMAT.md +35 -0
  131. package/bundled-skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
  132. package/bundled-skills/teach/MISSION-FORMAT.md +31 -0
  133. package/bundled-skills/teach/RESOURCES-FORMAT.md +32 -0
  134. package/bundled-skills/teach/SKILL.md +169 -0
  135. package/bundled-skills/to-issues/SKILL.md +115 -0
  136. package/bundled-skills/to-prd/SKILL.md +104 -0
  137. package/bundled-skills/tools-page-seo-optimizer/SKILL.md +616 -0
  138. package/bundled-skills/triage/AGENT-BRIEF.md +207 -0
  139. package/bundled-skills/triage/OUT-OF-SCOPE.md +105 -0
  140. package/bundled-skills/triage/SKILL.md +143 -0
  141. package/bundled-skills/vibecode-production-qa-validator/SKILL.md +371 -141
  142. package/bundled-skills/wiki-builder/SKILL.md +157 -0
  143. package/bundled-skills/wiki-builder/agents/openai.yaml +5 -0
  144. package/bundled-skills/wiki-builder/references/wiki-flavors.md +98 -0
  145. package/bundled-skills/wiki-builder/scripts/init_wiki.sh +105 -0
  146. package/bundled-skills/wiki-builder/templates/index.md +20 -0
  147. package/bundled-skills/wiki-builder/templates/maintenance-log.md +7 -0
  148. package/bundled-skills/wiki-builder/templates/prompts/compile-concept-page.md +12 -0
  149. package/bundled-skills/wiki-builder/templates/prompts/compile-index.md +11 -0
  150. package/bundled-skills/wiki-builder/templates/prompts/compile-source-page.md +12 -0
  151. package/bundled-skills/wiki-builder/templates/prompts/lint-wiki.md +10 -0
  152. package/bundled-skills/wiki-builder/templates/prompts/query-and-file.md +11 -0
  153. package/bundled-skills/wiki-builder/templates/sources.md +9 -0
  154. package/bundled-skills/wiki-builder/templates/wiki.config.md +53 -0
  155. package/bundled-skills/writing-great-skills/GLOSSARY.md +181 -0
  156. package/bundled-skills/writing-great-skills/SKILL.md +111 -0
  157. package/bundled-skills/yao-meta-skill/SKILL.md +86 -0
  158. package/bundled-skills/yao-meta-skill/agents/interface.yaml +26 -0
  159. package/bundled-skills/yao-meta-skill/manifest.json +24 -0
  160. package/bundled-skills/yao-meta-skill/references/artifact-design-doctrine.md +49 -0
  161. package/bundled-skills/yao-meta-skill/references/authoring-discipline.md +78 -0
  162. package/bundled-skills/yao-meta-skill/references/autonomous-adaptation.md +65 -0
  163. package/bundled-skills/yao-meta-skill/references/distribution-registry-method.md +60 -0
  164. package/bundled-skills/yao-meta-skill/references/eval-playbook.md +69 -0
  165. package/bundled-skills/yao-meta-skill/references/gate-selection.md +68 -0
  166. package/bundled-skills/yao-meta-skill/references/governance.md +134 -0
  167. package/bundled-skills/yao-meta-skill/references/human-review-template.md +54 -0
  168. package/bundled-skills/yao-meta-skill/references/intent-dialogue.md +138 -0
  169. package/bundled-skills/yao-meta-skill/references/iteration-philosophy.md +30 -0
  170. package/bundled-skills/yao-meta-skill/references/non-skill-decision-tree.md +39 -0
  171. package/bundled-skills/yao-meta-skill/references/operating-modes.md +107 -0
  172. package/bundled-skills/yao-meta-skill/references/output-eval-method.md +113 -0
  173. package/bundled-skills/yao-meta-skill/references/output-quality-risk.md +41 -0
  174. package/bundled-skills/yao-meta-skill/references/output-visual-quality.md +53 -0
  175. package/bundled-skills/yao-meta-skill/references/packaging-contracts.md +70 -0
  176. package/bundled-skills/yao-meta-skill/references/pattern-extraction-doctrine.md +76 -0
  177. package/bundled-skills/yao-meta-skill/references/platform-capability-matrix.md +49 -0
  178. package/bundled-skills/yao-meta-skill/references/prompt-engineering-doctrine.md +76 -0
  179. package/bundled-skills/yao-meta-skill/references/qa-ladder.md +57 -0
  180. package/bundled-skills/yao-meta-skill/references/reference-scan.md +126 -0
  181. package/bundled-skills/yao-meta-skill/references/regression-cause-taxonomy.md +80 -0
  182. package/bundled-skills/yao-meta-skill/references/resource-boundaries.md +120 -0
  183. package/bundled-skills/yao-meta-skill/references/review-studio-method.md +87 -0
  184. package/bundled-skills/yao-meta-skill/references/review-waiver-method.md +76 -0
  185. package/bundled-skills/yao-meta-skill/references/runtime-conformance-method.md +21 -0
  186. package/bundled-skills/yao-meta-skill/references/skill-archetypes.md +86 -0
  187. package/bundled-skills/yao-meta-skill/references/skill-atlas-method.md +35 -0
  188. package/bundled-skills/yao-meta-skill/references/skill-engineering-method.md +210 -0
  189. package/bundled-skills/yao-meta-skill/references/skill-ir-method.md +41 -0
  190. package/bundled-skills/yao-meta-skill/references/skillops-decision-policy.md +53 -0
  191. package/bundled-skills/yao-meta-skill/references/systems-thinking-doctrine.md +75 -0
  192. package/bundled-skills/yao-meta-skill/references/telemetry-drift-method.md +182 -0
  193. package/bundled-skills/yao-meta-skill/references/trust-security-method.md +79 -0
  194. package/bundled-skills/yao-meta-skill/references/user-memory-policy.md +35 -0
  195. package/bundled-skills/youtube-notetaker/SKILL.md +209 -0
  196. package/bundled-skills/youtube-notetaker/reference/artifact.html +269 -0
  197. package/bundled-skills/youtube-notetaker/scripts/contact_sheet.py +53 -0
  198. package/bundled-skills/youtube-notetaker/scripts/detect_slides.sh +19 -0
  199. package/bundled-skills/youtube-notetaker/scripts/download.sh +24 -0
  200. package/bundled-skills/youtube-notetaker/scripts/extract_slides.py +43 -0
  201. package/bundled-skills/youtube-notetaker/scripts/serve.py +173 -0
  202. package/bundled-skills/youtube-notetaker/scripts/setup.sh +27 -0
  203. package/bundled-skills/youtube-notetaker/scripts/verify.sh +31 -0
  204. package/bundled-skills/youtube-notetaker/scripts/vtt_to_transcript.py +59 -0
  205. package/bundled-skills/youtube-notetaker/scripts/write_library_item.py +69 -0
  206. package/dist/skill-pointer/config-loader.d.ts +14 -0
  207. package/dist/skill-pointer/config-loader.js +30 -3
  208. package/dist/skill-pointer/content-scanner.d.ts +38 -0
  209. package/dist/skill-pointer/content-scanner.js +118 -0
  210. package/dist/skill-pointer/index.d.ts +7 -2
  211. package/dist/skill-pointer/index.js +14 -4
  212. package/dist/skill-pointer/pointer-generator.js +2 -0
  213. package/dist/skill-pointer/skill-patcher.d.ts +13 -0
  214. package/dist/skill-pointer/skill-patcher.js +99 -0
  215. package/package.json +1 -1
  216. package/skills_index.json +1956 -286
  217. package/bundled-skills/ai-md/SKILL.md +0 -523
  218. package/bundled-skills/atlas-contract/SKILL.md +0 -650
  219. package/bundled-skills/busybox-on-windows/SKILL.md +0 -40
  220. package/bundled-skills/monte-carlo-prevent/SKILL.md +0 -257
  221. package/bundled-skills/monte-carlo-prevent/references/TROUBLESHOOTING.md +0 -23
  222. package/bundled-skills/monte-carlo-prevent/references/parameters.md +0 -32
  223. package/bundled-skills/monte-carlo-prevent/references/workflows.md +0 -478
  224. package/bundled-skills/monte-carlo-push-ingestion/SKILL.md +0 -372
  225. package/bundled-skills/monte-carlo-push-ingestion/references/anomaly-detection.md +0 -87
  226. package/bundled-skills/monte-carlo-push-ingestion/references/custom-lineage.md +0 -203
  227. package/bundled-skills/monte-carlo-push-ingestion/references/direct-http-api.md +0 -207
  228. package/bundled-skills/monte-carlo-push-ingestion/references/prerequisites.md +0 -150
  229. package/bundled-skills/monte-carlo-push-ingestion/references/push-lineage.md +0 -160
  230. package/bundled-skills/monte-carlo-push-ingestion/references/push-metadata.md +0 -158
  231. package/bundled-skills/monte-carlo-push-ingestion/references/push-query-logs.md +0 -219
  232. package/bundled-skills/monte-carlo-push-ingestion/references/validation.md +0 -257
  233. package/bundled-skills/monte-carlo-push-ingestion/scripts/sample_verify.py +0 -357
  234. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_lineage.py +0 -70
  235. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_metadata.py +0 -65
  236. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_query_logs.py +0 -70
  237. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_lineage.py +0 -214
  238. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_metadata.py +0 -160
  239. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_query_logs.py +0 -164
  240. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_lineage.py +0 -198
  241. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_metadata.py +0 -193
  242. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_query_logs.py +0 -207
  243. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_and_push_metadata.py +0 -71
  244. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_and_push_query_logs.py +0 -64
  245. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_metadata.py +0 -253
  246. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_query_logs.py +0 -149
  247. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/push_metadata.py +0 -190
  248. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/push_query_logs.py +0 -208
  249. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_lineage.py +0 -83
  250. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_metadata.py +0 -77
  251. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_query_logs.py +0 -83
  252. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_lineage.py +0 -240
  253. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_metadata.py +0 -212
  254. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_query_logs.py +0 -204
  255. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_lineage.py +0 -192
  256. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_metadata.py +0 -178
  257. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_query_logs.py +0 -200
  258. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_lineage.py +0 -119
  259. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_metadata.py +0 -119
  260. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_query_logs.py +0 -117
  261. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_lineage.py +0 -265
  262. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_metadata.py +0 -313
  263. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_query_logs.py +0 -284
  264. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_lineage.py +0 -309
  265. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_metadata.py +0 -245
  266. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_query_logs.py +0 -255
  267. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_lineage.py +0 -78
  268. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_metadata.py +0 -80
  269. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_query_logs.py +0 -88
  270. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_lineage.py +0 -235
  271. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_metadata.py +0 -219
  272. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_query_logs.py +0 -239
  273. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_lineage.py +0 -178
  274. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_metadata.py +0 -178
  275. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_query_logs.py +0 -196
  276. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_lineage.py +0 -154
  277. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_metadata.py +0 -137
  278. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_query_logs.py +0 -137
  279. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_lineage.py +0 -349
  280. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_metadata.py +0 -329
  281. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_query_logs.py +0 -254
  282. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_lineage.py +0 -307
  283. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_metadata.py +0 -228
  284. package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_query_logs.py +0 -248
  285. package/bundled-skills/monte-carlo-push-ingestion/scripts/test_template_sdk_usage.py +0 -340
  286. package/bundled-skills/skill-optimizer/SKILL.md +0 -271
  287. package/bundled-skills/using-superpowers/SKILL.md +0 -98
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Merges per-lane partial markdown files into one consolidated file per competitor.
4
+ //
5
+ // The 5-lane subagent fan-out writes partials to: {OUTPUT_DIR}/partials/{slug}.{lane}.md
6
+ // lane ∈ { marketing, discussion, social, news, technical }
7
+ //
8
+ // Each partial has its own YAML frontmatter + sections. The marketing partial owns
9
+ // the canonical frontmatter (pricing, features, etc.); other lanes contribute only
10
+ // Mentions / Benchmarks / Findings bullets. The merge:
11
+ // 1. Starts from marketing.md's frontmatter as the canonical header
12
+ // 2. Appends body sections in the canonical order (Product, Pricing, Features,
13
+ // Positioning, Comparison, Mentions, Benchmarks, Research Findings)
14
+ // 3. Unions all Mentions bullets across lanes, dedups by URL, sorts by date desc
15
+ // 4. Unions all Research Findings bullets across lanes
16
+ // 5. Unions all Benchmarks bullets
17
+ // 6. Writes the consolidated file to {OUTPUT_DIR}/{slug}.md
18
+ //
19
+ // Usage: node merge_partials.mjs <research-dir>
20
+
21
+ import { readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
22
+ import { join } from 'path';
23
+ import { parseFrontmatter, parseBody, parseSections } from './md_utils.mjs';
24
+
25
+ const args = process.argv.slice(2);
26
+ if (args.includes('--help') || args.includes('-h') || args.length === 0) {
27
+ console.error(`Usage: node merge_partials.mjs <research-dir>
28
+
29
+ Reads {dir}/partials/{slug}.{lane}.md files and writes consolidated
30
+ {dir}/{slug}.md per competitor. Lanes: marketing, discussion, social, news, technical.`);
31
+ process.exit(args.includes('--help') || args.includes('-h') ? 0 : 1);
32
+ }
33
+
34
+ const dir = args[0];
35
+ const partialsDir = join(dir, 'partials');
36
+
37
+ const LANES = ['marketing', 'discussion', 'social', 'news', 'technical', 'battle'];
38
+
39
+ function extractBullets(sectionText) {
40
+ if (!sectionText) return [];
41
+ const out = [];
42
+ for (const raw of sectionText.split('\n')) {
43
+ const line = raw.trim();
44
+ // Accept either "- ..." or numbered-list "1. ..." — normalize both to "- ...".
45
+ if (line.startsWith('- ')) out.push(line);
46
+ else {
47
+ const m = line.match(/^\d+\.\s+(.*)$/);
48
+ if (m) out.push('- ' + m[1]);
49
+ }
50
+ }
51
+ return out;
52
+ }
53
+
54
+ // Normalize Mentions bullet lines to the canonical format that `compile_report.mjs`
55
+ // parses: `- **[SourceType]** Title | Snippet (source: URL, YYYY-MM-DD)`.
56
+ //
57
+ // Lane subagents deviate in practice — we've observed at least three variants:
58
+ // A) discussion-style: `- **HN** — [Title](url) — snippet`
59
+ // B) news-style: `- **2025-08-06** — [News] Outlet — "title" — url`
60
+ // C) canonical: `- **[SourceType]** Title | Snippet (source: URL, YYYY-MM-DD)`
61
+ // Rather than fighting prompt drift, normalize at merge time so downstream stays clean.
62
+ function normalizeMentionBullet(line) {
63
+ // Already canonical — nothing to do.
64
+ if (/^-\s*\*\*\[\w+\]\*\*/.test(line)) return line;
65
+
66
+ const urlMatch = line.match(/https?:\/\/\S+/);
67
+ const url = urlMatch ? urlMatch[0].replace(/[).,\]\s]+$/, '') : '';
68
+ const dateMatch = line.match(/\b(\d{4}-\d{2}-\d{2})\b/);
69
+ const date = dateMatch ? dateMatch[1] : '';
70
+
71
+ // Pattern A — `- **SourceType** — [Title](url) — snippet` (e.g. discussion lane)
72
+ // **SourceType** is bold but without the brackets we want in canonical form.
73
+ let m = line.match(/^-\s*\*\*([^*]+)\*\*\s*[—\-]\s*\[([^\]]+)\]\(([^)]+)\)\s*(?:[—\-]\s*(.*))?$/);
74
+ if (m) {
75
+ const [, rawType, title, linkUrl, snippet] = m;
76
+ const sourceType = rawType.trim().replace(/^\[|\]$/g, '');
77
+ const snippetStr = snippet && snippet.trim() ? ` | ${snippet.trim()}` : '';
78
+ const dateStr = date ? `, ${date}` : '';
79
+ return `- **[${sourceType}]** ${title.trim()}${snippetStr} (source: ${linkUrl}${dateStr})`;
80
+ }
81
+
82
+ // Pattern B — `- **YYYY-MM-DD** — [SourceType] Outlet — "title" — url` (e.g. news lane)
83
+ m = line.match(/^-\s*\*\*(\d{4}-\d{2}-\d{2})\*\*\s*[—\-]\s*\[(\w+)\]\s+([^—]+?)\s*[—\-]\s*"?([^"]+?)"?\s*(?:[—\-]\s*(\S+))?\s*$/);
84
+ if (m) {
85
+ const [, dateStr, sourceType, outlet, title, trailingUrl] = m;
86
+ const finalUrl = trailingUrl && trailingUrl.startsWith('http') ? trailingUrl : url;
87
+ const snippet = outlet.trim();
88
+ return `- **[${sourceType}]** ${title.trim()}${snippet ? ` | ${snippet}` : ''} (source: ${finalUrl || ''}, ${dateStr})`;
89
+ }
90
+
91
+ // Pattern C — generic fallback: find any `**X**` tag + URL and format canonically.
92
+ m = line.match(/^-\s*\*\*([^*]+)\*\*\s*(.*)/);
93
+ if (m && url) {
94
+ const rawType = m[1].trim().replace(/^\[|\]$/g, '');
95
+ // If the leading token is a date, try to pull a later **type** off the rest.
96
+ let sourceType = rawType;
97
+ if (/^\d{4}-\d{2}-\d{2}$/.test(rawType)) {
98
+ const innerType = m[2].match(/\[(\w+)\]/);
99
+ if (innerType) sourceType = innerType[1];
100
+ }
101
+ const linkTextM = m[2].match(/\[([^\]]+)\]/);
102
+ const title = linkTextM ? linkTextM[1] : m[2].replace(url, '').replace(/[—"]+/g, '').replace(/^\W+|\W+$/g, '').slice(0, 100);
103
+ const dateStr = date ? `, ${date}` : '';
104
+ return `- **[${sourceType}]** ${title.trim()} (source: ${url}${dateStr})`;
105
+ }
106
+
107
+ // Last resort — leave line untouched (preserves data even if un-parseable).
108
+ return line;
109
+ }
110
+
111
+ function urlOf(bullet) {
112
+ const m = bullet.match(/\(source:\s*([^,)]+)/);
113
+ return m ? m[1].trim() : null;
114
+ }
115
+
116
+ function dateOf(bullet) {
117
+ const m = bullet.match(/\(source:\s*[^,)]+,\s*(\d{4}-\d{2}-\d{2})/);
118
+ return m ? m[1] : '';
119
+ }
120
+
121
+ let files;
122
+ try { files = readdirSync(partialsDir); } catch {
123
+ console.error(`No partials directory at ${partialsDir} — nothing to merge.`);
124
+ process.exit(0);
125
+ }
126
+
127
+ // Group partials by slug
128
+ const bySlug = new Map();
129
+ for (const f of files) {
130
+ if (!f.endsWith('.md')) continue;
131
+ const m = f.match(/^(.+)\.([a-z]+)\.md$/);
132
+ if (!m) continue;
133
+ const slug = m[1];
134
+ const lane = m[2];
135
+ if (!LANES.includes(lane)) continue;
136
+ if (!bySlug.has(slug)) bySlug.set(slug, {});
137
+ const content = readFileSync(join(partialsDir, f), 'utf-8');
138
+ bySlug.get(slug)[lane] = { fm: parseFrontmatter(content), body: parseBody(content) };
139
+ }
140
+
141
+ let merged = 0;
142
+ for (const [slug, lanes] of bySlug.entries()) {
143
+ const marketing = lanes.marketing;
144
+ if (!marketing || !marketing.fm) {
145
+ console.error(`[skip] ${slug}: no marketing partial — cannot form canonical frontmatter`);
146
+ continue;
147
+ }
148
+
149
+ // Union body sections
150
+ const allSections = {};
151
+ for (const lane of LANES) {
152
+ if (!lanes[lane]) continue;
153
+ const secs = parseSections(lanes[lane].body);
154
+ for (const [k, v] of Object.entries(secs)) {
155
+ if (!allSections[k]) allSections[k] = [];
156
+ allSections[k].push(v);
157
+ }
158
+ }
159
+
160
+ // Normalize → dedup Mentions by URL, sort by date desc
161
+ const rawBullets = (allSections['Mentions'] || []).flatMap(s => extractBullets(s));
162
+ const mentionBullets = rawBullets.map(normalizeMentionBullet);
163
+ const seenUrls = new Set();
164
+ const dedupedMentions = [];
165
+ for (const b of mentionBullets) {
166
+ const u = urlOf(b);
167
+ const key = u || b; // fallback to bullet text if no URL
168
+ if (seenUrls.has(key)) continue;
169
+ seenUrls.add(key);
170
+ dedupedMentions.push(b);
171
+ }
172
+ dedupedMentions.sort((a, b) => {
173
+ const da = dateOf(a), db = dateOf(b);
174
+ if (da && db) return db.localeCompare(da);
175
+ if (da) return -1;
176
+ if (db) return 1;
177
+ return 0;
178
+ });
179
+
180
+ // Dedup Benchmarks by URL
181
+ const benchmarkBullets = (allSections['Benchmarks'] || []).flatMap(s => extractBullets(s));
182
+ const seenBench = new Set();
183
+ const dedupedBench = [];
184
+ for (const b of benchmarkBullets) {
185
+ const m = b.match(/https?:\/\/\S+/);
186
+ const key = m ? m[0] : b;
187
+ if (seenBench.has(key)) continue;
188
+ seenBench.add(key);
189
+ dedupedBench.push(b);
190
+ }
191
+
192
+ // Dedup Findings loosely (by exact text)
193
+ const findingBullets = (allSections['Research Findings'] || []).flatMap(s => extractBullets(s));
194
+ const dedupedFindings = [...new Set(findingBullets)];
195
+
196
+ // Merge/prefer marketing for Product/Pricing/Features/Positioning/Comparison
197
+ function first(key) {
198
+ const arr = allSections[key] || [];
199
+ return arr.length ? arr[0] : '';
200
+ }
201
+
202
+ // Rebuild frontmatter — whitelist canonical fields only. Non-marketing lane subagents
203
+ // sometimes leak ad-hoc meta fields (notes, searches_run, lane, etc.) into their partial's
204
+ // frontmatter; those are debug/summary fields, not canonical data. Drop them here.
205
+ const CANONICAL_FIELDS = [
206
+ 'competitor_name', 'website', 'pricing_url',
207
+ 'tagline', 'positioning', 'product_description', 'target_customer',
208
+ 'pricing_model', 'pricing_tiers', 'key_features', 'integrations',
209
+ 'headquarters', 'founded', 'employee_estimate', 'funding_info',
210
+ 'strategic_diff',
211
+ ];
212
+ // Subagents drift on canonical field names too. Common aliases observed in real runs:
213
+ // `competitor` → `competitor_name` (browsaur marketing subagent), `homepage` → `website`,
214
+ // `price_tiers` → `pricing_tiers`. Accept aliases silently.
215
+ //
216
+ // NOTE: a bare `pricing` key is mapped to `pricing_model`, NOT `pricing_tiers`. In practice
217
+ // subagents use `pricing` for a pricing *model* or prose summary ("usage-based", "$0.005/req")
218
+ // far more often than for an enumerated tier list, so routing it to `pricing_tiers` corrupted
219
+ // the structured tier data the overview/matrix render from. Use `price_tiers`/`pricing_tiers`
220
+ // explicitly for tiers.
221
+ const FIELD_ALIASES = {
222
+ 'competitor': 'competitor_name',
223
+ 'name': 'competitor_name',
224
+ 'company': 'competitor_name',
225
+ 'homepage': 'website',
226
+ 'url': 'website',
227
+ 'price_tiers': 'pricing_tiers',
228
+ 'pricing': 'pricing_model',
229
+ };
230
+ function canonicalValue(fm, key) {
231
+ if (fm[key]) return fm[key];
232
+ for (const [alias, canonical] of Object.entries(FIELD_ALIASES)) {
233
+ if (canonical === key && fm[alias]) return fm[alias];
234
+ }
235
+ return undefined;
236
+ }
237
+ const mergedFm = {};
238
+ for (const k of CANONICAL_FIELDS) {
239
+ const v = canonicalValue(marketing.fm, k);
240
+ if (v) mergedFm[k] = v;
241
+ }
242
+ // Other lanes may fill in canonical gaps (e.g. funding_info from news, strategic_diff from technical).
243
+ for (const lane of LANES) {
244
+ if (lane === 'marketing' || !lanes[lane] || !lanes[lane].fm) continue;
245
+ for (const k of CANONICAL_FIELDS) {
246
+ if (!mergedFm[k]) {
247
+ const v = canonicalValue(lanes[lane].fm, k);
248
+ if (v) mergedFm[k] = v;
249
+ }
250
+ }
251
+ }
252
+
253
+ const fmLines = Object.entries(mergedFm).map(([k, v]) => `${k}: ${v}`).join('\n');
254
+
255
+ // Comparison heading may be "Comparison vs Exa" etc — find any key starting with "Comparison"
256
+ const comparisonKey = Object.keys(allSections).find(k => k.startsWith('Comparison'));
257
+ // Battle lane is format-drifty: subagents emit `## Battle Card`, `# Battle Card: X vs Y`
258
+ // (h1 — not picked up by parseSections), or skip the wrapper and lead with `## Landmines`.
259
+ // Treat the ENTIRE battle partial body as the Battle Card section regardless of heading style,
260
+ // so sales enablement content always lands in the merged file.
261
+ let battleCardBody = '';
262
+ if (lanes.battle && lanes.battle.body) {
263
+ const body = lanes.battle.body.trim();
264
+ // Strip the FIRST heading line if it mentions "Battle Card" — handles h1/h2/h3 and any
265
+ // suffix (e.g. `## Battle Card — Serper`, `# Battle Card: Tavily`). Otherwise the
266
+ // canonical `## Battle Card` wrapper added below produces duplicate headings.
267
+ battleCardBody = body.replace(/^#{1,3}\s+Battle\s*Card\b[^\n]*\n+/m, '').trim();
268
+ }
269
+
270
+ const out = [
271
+ '---',
272
+ fmLines,
273
+ '---',
274
+ '',
275
+ first('Product') ? `## Product\n${first('Product')}\n` : '',
276
+ first('Pricing') ? `## Pricing\n${first('Pricing')}\n` : '',
277
+ first('Features') ? `## Features\n${first('Features')}\n` : '',
278
+ first('Positioning') ? `## Positioning\n${first('Positioning')}\n` : '',
279
+ comparisonKey && allSections[comparisonKey].length ? `## ${comparisonKey}\n${allSections[comparisonKey][0]}\n` : '',
280
+ battleCardBody ? `## Battle Card\n${battleCardBody}\n` : '',
281
+ dedupedMentions.length ? `## Mentions\n${dedupedMentions.join('\n')}\n` : '',
282
+ dedupedBench.length ? `## Benchmarks\n${dedupedBench.join('\n')}\n` : '',
283
+ dedupedFindings.length ? `## Research Findings\n${dedupedFindings.join('\n')}\n` : '',
284
+ ].filter(Boolean).join('\n');
285
+
286
+ writeFileSync(join(dir, `${slug}.md`), out);
287
+ merged += 1;
288
+ console.error(`[ok] ${slug}: ${dedupedMentions.length} mentions, ${dedupedBench.length} benchmarks, ${dedupedFindings.length} findings`);
289
+ }
290
+
291
+ console.log(JSON.stringify({ merged, competitors: bySlug.size }));
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "competitor-analysis-scripts",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module"
6
+ }
@@ -0,0 +1,259 @@
1
+ ---
2
+ name: 3d-ui
3
+ description: Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth.
4
+ date_added: "2026-06-17"
5
+ risk: safe
6
+ source: self
7
+ source_type: self
8
+ ---
9
+
10
+ # 3D UI
11
+
12
+ > "Breaking the plane. Interfaces that exist in a three-dimensional, rotatable space."
13
+
14
+
15
+ ## When to Use
16
+ Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly.
17
+
18
+ ## Core Principles
19
+ 1. **True Depth (Z-Axis Translation)**: Elements don't just have shadows; they physically move closer to or further from the camera.
20
+ 2. **Perspective**: Use CSS perspective or WebGL to create realistic vanishing points.
21
+ 3. **Interactive Rotation**: Elements should respond to mouse movement or device gyroscope by tilting or rotating in 3D space.
22
+
23
+ ## Visual DNA
24
+ - **Colors**: Bold, striking palettes like **Midnight Luxury** or **Industrial Chic**. 3D elements need high contrast to show their geometry.
25
+ - **Typography**: Bold, blocky, or extruded text.
26
+ - **Graphics**: Instead of flat icons, use rendered 3D assets (.glb, .gltf, or high-res PNGs of 3D objects).
27
+
28
+ ## Web Implementation
29
+ - Rely heavily on `perspective`, `transform-style: preserve-3d`, and `rotateX`/`rotateY`.
30
+ - **CSS Example**:
31
+ ```css
32
+ .perspective-container {
33
+ perspective: 1000px;
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+ }
38
+
39
+ .card-3d {
40
+ width: 300px;
41
+ height: 400px;
42
+ transform-style: preserve-3d;
43
+ transition: transform 0.5s ease;
44
+
45
+ /* Initial slight rotation */
46
+ transform: rotateX(15deg) rotateY(-15deg);
47
+ }
48
+
49
+ .card-3d:hover {
50
+ /* Straighten out on hover */
51
+ transform: rotateX(0) rotateY(0) translateZ(50px);
52
+ }
53
+
54
+ /* Inner elements popping out */
55
+ .card-content {
56
+ transform: translateZ(30px); /* Pushes content 30px closer to viewer */
57
+ }
58
+ ```
59
+
60
+ ## App Implementation
61
+
62
+ ### SwiftUI
63
+ ```swift
64
+ struct Card3D: View {
65
+ @State private var dragOffset = CGSize.zero
66
+
67
+ var body: some View {
68
+ VStack {
69
+ Text("3D Card")
70
+ .font(.largeTitle.bold())
71
+ .foregroundColor(.white)
72
+ }
73
+ .frame(width: 300, height: 400)
74
+ .background(
75
+ LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing)
76
+ )
77
+ .cornerRadius(24)
78
+ .shadow(radius: 20)
79
+ // Magic 3D effect based on drag gesture
80
+ .rotation3DEffect(
81
+ .degrees(Double(dragOffset.width / 10)),
82
+ axis: (x: 0, y: 1, z: 0),
83
+ perspective: 0.5
84
+ )
85
+ .rotation3DEffect(
86
+ .degrees(Double(-dragOffset.height / 10)),
87
+ axis: (x: 1, y: 0, z: 0),
88
+ perspective: 0.5
89
+ )
90
+ .gesture(
91
+ DragGesture()
92
+ .onChanged { value in
93
+ withAnimation(.interactiveSpring()) {
94
+ dragOffset = value.translation
95
+ }
96
+ }
97
+ .onEnded { _ in
98
+ withAnimation(.spring()) {
99
+ dragOffset = .zero
100
+ }
101
+ }
102
+ )
103
+ }
104
+ }
105
+ ```
106
+ - SwiftUI makes this incredibly easy with `.rotation3DEffect()`.
107
+ - Use the `perspective` parameter (default 1/6, higher = more distorted) to control the camera distance.
108
+ - Link the rotation axes (`x`, `y`) to drag gestures or CoreMotion (gyroscope) for interactive 3D UI.
109
+
110
+ ### Flutter
111
+ ```dart
112
+ class Card3D extends StatefulWidget {
113
+ @override
114
+ State<Card3D> createState() => _Card3DState();
115
+ }
116
+
117
+ class _Card3DState extends State<Card3D> {
118
+ Offset _offset = Offset.zero;
119
+
120
+ @override
121
+ Widget build(BuildContext context) {
122
+ return GestureDetector(
123
+ onPanUpdate: (details) {
124
+ setState(() => _offset += details.delta);
125
+ },
126
+ onPanEnd: (_) {
127
+ setState(() => _offset = Offset.zero); // Snap back
128
+ },
129
+ child: TweenAnimationBuilder(
130
+ tween: Tween<Offset>(begin: Offset.zero, end: _offset),
131
+ duration: const Duration(milliseconds: 200),
132
+ curve: Curves.easeOut,
133
+ builder: (context, Offset offset, child) {
134
+ // Perspective Matrix
135
+ final transform = Matrix4.identity()
136
+ ..setEntry(3, 2, 0.001) // perspective
137
+ ..rotateX(-offset.dy * 0.01)
138
+ ..rotateY(offset.dx * 0.01);
139
+
140
+ return Transform(
141
+ transform: transform,
142
+ alignment: FractionalOffset.center,
143
+ child: Container(
144
+ width: 300,
145
+ height: 400,
146
+ decoration: BoxDecoration(
147
+ gradient: const LinearGradient(colors: [Colors.blue, Colors.purple]),
148
+ borderRadius: BorderRadius.circular(24),
149
+ boxShadow: const [BoxShadow(color: Colors.black45, blurRadius: 20)],
150
+ ),
151
+ alignment: Alignment.center,
152
+ child: const Text('3D Card',
153
+ style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)),
154
+ ),
155
+ );
156
+ },
157
+ ),
158
+ );
159
+ }
160
+ }
161
+ ```
162
+ - The secret to perspective in Flutter is `Matrix4.identity()..setEntry(3, 2, 0.001)`.
163
+ - Wrap the target container in a `Transform` widget and apply rotations on the X and Y axes.
164
+ - Use `TweenAnimationBuilder` to smooth out the return-to-center physics.
165
+
166
+ ### React Native
167
+ ```jsx
168
+ const Card3D = () => {
169
+ const pan = useRef(new Animated.ValueXY()).current;
170
+
171
+ const panResponder = useRef(
172
+ PanResponder.create({
173
+ onStartShouldSetPanResponder: () => true,
174
+ onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }),
175
+ onPanResponderRelease: () => {
176
+ Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false }).start();
177
+ },
178
+ })
179
+ ).current;
180
+
181
+ // Map drag distance to degrees
182
+ const rotateX = pan.y.interpolate({ inputRange: [-200, 200], outputRange: ['20deg', '-20deg'] });
183
+ const rotateY = pan.x.interpolate({ inputRange: [-200, 200], outputRange: ['-20deg', '20deg'] });
184
+
185
+ return (
186
+ <Animated.View
187
+ {...panResponder.panHandlers}
188
+ style={{
189
+ width: 300, height: 400,
190
+ backgroundColor: '#6b21a8',
191
+ borderRadius: 24,
192
+ justifyContent: 'center', alignItems: 'center',
193
+ // Pseudo-3D transforms
194
+ transform: [
195
+ { perspective: 1000 },
196
+ { rotateX },
197
+ { rotateY }
198
+ ]
199
+ }}
200
+ >
201
+ <Text style={{ color: '#fff', fontSize: 32, fontWeight: '700' }}>3D Card</Text>
202
+ </Animated.View>
203
+ );
204
+ };
205
+ ```
206
+ - True 3D models require `react-three-fiber`.
207
+ - For UI perspective transforms, use the `transform` array: `[{ perspective: 1000 }, { rotateX: '...' }, { rotateY: '...' }]`.
208
+ - `perspective` MUST be the first item in the transform array for the effect to render correctly.
209
+
210
+ ### Jetpack Compose
211
+ ```kotlin
212
+ @Composable
213
+ fun Card3D() {
214
+ var offset by remember { mutableStateOf(Offset.Zero) }
215
+ val animatedOffset by animateOffsetAsState(
216
+ targetValue = offset,
217
+ animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy)
218
+ )
219
+
220
+ Box(
221
+ modifier = Modifier
222
+ .size(300.dp, 400.dp)
223
+ .pointerInput(Unit) {
224
+ detectDragGestures(
225
+ onDrag = { change, dragAmount ->
226
+ change.consume()
227
+ offset += dragAmount
228
+ },
229
+ onDragEnd = { offset = Offset.Zero },
230
+ onDragCancel = { offset = Offset.Zero }
231
+ )
232
+ }
233
+ .graphicsLayer {
234
+ // Apply 3D rotation based on drag offset
235
+ rotationX = -animatedOffset.y * 0.1f
236
+ rotationY = animatedOffset.x * 0.1f
237
+ cameraDistance = 8f * density // Sets the perspective
238
+ }
239
+ .shadow(20.dp, RoundedCornerShape(24.dp))
240
+ .clip(RoundedCornerShape(24.dp))
241
+ .background(Brush.linearGradient(listOf(Color.Blue, Color.Magenta)))
242
+ ) {
243
+ Text("3D Card",
244
+ color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold,
245
+ modifier = Modifier.align(Alignment.Center))
246
+ }
247
+ }
248
+ ```
249
+ - Apply 3D transformations inside `Modifier.graphicsLayer { }`.
250
+ - Set `rotationX` and `rotationY` for the tilt.
251
+ - **Critical**: Set `cameraDistance` to establish the Z-axis perspective vanishing point. Usually `8f * density` is a good starting point.
252
+
253
+ ## Do's and Don'ts
254
+ - **DO**: Tie 3D rotation to user input (mouse move on web, device tilt on mobile) for maximum impact.
255
+ - **DON'T**: Make text itself 3D unless it's a massive headline. 3D text is generally unreadable at small sizes.
256
+
257
+ ## Limitations
258
+ - This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
259
+ - Ensure appropriate contrast ratios and responsive behaviors are verified separately.