@codyswann/lisa 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +867 -0
  3. package/all/copy-overwrite/.claude/README.md +205 -0
  4. package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
  5. package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
  6. package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
  7. package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
  8. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
  9. package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
  10. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
  11. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
  12. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
  13. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
  14. package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
  15. package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
  16. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
  17. package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
  18. package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
  19. package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
  20. package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
  21. package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
  22. package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
  23. package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
  24. package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
  25. package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
  26. package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
  27. package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
  28. package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
  29. package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
  30. package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
  31. package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
  32. package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
  33. package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
  34. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
  35. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
  36. package/all/copy-overwrite/.claude/hooks/README.md +301 -0
  37. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
  38. package/all/copy-overwrite/.claude/settings.json +41 -0
  39. package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
  40. package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
  41. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
  42. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
  43. package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
  44. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
  45. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
  46. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  47. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
  48. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  49. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
  50. package/all/copy-overwrite/CLAUDE.md +77 -0
  51. package/all/copy-overwrite/HUMAN.md +17 -0
  52. package/all/copy-overwrite/specs/.keep +0 -0
  53. package/all/create-only/PROJECT_RULES.md +0 -0
  54. package/cdk/merge/package.json +20 -0
  55. package/dist/cli/index.d.ts +7 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +107 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/prompts.d.ts +45 -0
  60. package/dist/cli/prompts.d.ts.map +1 -0
  61. package/dist/cli/prompts.js +58 -0
  62. package/dist/cli/prompts.js.map +1 -0
  63. package/dist/core/config.d.ts +73 -0
  64. package/dist/core/config.d.ts.map +1 -0
  65. package/dist/core/config.js +36 -0
  66. package/dist/core/config.js.map +1 -0
  67. package/dist/core/index.d.ts +4 -0
  68. package/dist/core/index.d.ts.map +1 -0
  69. package/dist/core/index.js +4 -0
  70. package/dist/core/index.js.map +1 -0
  71. package/dist/core/lisa.d.ts +81 -0
  72. package/dist/core/lisa.d.ts.map +1 -0
  73. package/dist/core/lisa.js +459 -0
  74. package/dist/core/lisa.js.map +1 -0
  75. package/dist/core/manifest.d.ts +58 -0
  76. package/dist/core/manifest.d.ts.map +1 -0
  77. package/dist/core/manifest.js +104 -0
  78. package/dist/core/manifest.js.map +1 -0
  79. package/dist/detection/detector.interface.d.ts +15 -0
  80. package/dist/detection/detector.interface.d.ts.map +1 -0
  81. package/dist/detection/detector.interface.js +2 -0
  82. package/dist/detection/detector.interface.js.map +1 -0
  83. package/dist/detection/detectors/cdk.d.ts +10 -0
  84. package/dist/detection/detectors/cdk.d.ts.map +1 -0
  85. package/dist/detection/detectors/cdk.js +34 -0
  86. package/dist/detection/detectors/cdk.js.map +1 -0
  87. package/dist/detection/detectors/expo.d.ts +10 -0
  88. package/dist/detection/detectors/expo.d.ts.map +1 -0
  89. package/dist/detection/detectors/expo.js +30 -0
  90. package/dist/detection/detectors/expo.js.map +1 -0
  91. package/dist/detection/detectors/nestjs.d.ts +10 -0
  92. package/dist/detection/detectors/nestjs.d.ts.map +1 -0
  93. package/dist/detection/detectors/nestjs.js +34 -0
  94. package/dist/detection/detectors/nestjs.js.map +1 -0
  95. package/dist/detection/detectors/npm-package.d.ts +13 -0
  96. package/dist/detection/detectors/npm-package.d.ts.map +1 -0
  97. package/dist/detection/detectors/npm-package.js +30 -0
  98. package/dist/detection/detectors/npm-package.js.map +1 -0
  99. package/dist/detection/detectors/typescript.d.ts +10 -0
  100. package/dist/detection/detectors/typescript.d.ts.map +1 -0
  101. package/dist/detection/detectors/typescript.js +25 -0
  102. package/dist/detection/detectors/typescript.js.map +1 -0
  103. package/dist/detection/index.d.ts +24 -0
  104. package/dist/detection/index.d.ts.map +1 -0
  105. package/dist/detection/index.js +57 -0
  106. package/dist/detection/index.js.map +1 -0
  107. package/dist/errors/index.d.ts +69 -0
  108. package/dist/errors/index.d.ts.map +1 -0
  109. package/dist/errors/index.js +110 -0
  110. package/dist/errors/index.js.map +1 -0
  111. package/dist/index.d.ts +3 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +8 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/logging/console-logger.d.ts +12 -0
  116. package/dist/logging/console-logger.d.ts.map +1 -0
  117. package/dist/logging/console-logger.js +22 -0
  118. package/dist/logging/console-logger.js.map +1 -0
  119. package/dist/logging/index.d.ts +4 -0
  120. package/dist/logging/index.d.ts.map +1 -0
  121. package/dist/logging/index.js +3 -0
  122. package/dist/logging/index.js.map +1 -0
  123. package/dist/logging/logger.interface.d.ts +20 -0
  124. package/dist/logging/logger.interface.d.ts.map +1 -0
  125. package/dist/logging/logger.interface.js +2 -0
  126. package/dist/logging/logger.interface.js.map +1 -0
  127. package/dist/logging/silent-logger.d.ts +12 -0
  128. package/dist/logging/silent-logger.d.ts.map +1 -0
  129. package/dist/logging/silent-logger.js +21 -0
  130. package/dist/logging/silent-logger.js.map +1 -0
  131. package/dist/strategies/copy-contents.d.ts +14 -0
  132. package/dist/strategies/copy-contents.d.ts.map +1 -0
  133. package/dist/strategies/copy-contents.js +69 -0
  134. package/dist/strategies/copy-contents.js.map +1 -0
  135. package/dist/strategies/copy-overwrite.d.ts +14 -0
  136. package/dist/strategies/copy-overwrite.d.ts.map +1 -0
  137. package/dist/strategies/copy-overwrite.js +47 -0
  138. package/dist/strategies/copy-overwrite.js.map +1 -0
  139. package/dist/strategies/create-only.d.ts +13 -0
  140. package/dist/strategies/create-only.d.ts.map +1 -0
  141. package/dist/strategies/create-only.js +30 -0
  142. package/dist/strategies/create-only.js.map +1 -0
  143. package/dist/strategies/index.d.ts +31 -0
  144. package/dist/strategies/index.d.ts.map +1 -0
  145. package/dist/strategies/index.js +52 -0
  146. package/dist/strategies/index.js.map +1 -0
  147. package/dist/strategies/merge.d.ts +13 -0
  148. package/dist/strategies/merge.d.ts.map +1 -0
  149. package/dist/strategies/merge.js +60 -0
  150. package/dist/strategies/merge.js.map +1 -0
  151. package/dist/strategies/strategy.interface.d.ts +31 -0
  152. package/dist/strategies/strategy.interface.d.ts.map +1 -0
  153. package/dist/strategies/strategy.interface.js +2 -0
  154. package/dist/strategies/strategy.interface.js.map +1 -0
  155. package/dist/transaction/backup.d.ts +38 -0
  156. package/dist/transaction/backup.d.ts.map +1 -0
  157. package/dist/transaction/backup.js +97 -0
  158. package/dist/transaction/backup.js.map +1 -0
  159. package/dist/transaction/index.d.ts +4 -0
  160. package/dist/transaction/index.d.ts.map +1 -0
  161. package/dist/transaction/index.js +3 -0
  162. package/dist/transaction/index.js.map +1 -0
  163. package/dist/transaction/transaction.d.ts +34 -0
  164. package/dist/transaction/transaction.d.ts.map +1 -0
  165. package/dist/transaction/transaction.js +68 -0
  166. package/dist/transaction/transaction.js.map +1 -0
  167. package/dist/utils/file-operations.d.ts +29 -0
  168. package/dist/utils/file-operations.d.ts.map +1 -0
  169. package/dist/utils/file-operations.js +84 -0
  170. package/dist/utils/file-operations.js.map +1 -0
  171. package/dist/utils/index.d.ts +4 -0
  172. package/dist/utils/index.d.ts.map +1 -0
  173. package/dist/utils/index.js +4 -0
  174. package/dist/utils/index.js.map +1 -0
  175. package/dist/utils/json-utils.d.ts +22 -0
  176. package/dist/utils/json-utils.d.ts.map +1 -0
  177. package/dist/utils/json-utils.js +57 -0
  178. package/dist/utils/json-utils.js.map +1 -0
  179. package/dist/utils/path-utils.d.ts +21 -0
  180. package/dist/utils/path-utils.d.ts.map +1 -0
  181. package/dist/utils/path-utils.js +35 -0
  182. package/dist/utils/path-utils.js.map +1 -0
  183. package/eslint-plugin-code-organization/README.md +149 -0
  184. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
  185. package/eslint-plugin-code-organization/index.js +23 -0
  186. package/eslint-plugin-code-organization/package.json +10 -0
  187. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
  188. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
  189. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
  190. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
  191. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
  192. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
  193. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
  194. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
  195. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
  196. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
  197. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
  198. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
  199. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
  200. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
  201. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
  202. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
  203. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
  204. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
  205. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
  206. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
  207. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
  208. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
  209. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
  210. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
  211. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
  212. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
  213. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
  214. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
  215. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
  216. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
  217. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
  218. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
  219. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
  220. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
  221. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
  222. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
  223. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
  224. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
  225. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
  226. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
  227. package/expo/copy-overwrite/.easignore.extra +2 -0
  228. package/expo/copy-overwrite/.mcp.json +33 -0
  229. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
  230. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
  231. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
  232. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
  233. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
  234. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
  235. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
  236. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
  237. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
  238. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
  239. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
  240. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
  241. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
  242. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
  243. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
  244. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
  245. package/expo/copy-overwrite/eslint.config.mjs +560 -0
  246. package/expo/copy-overwrite/lighthouserc.js +194 -0
  247. package/expo/create-only/lighthouserc-config.json +28 -0
  248. package/expo/merge/package.json +132 -0
  249. package/lisa.sh +35 -0
  250. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
  251. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
  252. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
  253. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
  254. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
  255. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
  256. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
  257. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
  258. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
  259. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
  260. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
  261. package/nestjs/merge/package.json +75 -0
  262. package/package.json +124 -0
  263. package/typescript/copy-contents/.husky/commit-msg +91 -0
  264. package/typescript/copy-contents/.husky/pre-commit +96 -0
  265. package/typescript/copy-contents/.husky/pre-push +211 -0
  266. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
  267. package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
  268. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
  269. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
  270. package/typescript/copy-overwrite/.github/README.md +455 -0
  271. package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
  272. package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
  273. package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
  274. package/typescript/copy-overwrite/.github/k6/README.md +386 -0
  275. package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
  276. package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
  277. package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
  278. package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
  279. package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
  280. package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
  281. package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
  282. package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
  283. package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
  284. package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
  285. package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
  286. package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
  287. package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
  288. package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
  289. package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
  290. package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
  291. package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
  292. package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
  293. package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
  294. package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
  295. package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
  296. package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
  297. package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
  298. package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
  299. package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
  300. package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
  301. package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
  302. package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
  303. package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
  304. package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
  305. package/typescript/copy-overwrite/.gitleaksignore +28 -0
  306. package/typescript/copy-overwrite/.nvmrc +1 -0
  307. package/typescript/copy-overwrite/.prettierignore +23 -0
  308. package/typescript/copy-overwrite/.prettierrc.json +22 -0
  309. package/typescript/copy-overwrite/.versionrc +42 -0
  310. package/typescript/copy-overwrite/.yamllint +20 -0
  311. package/typescript/copy-overwrite/commitlint.config.js +11 -0
  312. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
  313. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
  314. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
  315. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
  316. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
  317. package/typescript/copy-overwrite/eslint.config.mjs +390 -0
  318. package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
  319. package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
  320. package/typescript/github-rulesets/base.json +106 -0
  321. package/typescript/merge/.claude/settings.json +28 -0
  322. package/typescript/merge/package.json +71 -0
