@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,446 @@
1
+ # Reactive Variables Reference
2
+
3
+ ## Overview
4
+
5
+ Reactive variables are Apollo Client 3's mechanism for managing local state outside the GraphQL cache. They enable seamless reactivity without requiring GraphQL syntax and can store any data type.
6
+
7
+ ## Creating Reactive Variables
8
+
9
+ ### Basic Types
10
+
11
+ ```typescript
12
+ import { makeVar } from "@apollo/client";
13
+
14
+ // Boolean
15
+ export const isLoadingVar = makeVar<boolean>(false);
16
+
17
+ // String
18
+ export const selectedIdVar = makeVar<string | null>(null);
19
+
20
+ // Number
21
+ export const countVar = makeVar<number>(0);
22
+ ```
23
+
24
+ ### Complex Types
25
+
26
+ ```typescript
27
+ // Interface-based object
28
+ interface IFilterValues {
29
+ readonly minAge: number;
30
+ readonly maxAge: number;
31
+ readonly positions: readonly string[];
32
+ }
33
+
34
+ const DEFAULT_FILTERS: IFilterValues = {
35
+ minAge: 18,
36
+ maxAge: 40,
37
+ positions: [],
38
+ };
39
+
40
+ export const filterValuesVar = makeVar<IFilterValues>(DEFAULT_FILTERS);
41
+ ```
42
+
43
+ ### Record Types for Lookups
44
+
45
+ ```typescript
46
+ // Key-value lookup
47
+ export const selectedPlayersVar = makeVar<Record<string, boolean>>({});
48
+
49
+ // Complex value lookup
50
+ interface PlayerNote {
51
+ readonly playerId: string;
52
+ readonly note: string;
53
+ readonly updatedAt: string;
54
+ }
55
+
56
+ export const playerNotesVar = makeVar<Record<string, PlayerNote>>({});
57
+ ```
58
+
59
+ ### Array Types
60
+
61
+ ```typescript
62
+ interface Todo {
63
+ readonly id: string;
64
+ readonly text: string;
65
+ readonly completed: boolean;
66
+ }
67
+
68
+ type Todos = readonly Todo[];
69
+
70
+ export const todosVar = makeVar<Todos>([]);
71
+ ```
72
+
73
+ ## Reading Values
74
+
75
+ ### Direct Read (Non-Reactive)
76
+
77
+ Call without arguments to read current value. Does NOT trigger component re-renders:
78
+
79
+ ```typescript
80
+ const currentFilters = filterValuesVar();
81
+ const selectedPlayers = selectedPlayersVar();
82
+ ```
83
+
84
+ Use for:
85
+
86
+ - Event handlers
87
+ - Utility functions
88
+ - Async operations
89
+ - Conditional logic outside JSX
90
+
91
+ ### Reactive Read with Hook
92
+
93
+ Use `useReactiveVar` for components that should re-render on changes:
94
+
95
+ ```typescript
96
+ import { useReactiveVar } from "@apollo/client";
97
+
98
+ const FilterDisplay = () => {
99
+ const filters = useReactiveVar(filterValuesVar);
100
+
101
+ return (
102
+ <View>
103
+ <Text>Age: {filters.minAge} - {filters.maxAge}</Text>
104
+ <Text>Positions: {filters.positions.join(", ")}</Text>
105
+ </View>
106
+ );
107
+ };
108
+ ```
109
+
110
+ ## Updating Values
111
+
112
+ ### Object Updates
113
+
114
+ Always create new object references:
115
+
116
+ ```typescript
117
+ // Single field update
118
+ filterValuesVar({
119
+ ...filterValuesVar(),
120
+ minAge: 21,
121
+ });
122
+
123
+ // Multiple field update
124
+ filterValuesVar({
125
+ ...filterValuesVar(),
126
+ minAge: 21,
127
+ maxAge: 35,
128
+ });
129
+
130
+ // Nested object update
131
+ settingsVar({
132
+ ...settingsVar(),
133
+ display: {
134
+ ...settingsVar().display,
135
+ showGrid: true,
136
+ },
137
+ });
138
+ ```
139
+
140
+ ### Array Updates
141
+
142
+ ```typescript
143
+ // Add item
144
+ todosVar([
145
+ ...todosVar(),
146
+ { id: crypto.randomUUID(), text: "New todo", completed: false },
147
+ ]);
148
+
149
+ // Remove item
150
+ todosVar(todosVar().filter(todo => todo.id !== idToRemove));
151
+
152
+ // Update item
153
+ todosVar(
154
+ todosVar().map(todo =>
155
+ todo.id === idToUpdate ? { ...todo, completed: true } : todo
156
+ )
157
+ );
158
+
159
+ // Clear all
160
+ todosVar([]);
161
+ ```
162
+
163
+ ### Record Updates
164
+
165
+ ```typescript
166
+ // Add/update entry
167
+ selectedPlayersVar({
168
+ ...selectedPlayersVar(),
169
+ [playerId]: true,
170
+ });
171
+
172
+ // Remove entry (using destructuring)
173
+ const { [playerIdToRemove]: _, ...remaining } = selectedPlayersVar();
174
+ selectedPlayersVar(remaining);
175
+
176
+ // Toggle entry
177
+ const current = selectedPlayersVar();
178
+ selectedPlayersVar({
179
+ ...current,
180
+ [playerId]: !current[playerId],
181
+ });
182
+ ```
183
+
184
+ ## Custom Hooks Pattern
185
+
186
+ Encapsulate reactive variable logic in custom hooks for better testability:
187
+
188
+ ```typescript
189
+ import { makeVar, ReactiveVar, useReactiveVar } from "@apollo/client";
190
+ import { useCallback } from "react";
191
+
192
+ interface IFilterValues {
193
+ readonly minAge: number;
194
+ readonly maxAge: number;
195
+ readonly positions: readonly string[];
196
+ }
197
+
198
+ const DEFAULT_FILTERS: IFilterValues = {
199
+ minAge: 18,
200
+ maxAge: 40,
201
+ positions: [],
202
+ };
203
+
204
+ export const filterValuesVar = makeVar<IFilterValues>(DEFAULT_FILTERS);
205
+
206
+ /**
207
+ * Custom hook for filter operations
208
+ * Encapsulates all filter state logic
209
+ */
210
+ export const useFilters = () => {
211
+ const filters = useReactiveVar(filterValuesVar);
212
+
213
+ const setMinAge = useCallback((minAge: number) => {
214
+ filterValuesVar({ ...filterValuesVar(), minAge });
215
+ }, []);
216
+
217
+ const setMaxAge = useCallback((maxAge: number) => {
218
+ filterValuesVar({ ...filterValuesVar(), maxAge });
219
+ }, []);
220
+
221
+ const togglePosition = useCallback((position: string) => {
222
+ const current = filterValuesVar();
223
+ const hasPosition = current.positions.includes(position);
224
+ const positions = hasPosition
225
+ ? current.positions.filter(p => p !== position)
226
+ : [...current.positions, position];
227
+ filterValuesVar({ ...current, positions });
228
+ }, []);
229
+
230
+ const resetFilters = useCallback(() => {
231
+ filterValuesVar(DEFAULT_FILTERS);
232
+ }, []);
233
+
234
+ return {
235
+ filters,
236
+ setMinAge,
237
+ setMaxAge,
238
+ togglePosition,
239
+ resetFilters,
240
+ };
241
+ };
242
+ ```
243
+
244
+ ## Dependency Injection for Testing
245
+
246
+ Pass reactive variables as parameters for testable hooks:
247
+
248
+ ```typescript
249
+ /**
250
+ * Testable hook with dependency injection
251
+ * @param filtersVar - Reactive variable (can be mocked in tests)
252
+ */
253
+ export const useFiltersWithDI = (
254
+ filtersVar: ReactiveVar<IFilterValues> = filterValuesVar
255
+ ) => {
256
+ const filters = useReactiveVar(filtersVar);
257
+
258
+ const setMinAge = useCallback(
259
+ (minAge: number) => {
260
+ filtersVar({ ...filtersVar(), minAge });
261
+ },
262
+ [filtersVar]
263
+ );
264
+
265
+ return { filters, setMinAge };
266
+ };
267
+
268
+ // Test usage
269
+ describe("useFiltersWithDI", () => {
270
+ it("should update minAge", () => {
271
+ const testVar = makeVar<IFilterValues>(DEFAULT_FILTERS);
272
+ const { result } = renderHook(() => useFiltersWithDI(testVar));
273
+
274
+ act(() => {
275
+ result.current.setMinAge(25);
276
+ });
277
+
278
+ expect(testVar().minAge).toBe(25);
279
+ });
280
+ });
281
+ ```
282
+
283
+ ## Cache Type Policy Integration
284
+
285
+ Connect reactive variables to GraphQL queries using field policies:
286
+
287
+ ```typescript
288
+ import { InMemoryCache, makeVar } from "@apollo/client";
289
+ import { gql } from "@apollo/client";
290
+
291
+ // Reactive variable
292
+ export const filterValuesVar = makeVar<IFilterValues>(DEFAULT_FILTERS);
293
+
294
+ // Cache configuration
295
+ export const cache = new InMemoryCache({
296
+ typePolicies: {
297
+ Query: {
298
+ fields: {
299
+ filterValues: {
300
+ read() {
301
+ return filterValuesVar();
302
+ },
303
+ },
304
+ },
305
+ },
306
+ },
307
+ });
308
+
309
+ // Query local state with @client directive
310
+ export const GET_FILTER_VALUES = gql`
311
+ query GetFilterValues {
312
+ filterValues @client {
313
+ minAge
314
+ maxAge
315
+ positions
316
+ }
317
+ }
318
+ `;
319
+
320
+ // Use in component
321
+ const FilterComponent = () => {
322
+ const { data } = useQuery(GET_FILTER_VALUES);
323
+ // data.filterValues is reactive
324
+ };
325
+ ```
326
+
327
+ ## Performance Considerations
328
+
329
+ ### Split Large State
330
+
331
+ Instead of one large reactive variable, use multiple smaller ones:
332
+
333
+ ```typescript
334
+ // AVOID - single large state
335
+ const appStateVar = makeVar({
336
+ user: {
337
+ /* ... */
338
+ },
339
+ settings: {
340
+ /* ... */
341
+ },
342
+ filters: {
343
+ /* ... */
344
+ },
345
+ selectedItems: {
346
+ /* ... */
347
+ },
348
+ });
349
+
350
+ // PREFER - separate concerns
351
+ export const userVar = makeVar<User | null>(null);
352
+ export const settingsVar = makeVar<Settings>(DEFAULT_SETTINGS);
353
+ export const filtersVar = makeVar<Filters>(DEFAULT_FILTERS);
354
+ export const selectedItemsVar = makeVar<Record<string, boolean>>({});
355
+ ```
356
+
357
+ ### Batch Related Updates
358
+
359
+ Update multiple fields in a single call:
360
+
361
+ ```typescript
362
+ // CORRECT - single update
363
+ filterValuesVar({
364
+ ...filterValuesVar(),
365
+ minAge: 21,
366
+ maxAge: 35,
367
+ positions: ["QB", "WR"],
368
+ });
369
+
370
+ // AVOID - multiple sequential updates
371
+ filterValuesVar({ ...filterValuesVar(), minAge: 21 });
372
+ filterValuesVar({ ...filterValuesVar(), maxAge: 35 });
373
+ filterValuesVar({ ...filterValuesVar(), positions: ["QB", "WR"] });
374
+ ```
375
+
376
+ ### Selector Pattern for Complex State
377
+
378
+ Create selector wrappers to minimize re-renders:
379
+
380
+ ```typescript
381
+ // Store
382
+ export const allPlayersVar = makeVar<Record<string, Player>>({});
383
+
384
+ // Selector hook - only re-renders when specific player changes
385
+ export const usePlayer = (playerId: string): Player | undefined => {
386
+ const allPlayers = useReactiveVar(allPlayersVar);
387
+ return allPlayers[playerId];
388
+ };
389
+
390
+ // Component only re-renders when its specific player changes
391
+ const PlayerCard = ({ playerId }: { playerId: string }) => {
392
+ const player = usePlayer(playerId);
393
+ return player ? <Text>{player.name}</Text> : null;
394
+ };
395
+ ```
396
+
397
+ ## TypeScript Best Practices
398
+
399
+ ### Use Readonly Types
400
+
401
+ Enforce immutability at the type level:
402
+
403
+ ```typescript
404
+ interface IState {
405
+ readonly items: readonly Item[];
406
+ readonly metadata: Readonly<Metadata>;
407
+ }
408
+
409
+ export const stateVar = makeVar<IState>({
410
+ items: [],
411
+ metadata: { count: 0 },
412
+ });
413
+ ```
414
+
415
+ ### Use Generic Constraints
416
+
417
+ ```typescript
418
+ // Generic updater function
419
+ const updateVar = <T extends Record<string, unknown>>(
420
+ reactiveVar: ReactiveVar<T>,
421
+ updates: Partial<T>
422
+ ): void => {
423
+ reactiveVar({ ...reactiveVar(), ...updates });
424
+ };
425
+
426
+ // Usage
427
+ updateVar(settingsVar, { theme: "dark" });
428
+ ```
429
+
430
+ ### Export Types with Variables
431
+
432
+ ```typescript
433
+ // Export both type and variable
434
+ export interface IFilterValues {
435
+ readonly minAge: number;
436
+ readonly maxAge: number;
437
+ }
438
+
439
+ export const filterValuesVar = makeVar<IFilterValues>({
440
+ minAge: 18,
441
+ maxAge: 40,
442
+ });
443
+
444
+ // Re-export type for consumers
445
+ export type { IFilterValues };
446
+ ```
@@ -0,0 +1,223 @@
1
+ ---
2
+ name: playwright-selectors
3
+ description: Best practices for adding testID and aria-label selectors for Playwright E2E testing in Expo web applications. This skill should be used when adding E2E test coverage, creating new components that need test selectors, or reviewing code for testability.
4
+ ---
5
+
6
+ # Playwright Selectors Best Practices
7
+
8
+ ## Overview
9
+
10
+ This skill provides guidance for adding effective selectors (testID, aria-labels) to Expo/React Native components for Playwright E2E testing. Proper selector strategy ensures tests are reliable, maintainable, and accessible.
11
+
12
+ ## Selector Priority
13
+
14
+ Choose selectors based on their reliability and accessibility impact, in this priority order:
15
+
16
+ | Priority | Selector Method | When to Use |
17
+ | -------- | --------------- | ----------------------------------------- |
18
+ | 1 | `getByRole` | Interactive elements with semantic roles |
19
+ | 2 | `getByText` | Visible text content |
20
+ | 3 | `getByLabel` | Form elements with labels |
21
+ | 4 | `getByTestId` | Fallback for elements without semantics |
22
+
23
+ ### getByRole (Preferred)
24
+
25
+ Use semantic roles when possible - they improve both accessibility and test resilience.
26
+
27
+ ```typescript
28
+ // E2E test - preferred selector
29
+ const submitButton = page.getByRole("button", { name: "Submit" });
30
+ await expect(submitButton).toBeVisible();
31
+ ```
32
+
33
+ ### getByTestId (Fallback)
34
+
35
+ Use testID when semantic selectors are not available, particularly for structural containers.
36
+
37
+ ```typescript
38
+ // E2E test - fallback selector
39
+ const container = page.getByTestId("home:container");
40
+ await expect(container).toBeVisible();
41
+ ```
42
+
43
+ ## testID Naming Convention
44
+
45
+ Use a namespaced pattern with colons as separators: `screen:element`
46
+
47
+ ### Format
48
+
49
+ ```
50
+ {screen}:{element}
51
+ ```
52
+
53
+ - **screen**: lowercase screen/feature name (e.g., `home`, `profile`, `settings`)
54
+ - **element**: lowercase element identifier (e.g., `container`, `title`, `submit-button`)
55
+
56
+ ### Examples
57
+
58
+ | testID | Description |
59
+ | -------------------------- | -------------------------------- |
60
+ | `home:container` | Main container on home screen |
61
+ | `home:title` | Title text on home screen |
62
+ | `profile:avatar` | User avatar on profile screen |
63
+ | `settings:dark-mode-toggle`| Dark mode toggle in settings |
64
+ | `auth:login-button` | Login button on auth screen |
65
+
66
+ ### Rules
67
+
68
+ 1. Use lowercase only
69
+ 2. Use colons (`:`) to separate screen from element
70
+ 3. Use hyphens (`-`) for multi-word elements
71
+ 4. Be descriptive but concise
72
+ 5. Avoid redundant words (e.g., `home:home-title` should be `home:title`)
73
+
74
+ ## React Native to HTML Mapping
75
+
76
+ Understanding how testID propagates from React Native to the web is essential.
77
+
78
+ ### How It Works
79
+
80
+ 1. React Native's `testID` prop is for native testing (XCUITest, Espresso)
81
+ 2. On web (via react-native-web), `testID` renders as `data-testid` in HTML
82
+ 3. Playwright's `getByTestId()` queries `data-testid` by default
83
+
84
+ ```typescript
85
+ // React Native component
86
+ <Box testID="home:container">...</Box>
87
+
88
+ // Rendered HTML on web
89
+ <div data-testid="home:container">...</div>
90
+
91
+ // Playwright locator
92
+ page.getByTestId("home:container")
93
+ ```
94
+
95
+ ### Gluestack UI Components
96
+
97
+ Gluestack UI web components (Box, Text, etc.) require explicit testID handling because they use native HTML elements instead of react-native-web components. The web versions have been updated to:
98
+
99
+ 1. Accept a `testID` prop in the TypeScript type
100
+ 2. Map `testID` to `data-testid` on the rendered HTML element
101
+
102
+ ```typescript
103
+ // Gluestack Box web implementation
104
+ const Box = ({ testID, ...props }) => (
105
+ <div data-testid={testID} {...props} />
106
+ );
107
+ ```
108
+
109
+ ## When to Add testID
110
+
111
+ ### Add testID To
112
+
113
+ 1. **Interactive elements** that E2E tests will click/interact with
114
+ 2. **Key structural containers** for page load verification
115
+ 3. **Dynamic content areas** that change based on state
116
+ 4. **Form elements** that lack semantic labels
117
+
118
+ ### Do Not Add testID To
119
+
120
+ 1. Every element (over-testing creates maintenance burden)
121
+ 2. Elements with good semantic selectors (use getByRole instead)
122
+ 3. Decorative elements not needed for testing
123
+ 4. Elements inside third-party components (may not propagate)
124
+
125
+ ## Accessibility Best Practices
126
+
127
+ Prefer semantic selectors and aria-labels over testID when possible.
128
+
129
+ ### aria-label for Testing and Accessibility
130
+
131
+ When adding labels for testing, use `aria-label` or `accessibilityLabel` to benefit screen reader users too.
132
+
133
+ ```typescript
134
+ // Correct - benefits both testing and accessibility
135
+ <Pressable
136
+ accessibilityLabel="Close dialog"
137
+ onPress={handleClose}
138
+ >
139
+ <XIcon />
140
+ </Pressable>
141
+
142
+ // E2E test uses accessible name
143
+ await page.getByRole("button", { name: "Close dialog" }).click();
144
+ ```
145
+
146
+ ### accessibilityRole for Semantic Elements
147
+
148
+ Use `accessibilityRole` to provide semantic meaning on web.
149
+
150
+ ```typescript
151
+ // Correct - semantic role for assistive technology
152
+ <Box accessibilityRole="banner" testID="header:container">
153
+ <Text accessibilityRole="heading">Welcome</Text>
154
+ </Box>
155
+
156
+ // E2E test can use role
157
+ await expect(page.getByRole("banner")).toBeVisible();
158
+ await expect(page.getByRole("heading", { name: "Welcome" })).toBeVisible();
159
+ ```
160
+
161
+ ## Implementation Checklist
162
+
163
+ When adding E2E test coverage to a component:
164
+
165
+ - [ ] Identify elements that need selectors for testing
166
+ - [ ] Prefer semantic selectors (role, text, label) when available
167
+ - [ ] Use namespaced testID pattern for elements without semantics
168
+ - [ ] Verify testID propagates to `data-testid` on web (check Gluestack components)
169
+ - [ ] Add accessibility labels where beneficial
170
+ - [ ] Document testIDs in component JSDoc preamble
171
+
172
+ ## Example Component
173
+
174
+ ```typescript
175
+ /**
176
+ * Profile screen component.
177
+ *
178
+ * Test IDs for E2E testing:
179
+ * - `profile:container` - Main container
180
+ * - `profile:avatar` - User avatar image
181
+ * - `profile:name` - User display name
182
+ *
183
+ * @module features/profile/screens/Main
184
+ */
185
+ export const ProfileScreen = () => (
186
+ <Box testID="profile:container" className="flex-1 p-4">
187
+ <Image
188
+ testID="profile:avatar"
189
+ source={{ uri: user.avatarUrl }}
190
+ accessibilityLabel={`${user.name}'s profile photo`}
191
+ />
192
+ <Text testID="profile:name" accessibilityRole="heading">
193
+ {user.name}
194
+ </Text>
195
+ <Pressable
196
+ accessibilityLabel="Edit profile"
197
+ onPress={handleEdit}
198
+ >
199
+ <Text>Edit</Text>
200
+ </Pressable>
201
+ </Box>
202
+ );
203
+ ```
204
+
205
+ ## Corresponding E2E Test
206
+
207
+ ```typescript
208
+ test.describe("Profile Screen", () => {
209
+ test("displays user information", async ({ page }) => {
210
+ await page.goto("/profile");
211
+
212
+ // Verify structural container
213
+ await expect(page.getByTestId("profile:container")).toBeVisible();
214
+
215
+ // Prefer accessible queries when available
216
+ await expect(page.getByRole("heading")).toHaveText("John Doe");
217
+ await expect(page.getByRole("button", { name: "Edit profile" })).toBeVisible();
218
+
219
+ // Use testID for elements without semantic roles
220
+ await expect(page.getByTestId("profile:avatar")).toBeVisible();
221
+ });
222
+ });
223
+ ```