@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,556 @@
1
+ # Expo Router Testing
2
+
3
+ This reference covers testing patterns for applications using Expo Router.
4
+
5
+ ## Setup
6
+
7
+ ### Required Imports
8
+
9
+ ```typescript
10
+ import { renderRouter, screen } from "expo-router/testing-library";
11
+ import userEvent from "@testing-library/user-event";
12
+ ```
13
+
14
+ ### Why renderRouter Over render
15
+
16
+ When testing components that use Expo Router features (navigation, params, pathname), use `renderRouter` instead of `render`:
17
+
18
+ ```typescript
19
+ // Standard render - for components without routing
20
+ import { render } from "@testing-library/react-native";
21
+ render(<PureComponent />);
22
+
23
+ // renderRouter - for components using expo-router
24
+ import { renderRouter } from "expo-router/testing-library";
25
+ renderRouter({
26
+ index: () => <HomeScreen />,
27
+ });
28
+ ```
29
+
30
+ ## Basic Usage
31
+
32
+ ### Single Route Testing
33
+
34
+ ```typescript
35
+ test("renders home screen", async () => {
36
+ renderRouter({
37
+ index: () => <HomeScreen />,
38
+ });
39
+
40
+ expect(screen.getByRole("heading", { name: "Welcome" })).toBeOnTheScreen();
41
+ });
42
+ ```
43
+
44
+ ### Multiple Routes
45
+
46
+ ```typescript
47
+ test("navigates between screens", async () => {
48
+ const user = userEvent.setup();
49
+
50
+ renderRouter({
51
+ index: () => <HomeScreen />,
52
+ profile: () => <ProfileScreen />,
53
+ settings: () => <SettingsScreen />,
54
+ });
55
+
56
+ // Start on home
57
+ expect(screen.getByText("Home")).toBeOnTheScreen();
58
+
59
+ // Navigate to profile
60
+ await user.press(screen.getByRole("button", { name: "Go to Profile" }));
61
+ expect(await screen.findByText("Profile")).toBeOnTheScreen();
62
+ });
63
+ ```
64
+
65
+ ### Dynamic Routes
66
+
67
+ ```typescript
68
+ test("displays player details", async () => {
69
+ renderRouter(
70
+ {
71
+ index: () => <PlayerList />,
72
+ "players/[id]": () => <PlayerDetail />,
73
+ },
74
+ {
75
+ initialUrl: "/players/123",
76
+ }
77
+ );
78
+
79
+ expect(await screen.findByText("Player 123")).toBeOnTheScreen();
80
+ });
81
+ ```
82
+
83
+ ## Initial URL
84
+
85
+ ### Setting Initial Route
86
+
87
+ ```typescript
88
+ renderRouter(
89
+ {
90
+ index: () => <Home />,
91
+ profile: () => <Profile />,
92
+ "settings/account": () => <AccountSettings />,
93
+ },
94
+ {
95
+ initialUrl: "/settings/account",
96
+ }
97
+ );
98
+ ```
99
+
100
+ ### With Query Parameters
101
+
102
+ ```typescript
103
+ renderRouter(
104
+ {
105
+ "search/[query]": () => <SearchResults />,
106
+ },
107
+ {
108
+ initialUrl: "/search/players?filter=active&sort=name",
109
+ }
110
+ );
111
+ ```
112
+
113
+ ## Route Mocking
114
+
115
+ ### Inline Mock Components
116
+
117
+ ```typescript
118
+ renderRouter({
119
+ index: jest.fn(() => <Text>Home</Text>),
120
+ about: jest.fn(() => <Text>About</Text>),
121
+ });
122
+ ```
123
+
124
+ ### Null Components (Placeholder Routes)
125
+
126
+ Use null for routes that don't need rendering in this test:
127
+
128
+ ```typescript
129
+ renderRouter({
130
+ index: () => <HomeScreen />,
131
+ profile: null, // Route exists but won't render anything
132
+ settings: null,
133
+ });
134
+ ```
135
+
136
+ ### String Array Shorthand
137
+
138
+ Create mock routes quickly:
139
+
140
+ ```typescript
141
+ // Creates null components for each route
142
+ renderRouter(["index", "profile", "settings", "help"]);
143
+ ```
144
+
145
+ ## Navigation Testing
146
+
147
+ ### Testing Navigation Actions
148
+
149
+ ```typescript
150
+ test("navigates on button press", async () => {
151
+ const user = userEvent.setup();
152
+
153
+ renderRouter({
154
+ index: () => (
155
+ <Pressable onPress={() => router.push("/details")}>
156
+ <Text>View Details</Text>
157
+ </Pressable>
158
+ ),
159
+ details: () => <Text>Details Screen</Text>,
160
+ });
161
+
162
+ await user.press(screen.getByText("View Details"));
163
+ expect(await screen.findByText("Details Screen")).toBeOnTheScreen();
164
+ });
165
+ ```
166
+
167
+ ### Testing Back Navigation
168
+
169
+ ```typescript
170
+ test("goes back to previous screen", async () => {
171
+ const user = userEvent.setup();
172
+
173
+ renderRouter(
174
+ {
175
+ index: () => <Text>Home</Text>,
176
+ details: () => (
177
+ <Pressable onPress={() => router.back()}>
178
+ <Text>Go Back</Text>
179
+ </Pressable>
180
+ ),
181
+ },
182
+ {
183
+ initialUrl: "/details",
184
+ }
185
+ );
186
+
187
+ await user.press(screen.getByText("Go Back"));
188
+ expect(await screen.findByText("Home")).toBeOnTheScreen();
189
+ });
190
+ ```
191
+
192
+ ### Testing Replace Navigation
193
+
194
+ ```typescript
195
+ test("replaces current route", async () => {
196
+ const user = userEvent.setup();
197
+
198
+ renderRouter(
199
+ {
200
+ login: () => (
201
+ <Pressable onPress={() => router.replace("/dashboard")}>
202
+ <Text>Login</Text>
203
+ </Pressable>
204
+ ),
205
+ dashboard: () => <Text>Dashboard</Text>,
206
+ },
207
+ {
208
+ initialUrl: "/login",
209
+ }
210
+ );
211
+
212
+ await user.press(screen.getByText("Login"));
213
+ expect(await screen.findByText("Dashboard")).toBeOnTheScreen();
214
+ });
215
+ ```
216
+
217
+ ## Testing Route Params
218
+
219
+ ### useLocalSearchParams
220
+
221
+ ```typescript
222
+ // Component using params
223
+ const PlayerDetail = () => {
224
+ const { id } = useLocalSearchParams<{ id: string }>();
225
+ return <Text>Player ID: {id}</Text>;
226
+ };
227
+
228
+ test("displays player from params", async () => {
229
+ renderRouter(
230
+ {
231
+ "players/[id]": () => <PlayerDetail />,
232
+ },
233
+ {
234
+ initialUrl: "/players/456",
235
+ }
236
+ );
237
+
238
+ expect(screen.getByText("Player ID: 456")).toBeOnTheScreen();
239
+ });
240
+ ```
241
+
242
+ ### useGlobalSearchParams
243
+
244
+ ```typescript
245
+ const SearchWithFilters = () => {
246
+ const { query, filter } = useGlobalSearchParams<{
247
+ query: string;
248
+ filter: string;
249
+ }>();
250
+ return <Text>{`Search: ${query}, Filter: ${filter}`}</Text>;
251
+ };
252
+
253
+ test("reads global search params", async () => {
254
+ renderRouter(
255
+ {
256
+ "search/[query]": () => <SearchWithFilters />,
257
+ },
258
+ {
259
+ initialUrl: "/search/players?filter=active",
260
+ }
261
+ );
262
+
263
+ expect(screen.getByText("Search: players, Filter: active")).toBeOnTheScreen();
264
+ });
265
+ ```
266
+
267
+ ## Testing Pathname
268
+
269
+ ### usePathname
270
+
271
+ ```typescript
272
+ const BreadCrumb = () => {
273
+ const pathname = usePathname();
274
+ return <Text>Current: {pathname}</Text>;
275
+ };
276
+
277
+ test("displays current pathname", async () => {
278
+ renderRouter(
279
+ {
280
+ "settings/account": () => <BreadCrumb />,
281
+ },
282
+ {
283
+ initialUrl: "/settings/account",
284
+ }
285
+ );
286
+
287
+ expect(screen.getByText("Current: /settings/account")).toBeOnTheScreen();
288
+ });
289
+ ```
290
+
291
+ ### Asserting Pathname in Tests
292
+
293
+ ```typescript
294
+ test("navigates to correct path", async () => {
295
+ const user = userEvent.setup();
296
+
297
+ renderRouter({
298
+ index: () => <HomeWithNavigation />,
299
+ "players/[id]": () => <PlayerDetail />,
300
+ });
301
+
302
+ await user.press(screen.getByRole("button", { name: "View Player 123" }));
303
+
304
+ // Assert the pathname
305
+ expect(screen).toHavePathname("/players/123");
306
+ });
307
+ ```
308
+
309
+ ## Testing Segments
310
+
311
+ ### useSegments
312
+
313
+ ```typescript
314
+ const SegmentDisplay = () => {
315
+ const segments = useSegments();
316
+ return <Text>Segments: {segments.join("/")}</Text>;
317
+ };
318
+
319
+ test("displays route segments", async () => {
320
+ renderRouter(
321
+ {
322
+ "settings/account/security": () => <SegmentDisplay />,
323
+ },
324
+ {
325
+ initialUrl: "/settings/account/security",
326
+ }
327
+ );
328
+
329
+ expect(screen.getByText("Segments: settings/account/security")).toBeOnTheScreen();
330
+ });
331
+ ```
332
+
333
+ ## Layout Testing
334
+
335
+ ### Testing with Layout Components
336
+
337
+ ```typescript
338
+ const RootLayout = () => (
339
+ <View>
340
+ <Header />
341
+ <Slot />
342
+ <Footer />
343
+ </View>
344
+ );
345
+
346
+ test("layout wraps content", async () => {
347
+ renderRouter({
348
+ _layout: () => <RootLayout />,
349
+ index: () => <Text>Home Content</Text>,
350
+ });
351
+
352
+ expect(screen.getByText("Header")).toBeOnTheScreen();
353
+ expect(screen.getByText("Home Content")).toBeOnTheScreen();
354
+ expect(screen.getByText("Footer")).toBeOnTheScreen();
355
+ });
356
+ ```
357
+
358
+ ### Tab Navigation Layout
359
+
360
+ ```typescript
361
+ test("tab navigation works", async () => {
362
+ const user = userEvent.setup();
363
+
364
+ renderRouter({
365
+ "(tabs)/_layout": () => <TabsLayout />,
366
+ "(tabs)/home": () => <Text>Home Tab</Text>,
367
+ "(tabs)/search": () => <Text>Search Tab</Text>,
368
+ "(tabs)/profile": () => <Text>Profile Tab</Text>,
369
+ });
370
+
371
+ // Switch tabs
372
+ await user.press(screen.getByRole("tab", { name: "Search" }));
373
+ expect(await screen.findByText("Search Tab")).toBeOnTheScreen();
374
+ });
375
+ ```
376
+
377
+ ## Protected Routes Testing
378
+
379
+ ### Authentication Flow
380
+
381
+ ```typescript
382
+ const AuthenticatedRoute = () => {
383
+ const { user } = useAuth();
384
+
385
+ if (!user) {
386
+ return <Redirect href="/login" />;
387
+ }
388
+
389
+ return <Text>Protected Content</Text>;
390
+ };
391
+
392
+ test("redirects unauthenticated users", async () => {
393
+ mockUseAuth.mockReturnValue({ user: null });
394
+
395
+ renderRouter(
396
+ {
397
+ dashboard: () => <AuthenticatedRoute />,
398
+ login: () => <Text>Login Page</Text>,
399
+ },
400
+ {
401
+ initialUrl: "/dashboard",
402
+ }
403
+ );
404
+
405
+ expect(await screen.findByText("Login Page")).toBeOnTheScreen();
406
+ });
407
+
408
+ test("shows content for authenticated users", async () => {
409
+ mockUseAuth.mockReturnValue({ user: { id: "1" } });
410
+
411
+ renderRouter(
412
+ {
413
+ dashboard: () => <AuthenticatedRoute />,
414
+ },
415
+ {
416
+ initialUrl: "/dashboard",
417
+ }
418
+ );
419
+
420
+ expect(screen.getByText("Protected Content")).toBeOnTheScreen();
421
+ });
422
+ ```
423
+
424
+ ## File Location Rules
425
+
426
+ ### Never Put Tests in app/ Directory
427
+
428
+ Expo Router treats all files in `app/` as routes. Test files must be outside:
429
+
430
+ ```
431
+ ✅ Correct structure:
432
+ __tests__/
433
+ features/
434
+ home/
435
+ HomeScreen.test.tsx
436
+ components/
437
+ Button.test.tsx
438
+ features/
439
+ home/
440
+ components/
441
+ HomeScreen.tsx
442
+
443
+ ❌ Wrong structure:
444
+ app/
445
+ __tests__/ # Tests will be treated as routes!
446
+ home.test.tsx
447
+ ```
448
+
449
+ ### Recommended Test Location Patterns
450
+
451
+ ```
452
+ # Option 1: Root __tests__ directory
453
+ __tests__/
454
+ features/
455
+ players/
456
+ PlayerList.test.tsx
457
+ PlayerDetail.test.tsx
458
+
459
+ # Option 2: Feature-level __tests__
460
+ features/
461
+ players/
462
+ __tests__/
463
+ PlayerList.test.tsx
464
+ PlayerDetail.test.tsx
465
+ components/
466
+ PlayerList.tsx
467
+ PlayerDetail.tsx
468
+ ```
469
+
470
+ ## Common Issues
471
+
472
+ ### Route Not Found
473
+
474
+ ```typescript
475
+ // Error: Route not found
476
+ renderRouter({
477
+ index: () => <Home />,
478
+ });
479
+ // Then navigating to /profile that doesn't exist
480
+
481
+ // Solution: Define all routes needed for the test
482
+ renderRouter({
483
+ index: () => <Home />,
484
+ profile: () => <Profile />, // Add missing route
485
+ });
486
+ ```
487
+
488
+ ### Async Navigation
489
+
490
+ ```typescript
491
+ // Issue: Assertion runs before navigation completes
492
+ await user.press(navigationButton);
493
+ expect(screen.getByText("New Screen")).toBeOnTheScreen(); // May fail
494
+
495
+ // Solution: Use findBy for async assertions
496
+ await user.press(navigationButton);
497
+ expect(await screen.findByText("New Screen")).toBeOnTheScreen();
498
+ ```
499
+
500
+ ### useRouter Outside Router Context
501
+
502
+ ```typescript
503
+ // Error: useRouter must be used within a Router
504
+ render(<ComponentUsingRouter />);
505
+
506
+ // Solution: Use renderRouter
507
+ renderRouter({
508
+ index: () => <ComponentUsingRouter />,
509
+ });
510
+ ```
511
+
512
+ ## Integration with Other Providers
513
+
514
+ ### Wrapping with Apollo and Other Providers
515
+
516
+ ```typescript
517
+ const Wrapper = ({ children }: { children: React.ReactNode }) => (
518
+ <MockedProvider mocks={graphqlMocks}>
519
+ <ThemeProvider>{children}</ThemeProvider>
520
+ </MockedProvider>
521
+ );
522
+
523
+ test("works with multiple providers", async () => {
524
+ renderRouter(
525
+ {
526
+ index: () => (
527
+ <Wrapper>
528
+ <HomeWithData />
529
+ </Wrapper>
530
+ ),
531
+ }
532
+ );
533
+
534
+ expect(await screen.findByText("Data loaded")).toBeOnTheScreen();
535
+ });
536
+ ```
537
+
538
+ ### Custom renderRouter Wrapper
539
+
540
+ ```typescript
541
+ import { renderRouter as baseRenderRouter } from "expo-router/testing-library";
542
+
543
+ const customRenderRouter = (
544
+ routes: Parameters<typeof baseRenderRouter>[0],
545
+ options?: Parameters<typeof baseRenderRouter>[1]
546
+ ) => {
547
+ return baseRenderRouter(routes, {
548
+ ...options,
549
+ wrapper: ({ children }) => (
550
+ <AllProviders>{children}</AllProviders>
551
+ ),
552
+ });
553
+ };
554
+
555
+ export { customRenderRouter as renderRouter };
556
+ ```