@@ -0,0 +1,619 @@
1
+ # Common Cross-Platform Issues and Solutions
2
+
3
+ This reference documents common cross-platform compatibility issues in Expo apps and their solutions.
4
+
5
+ ## Table of Contents
6
+
7
+ - [API Compatibility Issues](#api-compatibility-issues)
8
+ - [Style and Layout Issues](#style-and-layout-issues)
9
+ - [Navigation Issues](#navigation-issues)
10
+ - [Gesture and Input Issues](#gesture-and-input-issues)
11
+ - [Media and File Issues](#media-and-file-issues)
12
+ - [Storage Issues](#storage-issues)
13
+ - [Debugging Platform Issues](#debugging-platform-issues)
14
+
15
+ ## API Compatibility Issues
16
+
17
+ ### MediaLibrary (Not Supported on Web)
18
+
19
+ **Issue:** `expo-media-library` has no web implementation.
20
+
21
+ ```tsx
22
+ // ❌ Crashes on web
23
+ import * as MediaLibrary from "expo-media-library";
24
+ await MediaLibrary.saveToLibraryAsync(uri);
25
+ ```
26
+
27
+ **Solution:**
28
+
29
+ ```tsx
30
+ import { Platform } from "react-native";
31
+ import * as MediaLibrary from "expo-media-library";
32
+
33
+ const saveImage = async (uri: string, filename: string) => {
34
+ if (Platform.OS === "web") {
35
+ // Download via browser
36
+ const link = document.createElement("a");
37
+ link.href = uri;
38
+ link.download = filename;
39
+ document.body.appendChild(link);
40
+ link.click();
41
+ document.body.removeChild(link);
42
+ } else {
43
+ await MediaLibrary.saveToLibraryAsync(uri);
44
+ }
45
+ };
46
+ ```
47
+
48
+ ### View Capture (Different Libraries per Platform)
49
+
50
+ **Issue:** `react-native-view-shot` doesn't work on web.
51
+
52
+ **Solution:**
53
+
54
+ ```tsx
55
+ import { Platform } from "react-native";
56
+ import { captureRef } from "react-native-view-shot";
57
+
58
+ const captureView = async (ref: React.RefObject<View>) => {
59
+ if (Platform.OS === "web") {
60
+ const domToImage = await import("dom-to-image");
61
+ return await domToImage.default.toJpeg(
62
+ ref.current as unknown as HTMLElement
63
+ );
64
+ }
65
+ return await captureRef(ref, { format: "jpg", quality: 0.9 });
66
+ };
67
+ ```
68
+
69
+ ### Haptics (No Web Support)
70
+
71
+ **Issue:** `expo-haptics` has no effect on web.
72
+
73
+ **Solution:**
74
+
75
+ ```tsx
76
+ import { Platform } from "react-native";
77
+ import * as Haptics from "expo-haptics";
78
+
79
+ const triggerFeedback = () => {
80
+ if (Platform.OS !== "web") {
81
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
82
+ }
83
+ // Optionally add visual feedback for web
84
+ };
85
+ ```
86
+
87
+ ### Share API (Limited Web Support)
88
+
89
+ **Issue:** `Share.share()` has limited web support.
90
+
91
+ **Solution:**
92
+
93
+ ```tsx
94
+ import { Platform, Share } from "react-native";
95
+
96
+ const shareContent = async (content: {
97
+ title: string;
98
+ message: string;
99
+ url?: string;
100
+ }) => {
101
+ if (Platform.OS === "web") {
102
+ if (navigator.share) {
103
+ await navigator.share({
104
+ title: content.title,
105
+ text: content.message,
106
+ url: content.url,
107
+ });
108
+ } else {
109
+ // Fallback: copy to clipboard
110
+ await navigator.clipboard.writeText(content.url ?? content.message);
111
+ alert("Link copied to clipboard!");
112
+ }
113
+ } else {
114
+ await Share.share(content);
115
+ }
116
+ };
117
+ ```
118
+
119
+ ### Linking (Behavior Differences)
120
+
121
+ **Issue:** `Linking.openURL()` works but behaves differently across platforms.
122
+
123
+ **Solution:**
124
+
125
+ ```tsx
126
+ import { Linking, Platform } from "react-native";
127
+
128
+ const openExternalURL = (url: string, options?: { newTab?: boolean }) => {
129
+ if (Platform.OS === "web" && options?.newTab) {
130
+ window.open(url, "_blank", "noopener,noreferrer");
131
+ } else {
132
+ Linking.openURL(url);
133
+ }
134
+ };
135
+ ```
136
+
137
+ ## Style and Layout Issues
138
+
139
+ ### Shadows
140
+
141
+ **Issue:** Shadow properties differ significantly between platforms.
142
+
143
+ ```tsx
144
+ // ❌ iOS shadows don't work on Android or web
145
+ const styles = StyleSheet.create({
146
+ card: {
147
+ shadowColor: "#000",
148
+ shadowOffset: { width: 0, height: 2 },
149
+ shadowOpacity: 0.25,
150
+ shadowRadius: 3.84,
151
+ },
152
+ });
153
+ ```
154
+
155
+ **Solution:**
156
+
157
+ ```tsx
158
+ import { Platform, StyleSheet } from "react-native";
159
+
160
+ const createShadow = (elevation: number, color = "#000", opacity = 0.25) =>
161
+ Platform.select({
162
+ ios: {
163
+ shadowColor: color,
164
+ shadowOffset: { width: 0, height: elevation / 2 },
165
+ shadowOpacity: opacity,
166
+ shadowRadius: elevation,
167
+ },
168
+ android: {
169
+ elevation,
170
+ },
171
+ web: {
172
+ boxShadow: `0 ${elevation / 2}px ${elevation}px rgba(0,0,0,${opacity})`,
173
+ },
174
+ });
175
+
176
+ const styles = StyleSheet.create({
177
+ card: {
178
+ ...createShadow(4),
179
+ },
180
+ });
181
+ ```
182
+
183
+ ### StatusBar Height
184
+
185
+ **Issue:** Status bar height varies and affects layout.
186
+
187
+ **Solution:**
188
+
189
+ ```tsx
190
+ import { Platform, StatusBar } from "react-native";
191
+ import Constants from "expo-constants";
192
+
193
+ const getStatusBarHeight = () => {
194
+ if (Platform.OS === "ios") {
195
+ return Constants.statusBarHeight;
196
+ }
197
+ if (Platform.OS === "android") {
198
+ return StatusBar.currentHeight ?? 0;
199
+ }
200
+ return 0; // Web has no status bar
201
+ };
202
+ ```
203
+
204
+ ### Safe Area
205
+
206
+ **Issue:** Safe areas differ across devices and platforms.
207
+
208
+ **Solution:**
209
+
210
+ ```tsx
211
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
212
+
213
+ const MyComponent = () => {
214
+ const insets = useSafeAreaInsets();
215
+
216
+ return (
217
+ <View
218
+ style={{
219
+ paddingTop: insets.top,
220
+ paddingBottom: insets.bottom,
221
+ paddingLeft: insets.left,
222
+ paddingRight: insets.right,
223
+ }}
224
+ >
225
+ {/* Content */}
226
+ </View>
227
+ );
228
+ };
229
+ ```
230
+
231
+ ### Keyboard Avoidance
232
+
233
+ **Issue:** Keyboard behavior differs between platforms.
234
+
235
+ **Solution:**
236
+
237
+ ```tsx
238
+ import { KeyboardAvoidingView, Platform } from "react-native";
239
+
240
+ const FormContainer = ({ children }: { children: React.ReactNode }) => (
241
+ <KeyboardAvoidingView
242
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
243
+ keyboardVerticalOffset={Platform.select({ ios: 64, android: 0 })}
244
+ style={{ flex: 1 }}
245
+ >
246
+ {children}
247
+ </KeyboardAvoidingView>
248
+ );
249
+ ```
250
+
251
+ ### Scrolling Behavior
252
+
253
+ **Issue:** Scroll bounce and indicators differ.
254
+
255
+ **Solution:**
256
+
257
+ ```tsx
258
+ import { Platform, ScrollView } from "react-native";
259
+
260
+ const CrossPlatformScrollView = ({
261
+ children,
262
+ }: {
263
+ children: React.ReactNode;
264
+ }) => (
265
+ <ScrollView
266
+ bounces={Platform.OS === "ios"}
267
+ overScrollMode={Platform.OS === "android" ? "never" : undefined}
268
+ showsVerticalScrollIndicator={Platform.OS !== "web"}
269
+ >
270
+ {children}
271
+ </ScrollView>
272
+ );
273
+ ```
274
+
275
+ ## Navigation Issues
276
+
277
+ ### Bottom Tabs on Web
278
+
279
+ **Issue:** Bottom tabs may not be ideal for web.
280
+
281
+ **Solution:**
282
+
283
+ ```tsx
284
+ // app/_layout.tsx
285
+ import { Platform } from "react-native";
286
+ import { Tabs, Slot, Link } from "expo-router";
287
+
288
+ export default function Layout() {
289
+ if (Platform.OS === "web") {
290
+ return (
291
+ <div
292
+ style={{ display: "flex", flexDirection: "column", height: "100vh" }}
293
+ >
294
+ <nav style={{ display: "flex", gap: 16, padding: 16 }}>
295
+ <Link href="/">Home</Link>
296
+ <Link href="/settings">Settings</Link>
297
+ </nav>
298
+ <main style={{ flex: 1 }}>
299
+ <Slot />
300
+ </main>
301
+ </div>
302
+ );
303
+ }
304
+
305
+ return (
306
+ <Tabs>
307
+ <Tabs.Screen name="index" options={{ title: "Home" }} />
308
+ <Tabs.Screen name="settings" options={{ title: "Settings" }} />
309
+ </Tabs>
310
+ );
311
+ }
312
+ ```
313
+
314
+ ### Drawer Navigation
315
+
316
+ **Issue:** Drawer gestures conflict with browser navigation on web.
317
+
318
+ **Solution:**
319
+
320
+ ```tsx
321
+ import { Platform } from "react-native";
322
+ import { Drawer } from "expo-router/drawer";
323
+
324
+ export default function DrawerLayout() {
325
+ return (
326
+ <Drawer
327
+ screenOptions={{
328
+ swipeEnabled: Platform.OS !== "web",
329
+ drawerType: Platform.OS === "web" ? "permanent" : "front",
330
+ }}
331
+ />
332
+ );
333
+ }
334
+ ```
335
+
336
+ ### Back Button Behavior
337
+
338
+ **Issue:** Hardware back button (Android) vs browser back vs iOS gesture.
339
+
340
+ **Solution:**
341
+
342
+ ```tsx
343
+ import { Platform } from "react-native";
344
+ import { useNavigation } from "expo-router";
345
+ import { useEffect } from "react";
346
+
347
+ const useBackHandler = (onBack: () => boolean) => {
348
+ const navigation = useNavigation();
349
+
350
+ useEffect(() => {
351
+ if (Platform.OS === "android") {
352
+ const backHandler = navigation.addListener("beforeRemove", e => {
353
+ if (onBack()) {
354
+ e.preventDefault();
355
+ }
356
+ });
357
+ return () => backHandler();
358
+ }
359
+ // Web uses browser back button naturally
360
+ }, [navigation, onBack]);
361
+ };
362
+ ```
363
+
364
+ ## Gesture and Input Issues
365
+
366
+ ### Touch vs Mouse
367
+
368
+ **Issue:** Touch events work differently from mouse events.
369
+
370
+ **Solution:**
371
+
372
+ ```tsx
373
+ import { Platform, Pressable } from "react-native";
374
+
375
+ const InteractiveCard = ({ onPress, children }: Props) => (
376
+ <Pressable
377
+ onPress={onPress}
378
+ style={({ pressed, hovered }) => [
379
+ styles.card,
380
+ Platform.OS === "web" && hovered && styles.cardHovered,
381
+ pressed && styles.cardPressed,
382
+ ]}
383
+ >
384
+ {children}
385
+ </Pressable>
386
+ );
387
+ ```
388
+
389
+ ### Long Press
390
+
391
+ **Issue:** Long press conflicts with context menu on web.
392
+
393
+ **Solution:**
394
+
395
+ ```tsx
396
+ import { Platform, Pressable } from "react-native";
397
+
398
+ const LongPressable = ({ onLongPress, children }: Props) => (
399
+ <Pressable
400
+ onLongPress={Platform.OS !== "web" ? onLongPress : undefined}
401
+ onContextMenu={
402
+ Platform.OS === "web"
403
+ ? e => {
404
+ e.preventDefault();
405
+ onLongPress?.();
406
+ }
407
+ : undefined
408
+ }
409
+ delayLongPress={Platform.select({ ios: 500, android: 400, web: 500 })}
410
+ >
411
+ {children}
412
+ </Pressable>
413
+ );
414
+ ```
415
+
416
+ ### Text Selection
417
+
418
+ **Issue:** Text selection behavior differs.
419
+
420
+ **Solution:**
421
+
422
+ ```tsx
423
+ import { Platform, Text } from "react-native";
424
+
425
+ const SelectableText = ({ children }: { children: string }) => (
426
+ <Text
427
+ selectable={Platform.OS !== "web"} // Web handles selection natively
428
+ style={Platform.OS === "web" ? { userSelect: "text" } : undefined}
429
+ >
430
+ {children}
431
+ </Text>
432
+ );
433
+ ```
434
+
435
+ ## Media and File Issues
436
+
437
+ ### Image Formats
438
+
439
+ **Issue:** Some image formats not supported on all platforms.
440
+
441
+ **Solution:**
442
+
443
+ ```tsx
444
+ const getOptimalImageFormat = () =>
445
+ Platform.select({
446
+ ios: "heic", // Efficient on iOS
447
+ android: "webp", // Good on Android
448
+ web: "webp", // Modern browsers support webp
449
+ default: "jpg",
450
+ });
451
+ ```
452
+
453
+ ### Video Playback
454
+
455
+ **Issue:** Video components have different APIs.
456
+
457
+ **Solution:**
458
+
459
+ ```tsx
460
+ import { Platform } from "react-native";
461
+ import { Video } from "expo-av";
462
+
463
+ const VideoPlayer = ({ uri }: { uri: string }) => {
464
+ if (Platform.OS === "web") {
465
+ return (
466
+ <video src={uri} controls style={{ width: "100%", maxHeight: 400 }} />
467
+ );
468
+ }
469
+
470
+ return (
471
+ <Video
472
+ source={{ uri }}
473
+ useNativeControls
474
+ style={{ width: "100%", height: 300 }}
475
+ />
476
+ );
477
+ };
478
+ ```
479
+
480
+ ### File Picking
481
+
482
+ **Issue:** File system access differs significantly.
483
+
484
+ **Solution:**
485
+
486
+ ```tsx
487
+ import { Platform } from "react-native";
488
+ import * as DocumentPicker from "expo-document-picker";
489
+
490
+ const pickFile = async () => {
491
+ if (Platform.OS === "web") {
492
+ return new Promise<File | null>(resolve => {
493
+ const input = document.createElement("input");
494
+ input.type = "file";
495
+ input.onchange = () => resolve(input.files?.[0] ?? null);
496
+ input.click();
497
+ });
498
+ }
499
+
500
+ const result = await DocumentPicker.getDocumentAsync();
501
+ return result.canceled ? null : result.assets[0];
502
+ };
503
+ ```
504
+
505
+ ## Storage Issues
506
+
507
+ ### AsyncStorage vs localStorage
508
+
509
+ **Issue:** Different storage mechanisms per platform.
510
+
511
+ **Solution:**
512
+
513
+ ```tsx
514
+ // utils/storage.ts
515
+ import AsyncStorage from "@react-native-async-storage/async-storage";
516
+ import { Platform } from "react-native";
517
+
518
+ export const storage = {
519
+ get: async (key: string): Promise<string | null> => {
520
+ if (Platform.OS === "web") {
521
+ return localStorage.getItem(key);
522
+ }
523
+ return await AsyncStorage.getItem(key);
524
+ },
525
+
526
+ set: async (key: string, value: string): Promise<void> => {
527
+ if (Platform.OS === "web") {
528
+ localStorage.setItem(key, value);
529
+ } else {
530
+ await AsyncStorage.setItem(key, value);
531
+ }
532
+ },
533
+
534
+ remove: async (key: string): Promise<void> => {
535
+ if (Platform.OS === "web") {
536
+ localStorage.removeItem(key);
537
+ } else {
538
+ await AsyncStorage.removeItem(key);
539
+ }
540
+ },
541
+ };
542
+ ```
543
+
544
+ ### SecureStore (No Web Support)
545
+
546
+ **Issue:** `expo-secure-store` doesn't work on web.
547
+
548
+ **Solution:**
549
+
550
+ ```tsx
551
+ import { Platform } from "react-native";
552
+ import * as SecureStore from "expo-secure-store";
553
+
554
+ export const secureStorage = {
555
+ get: async (key: string): Promise<string | null> => {
556
+ if (Platform.OS === "web") {
557
+ // Web fallback - consider using a more secure solution
558
+ return sessionStorage.getItem(key);
559
+ }
560
+ return await SecureStore.getItemAsync(key);
561
+ },
562
+
563
+ set: async (key: string, value: string): Promise<void> => {
564
+ if (Platform.OS === "web") {
565
+ sessionStorage.setItem(key, value);
566
+ } else {
567
+ await SecureStore.setItemAsync(key, value);
568
+ }
569
+ },
570
+ };
571
+ ```
572
+
573
+ ## Debugging Platform Issues
574
+
575
+ ### Console Logging Platform
576
+
577
+ ```tsx
578
+ console.log(`Running on: ${Platform.OS}`);
579
+ console.log(`Version: ${Platform.Version}`);
580
+ if (Platform.OS === "ios") {
581
+ console.log(`iPad: ${Platform.isPad}`);
582
+ }
583
+ ```
584
+
585
+ ### Platform-Specific Debug Tools
586
+
587
+ ```tsx
588
+ const enableDebugTools = () => {
589
+ if (__DEV__) {
590
+ if (Platform.OS === "web") {
591
+ // Web DevTools are built-in
592
+ console.log("Use browser DevTools (F12)");
593
+ } else {
594
+ // React Native Debugger or Flipper
595
+ console.log("Shake device or Cmd+D for dev menu");
596
+ }
597
+ }
598
+ };
599
+ ```
600
+
601
+ ### Testing Platform-Specific Code
602
+
603
+ ```tsx
604
+ // __tests__/platform.test.ts
605
+ import { Platform } from "react-native";
606
+
607
+ jest.mock("react-native", () => ({
608
+ Platform: {
609
+ OS: "ios", // Mock specific platform
610
+ select: jest.fn(obj => obj.ios ?? obj.default),
611
+ },
612
+ }));
613
+
614
+ describe("iOS-specific behavior", () => {
615
+ it("should use iOS implementation", () => {
616
+ expect(Platform.OS).toBe("ios");
617
+ });
618
+ });
619
+ ```