@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,505 @@
1
+ # AsyncStorage Reference
2
+
3
+ ## Overview
4
+
5
+ AsyncStorage is an asynchronous, unencrypted, persistent key-value storage system for React Native. The community package `@react-native-async-storage/async-storage` is the standard solution for Expo projects.
6
+
7
+ ## Key Characteristics
8
+
9
+ - **Asynchronous**: All operations return Promises (non-blocking)
10
+ - **String-only**: Stores only string values (JSON serialization required for objects)
11
+ - **Persistent**: Data survives app restarts
12
+ - **Unencrypted**: Not suitable for sensitive data
13
+ - **Size limits**: ~6 MB total storage, ~2 MB per record (varies by platform)
14
+
15
+ ## Core API
16
+
17
+ ### Basic Operations
18
+
19
+ ```typescript
20
+ import AsyncStorage from "@react-native-async-storage/async-storage";
21
+
22
+ // Set a value
23
+ await AsyncStorage.setItem("@app:key", "string value");
24
+
25
+ // Get a value (returns string | null)
26
+ const value = await AsyncStorage.getItem("@app:key");
27
+
28
+ // Remove a value
29
+ await AsyncStorage.removeItem("@app:key");
30
+
31
+ // Get all keys
32
+ const allKeys = await AsyncStorage.getAllKeys();
33
+
34
+ // Clear all storage (use with caution)
35
+ await AsyncStorage.clear();
36
+ ```
37
+
38
+ ### Batch Operations
39
+
40
+ More efficient than multiple single operations:
41
+
42
+ ```typescript
43
+ // Get multiple values
44
+ const keyValuePairs = await AsyncStorage.multiGet([
45
+ "@app:user-prefs",
46
+ "@app:filters",
47
+ "@app:theme",
48
+ ]);
49
+ // Returns: [["@app:user-prefs", "..."], ["@app:filters", "..."], ...]
50
+
51
+ // Set multiple values
52
+ await AsyncStorage.multiSet([
53
+ ["@app:user-prefs", JSON.stringify(prefs)],
54
+ ["@app:filters", JSON.stringify(filters)],
55
+ ]);
56
+
57
+ // Remove multiple keys
58
+ await AsyncStorage.multiRemove(["@app:temp-data", "@app:cache"]);
59
+
60
+ // Merge values (shallow merge for JSON objects)
61
+ await AsyncStorage.multiMerge([
62
+ ["@app:user", JSON.stringify({ name: "John" })],
63
+ ["@app:user", JSON.stringify({ age: 30 })],
64
+ ]);
65
+ // Result: { name: "John", age: 30 }
66
+ ```
67
+
68
+ ## Type-Safe Utilities
69
+
70
+ ### Generic Storage Functions
71
+
72
+ ```typescript
73
+ import AsyncStorage from "@react-native-async-storage/async-storage";
74
+
75
+ /**
76
+ * Save typed data to AsyncStorage with error handling
77
+ * @param key - Storage key (should include namespace prefix)
78
+ * @param value - Value to store (will be JSON stringified)
79
+ */
80
+ export const saveToStorage = async <T>(
81
+ key: string,
82
+ value: T
83
+ ): Promise<void> => {
84
+ try {
85
+ const jsonValue = JSON.stringify(value);
86
+ await AsyncStorage.setItem(key, jsonValue);
87
+ } catch (error) {
88
+ const message = error instanceof Error ? error.message : "Unknown error";
89
+ console.error(`Failed to save ${key}:`, message);
90
+ throw error;
91
+ }
92
+ };
93
+
94
+ /**
95
+ * Load typed data from AsyncStorage with error handling
96
+ * @param key - Storage key
97
+ * @param defaultValue - Default value if key doesn't exist or parsing fails
98
+ * @returns Parsed value or default
99
+ */
100
+ export const loadFromStorage = async <T>(
101
+ key: string,
102
+ defaultValue: T
103
+ ): Promise<T> => {
104
+ try {
105
+ const jsonValue = await AsyncStorage.getItem(key);
106
+ if (jsonValue === null) {
107
+ return defaultValue;
108
+ }
109
+ return JSON.parse(jsonValue) as T;
110
+ } catch (error) {
111
+ const message = error instanceof Error ? error.message : "Unknown error";
112
+ console.error(`Failed to load ${key}:`, message);
113
+ return defaultValue;
114
+ }
115
+ };
116
+
117
+ /**
118
+ * Remove data from AsyncStorage
119
+ * @param key - Storage key to remove
120
+ */
121
+ export const removeFromStorage = async (key: string): Promise<void> => {
122
+ try {
123
+ await AsyncStorage.removeItem(key);
124
+ } catch (error) {
125
+ const message = error instanceof Error ? error.message : "Unknown error";
126
+ console.error(`Failed to remove ${key}:`, message);
127
+ }
128
+ };
129
+ ```
130
+
131
+ ### Result-Based Error Handling
132
+
133
+ For operations where you need to know if they succeeded:
134
+
135
+ ```typescript
136
+ interface StorageResult<T> {
137
+ readonly success: boolean;
138
+ readonly data?: T;
139
+ readonly error?: string;
140
+ }
141
+
142
+ /**
143
+ * Safely get item with success/failure result
144
+ */
145
+ export const safeGetItem = async <T>(
146
+ key: string,
147
+ defaultValue: T
148
+ ): Promise<StorageResult<T>> => {
149
+ try {
150
+ const jsonValue = await AsyncStorage.getItem(key);
151
+ if (jsonValue === null) {
152
+ return { success: true, data: defaultValue };
153
+ }
154
+ const parsed = JSON.parse(jsonValue) as T;
155
+ return { success: true, data: parsed };
156
+ } catch (error) {
157
+ const errorMessage =
158
+ error instanceof Error ? error.message : "Unknown error";
159
+ return { success: false, error: errorMessage, data: defaultValue };
160
+ }
161
+ };
162
+
163
+ /**
164
+ * Safely set item with success/failure result
165
+ */
166
+ export const safeSetItem = async <T>(
167
+ key: string,
168
+ value: T
169
+ ): Promise<StorageResult<void>> => {
170
+ try {
171
+ await AsyncStorage.setItem(key, JSON.stringify(value));
172
+ return { success: true };
173
+ } catch (error) {
174
+ const errorMessage =
175
+ error instanceof Error ? error.message : "Unknown error";
176
+ return { success: false, error: errorMessage };
177
+ }
178
+ };
179
+
180
+ // Usage
181
+ const result = await safeGetItem<UserPrefs>("@app:prefs", DEFAULT_PREFS);
182
+ if (!result.success) {
183
+ console.warn("Storage read failed:", result.error);
184
+ }
185
+ const prefs = result.data;
186
+ ```
187
+
188
+ ## Key Naming Conventions
189
+
190
+ ### Namespace Prefix
191
+
192
+ Always use a namespace prefix to avoid collisions with other libraries:
193
+
194
+ ```typescript
195
+ // Project namespace
196
+ const STORAGE_PREFIX = "@whatever";
197
+
198
+ // Key examples
199
+ const KEYS = {
200
+ USER_PREFERENCES: `${STORAGE_PREFIX}:user-preferences`,
201
+ FILTER_VALUES: `${STORAGE_PREFIX}:filter-values`,
202
+ FEATURE_FLAGS: `${STORAGE_PREFIX}:feature-flags`,
203
+ ONBOARDING_COMPLETE: `${STORAGE_PREFIX}:onboarding-complete`,
204
+ } as const;
205
+ ```
206
+
207
+ ### Key Organization
208
+
209
+ ```typescript
210
+ // Feature-scoped keys
211
+ const PLAYER_KEYS = {
212
+ FAVORITES: "@whatever:players:favorites",
213
+ RECENT_VIEWS: "@whatever:players:recent-views",
214
+ COMPARISONS: "@whatever:players:comparisons",
215
+ } as const;
216
+
217
+ const SETTINGS_KEYS = {
218
+ THEME: "@whatever:settings:theme",
219
+ LANGUAGE: "@whatever:settings:language",
220
+ NOTIFICATIONS: "@whatever:settings:notifications",
221
+ } as const;
222
+ ```
223
+
224
+ ## Error Handling Patterns
225
+
226
+ ### Always Use Try/Catch
227
+
228
+ AsyncStorage operations can fail for various reasons (storage full, permissions, corrupted data):
229
+
230
+ ```typescript
231
+ // CORRECT - proper error handling
232
+ const loadSettings = async (): Promise<Settings> => {
233
+ try {
234
+ const stored = await AsyncStorage.getItem(SETTINGS_KEY);
235
+ if (stored) {
236
+ return JSON.parse(stored) as Settings;
237
+ }
238
+ return DEFAULT_SETTINGS;
239
+ } catch (error) {
240
+ const message = error instanceof Error ? error.message : "Unknown error";
241
+ console.error("Failed to load settings:", message);
242
+ return DEFAULT_SETTINGS; // Graceful fallback
243
+ }
244
+ };
245
+
246
+ // INCORRECT - unhandled errors can crash the app
247
+ const loadSettings = async (): Promise<Settings> => {
248
+ const stored = await AsyncStorage.getItem(SETTINGS_KEY);
249
+ return stored ? JSON.parse(stored) : DEFAULT_SETTINGS;
250
+ };
251
+ ```
252
+
253
+ ### Handle JSON Parse Errors Separately
254
+
255
+ ```typescript
256
+ const loadData = async <T>(key: string, defaultValue: T): Promise<T> => {
257
+ try {
258
+ const jsonValue = await AsyncStorage.getItem(key);
259
+ if (jsonValue === null) {
260
+ return defaultValue;
261
+ }
262
+
263
+ try {
264
+ return JSON.parse(jsonValue) as T;
265
+ } catch (parseError) {
266
+ // Corrupted data - clear and return default
267
+ console.warn(`Corrupted data for ${key}, resetting to default`);
268
+ await AsyncStorage.removeItem(key);
269
+ return defaultValue;
270
+ }
271
+ } catch (storageError) {
272
+ const message =
273
+ storageError instanceof Error ? storageError.message : "Unknown error";
274
+ console.error(`Storage error for ${key}:`, message);
275
+ return defaultValue;
276
+ }
277
+ };
278
+ ```
279
+
280
+ ## Security Considerations
281
+
282
+ ### Never Store Sensitive Data
283
+
284
+ AsyncStorage is unencrypted and readable by anyone with device access:
285
+
286
+ ```typescript
287
+ // NEVER store these in AsyncStorage:
288
+ // - Access tokens
289
+ // - Refresh tokens
290
+ // - Passwords
291
+ // - API keys
292
+ // - Personal identification numbers
293
+ // - Financial data
294
+
295
+ // Use expo-secure-store instead:
296
+ import * as SecureStore from "expo-secure-store";
297
+
298
+ const saveToken = async (token: string): Promise<void> => {
299
+ await SecureStore.setItemAsync("accessToken", token);
300
+ };
301
+
302
+ const getToken = async (): Promise<string | null> => {
303
+ return await SecureStore.getItemAsync("accessToken");
304
+ };
305
+ ```
306
+
307
+ ### What IS Safe for AsyncStorage
308
+
309
+ - User preferences (theme, language, notifications)
310
+ - Feature flags
311
+ - UI state (last viewed tab, collapsed sections)
312
+ - Non-sensitive cache data
313
+ - Onboarding completion flags
314
+ - Search history (non-sensitive queries)
315
+
316
+ ## Performance Best Practices
317
+
318
+ ### Use Batch Operations
319
+
320
+ ```typescript
321
+ // EFFICIENT - single batch operation
322
+ await AsyncStorage.multiSet([
323
+ ["@app:pref1", JSON.stringify(pref1)],
324
+ ["@app:pref2", JSON.stringify(pref2)],
325
+ ["@app:pref3", JSON.stringify(pref3)],
326
+ ]);
327
+
328
+ // INEFFICIENT - multiple sequential operations
329
+ await AsyncStorage.setItem("@app:pref1", JSON.stringify(pref1));
330
+ await AsyncStorage.setItem("@app:pref2", JSON.stringify(pref2));
331
+ await AsyncStorage.setItem("@app:pref3", JSON.stringify(pref3));
332
+ ```
333
+
334
+ ### Debounce Frequent Writes
335
+
336
+ For values that change frequently (e.g., form inputs):
337
+
338
+ ```typescript
339
+ import { useDebouncedCallback } from "use-debounce";
340
+
341
+ const usePersistedFilter = () => {
342
+ const [filter, setFilter] = useState("");
343
+
344
+ const persistFilter = useDebouncedCallback(
345
+ async (value: string) => {
346
+ try {
347
+ await AsyncStorage.setItem("@app:filter", value);
348
+ } catch (error) {
349
+ console.error("Failed to persist filter");
350
+ }
351
+ },
352
+ 500 // 500ms debounce
353
+ );
354
+
355
+ const updateFilter = useCallback(
356
+ (value: string) => {
357
+ setFilter(value);
358
+ persistFilter(value);
359
+ },
360
+ [persistFilter]
361
+ );
362
+
363
+ return { filter, updateFilter };
364
+ };
365
+ ```
366
+
367
+ ### Load Only What You Need
368
+
369
+ ```typescript
370
+ // EFFICIENT - load specific keys
371
+ const loadUserContext = async () => {
372
+ const keys = ["@app:user-prefs", "@app:theme"];
373
+ const results = await AsyncStorage.multiGet(keys);
374
+ return results.reduce(
375
+ (acc, [key, value]) => ({
376
+ ...acc,
377
+ [key]: value ? JSON.parse(value) : null,
378
+ }),
379
+ {} as Record<string, unknown>
380
+ );
381
+ };
382
+
383
+ // INEFFICIENT - loading all keys
384
+ const loadEverything = async () => {
385
+ const allKeys = await AsyncStorage.getAllKeys();
386
+ const allData = await AsyncStorage.multiGet(allKeys);
387
+ // Processing potentially hundreds of keys...
388
+ };
389
+ ```
390
+
391
+ ### Consider Storage Limits
392
+
393
+ ```typescript
394
+ // Check data size before storing
395
+ const safeStore = async <T>(key: string, data: T): Promise<boolean> => {
396
+ const serialized = JSON.stringify(data);
397
+ const sizeInBytes = new Blob([serialized]).size;
398
+
399
+ // Warn if approaching 2MB limit per key
400
+ if (sizeInBytes > 1_500_000) {
401
+ console.warn(
402
+ `Data for ${key} is ${(sizeInBytes / 1_000_000).toFixed(2)}MB`
403
+ );
404
+ }
405
+
406
+ if (sizeInBytes > 2_000_000) {
407
+ console.error(`Data for ${key} exceeds 2MB limit, not storing`);
408
+ return false;
409
+ }
410
+
411
+ try {
412
+ await AsyncStorage.setItem(key, serialized);
413
+ return true;
414
+ } catch (error) {
415
+ console.error("Storage failed:", error);
416
+ return false;
417
+ }
418
+ };
419
+ ```
420
+
421
+ ## Migration Patterns
422
+
423
+ ### Versioned Storage Keys
424
+
425
+ ```typescript
426
+ const STORAGE_VERSION = "v2";
427
+ const PREFS_KEY = `@app:preferences:${STORAGE_VERSION}`;
428
+
429
+ // Migration on app start
430
+ const migrateStorageIfNeeded = async (): Promise<void> => {
431
+ const allKeys = await AsyncStorage.getAllKeys();
432
+
433
+ // Find old version keys
434
+ const oldKeys = allKeys.filter(
435
+ key => key.startsWith("@app:preferences:") && !key.includes(STORAGE_VERSION)
436
+ );
437
+
438
+ if (oldKeys.length === 0) return;
439
+
440
+ // Migrate each old key
441
+ const migrations = oldKeys.map(async oldKey => {
442
+ try {
443
+ const oldData = await AsyncStorage.getItem(oldKey);
444
+ if (oldData) {
445
+ const parsed = JSON.parse(oldData);
446
+ const migrated = migratePreferences(parsed); // Your migration logic
447
+ await AsyncStorage.setItem(PREFS_KEY, JSON.stringify(migrated));
448
+ }
449
+ await AsyncStorage.removeItem(oldKey);
450
+ } catch (error) {
451
+ console.error(`Failed to migrate ${oldKey}:`, error);
452
+ }
453
+ });
454
+
455
+ await Promise.all(migrations);
456
+ };
457
+ ```
458
+
459
+ ### Schema Validation
460
+
461
+ ```typescript
462
+ interface StoredPreferences {
463
+ readonly theme: "light" | "dark";
464
+ readonly language: string;
465
+ readonly schemaVersion: number;
466
+ }
467
+
468
+ const CURRENT_SCHEMA_VERSION = 2;
469
+
470
+ const isValidPreferences = (data: unknown): data is StoredPreferences => {
471
+ if (typeof data !== "object" || data === null) return false;
472
+ const obj = data as Record<string, unknown>;
473
+ return (
474
+ (obj.theme === "light" || obj.theme === "dark") &&
475
+ typeof obj.language === "string" &&
476
+ typeof obj.schemaVersion === "number"
477
+ );
478
+ };
479
+
480
+ const loadPreferences = async (): Promise<StoredPreferences> => {
481
+ try {
482
+ const stored = await AsyncStorage.getItem(PREFS_KEY);
483
+ if (!stored) return DEFAULT_PREFERENCES;
484
+
485
+ const parsed = JSON.parse(stored);
486
+
487
+ if (!isValidPreferences(parsed)) {
488
+ console.warn("Invalid preferences schema, resetting");
489
+ await AsyncStorage.removeItem(PREFS_KEY);
490
+ return DEFAULT_PREFERENCES;
491
+ }
492
+
493
+ if (parsed.schemaVersion < CURRENT_SCHEMA_VERSION) {
494
+ const migrated = migrateToCurrentSchema(parsed);
495
+ await AsyncStorage.setItem(PREFS_KEY, JSON.stringify(migrated));
496
+ return migrated;
497
+ }
498
+
499
+ return parsed;
500
+ } catch (error) {
501
+ console.error("Failed to load preferences:", error);
502
+ return DEFAULT_PREFERENCES;
503
+ }
504
+ };
505
+ ```