@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,230 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ module.exports = {
5
+ meta: {
6
+ type: "problem",
7
+ docs: {
8
+ description:
9
+ "Enforce component structure in features/**/components directories",
10
+ category: "Best Practices",
11
+ recommended: true,
12
+ },
13
+ fixable: null,
14
+ schema: [],
15
+ messages: {
16
+ missingContainer:
17
+ 'Component directory "{{componentName}}" is missing {{componentName}}Container.tsx file',
18
+ missingView:
19
+ 'Component directory "{{componentName}}" is missing {{componentName}}View.tsx file',
20
+ missingIndex:
21
+ 'Component directory "{{componentName}}" is missing index.tsx file',
22
+ incorrectIndexExport:
23
+ "index.tsx should export {{componentName}}Container or {{componentName}}View as default",
24
+ componentNotInDirectory:
25
+ "Component files must be inside a directory named after the component",
26
+ incorrectFileNaming: "{{fileName}} should be named {{expectedName}}",
27
+ invalidFileInComponentDirectory:
28
+ "Only index.ts(x), {{componentName}}Container.tsx, and {{componentName}}View.tsx are allowed in component directories. Found: {{fileName}}",
29
+ },
30
+ },
31
+
32
+ create(context) {
33
+ const filename = context.getFilename();
34
+ const normalizedPath = filename.replace(/\\/g, "/");
35
+
36
+ // Get the path after components/ or screens/
37
+ const componentsMatch = normalizedPath.match(
38
+ /\/(components|screens)\/(.+)$/
39
+ );
40
+ if (!componentsMatch) return {};
41
+ const afterComponents = componentsMatch[2];
42
+
43
+ const pathParts = afterComponents.split("/");
44
+
45
+ // If file is directly in components/ directory (not in a subdirectory)
46
+ if (pathParts.length === 1) {
47
+ const fileName = pathParts[0];
48
+ if (fileName.endsWith(".tsx") || fileName.endsWith(".jsx")) {
49
+ context.report({
50
+ node: context.getSourceCode().ast,
51
+ messageId: "componentNotInDirectory",
52
+ });
53
+ }
54
+ return {};
55
+ }
56
+
57
+ // Get component name and file name from the END of the path
58
+ // This handles both ComponentName/file.tsx and custom/ui/ComponentName/file.tsx
59
+ const fileName = pathParts[pathParts.length - 1];
60
+ const componentName = pathParts[pathParts.length - 2];
61
+
62
+ // Skip validation for files in __tests__ directories
63
+ if (componentName === "__tests__") {
64
+ return {};
65
+ }
66
+
67
+ // Only check .ts/.tsx/.jsx files
68
+ if (
69
+ !fileName ||
70
+ (!fileName.endsWith(".ts") &&
71
+ !fileName.endsWith(".tsx") &&
72
+ !fileName.endsWith(".jsx"))
73
+ ) {
74
+ return {};
75
+ }
76
+
77
+ // Get the directory path
78
+ const dirPath = path.dirname(filename);
79
+
80
+ // Check if file is one of the allowed types
81
+ const isIndex =
82
+ fileName === "index.ts" ||
83
+ fileName === "index.tsx" ||
84
+ fileName === "index.jsx";
85
+
86
+ // Allow *Container.*.tsx and *Container.*.jsx patterns (e.g., MyComponentContainer.native.tsx)
87
+ const containerPattern = new RegExp(
88
+ `^${componentName}Container\\.[^.]+\\.(tsx|jsx)$`
89
+ );
90
+ const isContainer =
91
+ fileName === `${componentName}Container.tsx` ||
92
+ fileName === `${componentName}Container.jsx` ||
93
+ containerPattern.test(fileName);
94
+
95
+ // Allow *View.*.tsx and *View.*.jsx patterns (e.g., MyComponentView.web.tsx)
96
+ const viewPattern = new RegExp(
97
+ `^${componentName}View\\.[^.]+\\.(tsx|jsx)$`
98
+ );
99
+ const isView =
100
+ fileName === `${componentName}View.tsx` ||
101
+ fileName === `${componentName}View.jsx` ||
102
+ viewPattern.test(fileName);
103
+
104
+ // Report error if file is not one of the allowed types
105
+ if (!isIndex && !isContainer && !isView) {
106
+ context.report({
107
+ node: context.getSourceCode().ast,
108
+ messageId: "invalidFileInComponentDirectory",
109
+ data: { fileName, componentName },
110
+ });
111
+ return {};
112
+ }
113
+
114
+ // Check file naming
115
+ if (
116
+ fileName === "index.ts" ||
117
+ fileName === "index.tsx" ||
118
+ fileName === "index.jsx"
119
+ ) {
120
+ // Check if index.tsx exports the Container
121
+ return {
122
+ Program(node) {
123
+ const sourceCode = context.getSourceCode();
124
+ const text = sourceCode.getText();
125
+
126
+ // Check for export patterns (allow Container or View)
127
+ const defaultExportPattern = new RegExp(
128
+ `export\\s*{\\s*default\\s*}\\s*from\\s*['"\`]\\.\\/${componentName}(Container|View)['"\`]|` +
129
+ `export\\s*\\*\\s*from\\s*['"\`]\\.\\/${componentName}(Container|View)['"\`]|` +
130
+ `export\\s*{\\s*${componentName}(Container|View)\\s*as\\s*default\\s*}|` +
131
+ `export\\s*default\\s*${componentName}(Container|View)`
132
+ );
133
+
134
+ if (!defaultExportPattern.test(text)) {
135
+ context.report({
136
+ node,
137
+ messageId: "incorrectIndexExport",
138
+ data: { componentName },
139
+ });
140
+ }
141
+ },
142
+ };
143
+ } else if (
144
+ fileName.endsWith("Container.tsx") ||
145
+ fileName.endsWith("Container.jsx")
146
+ ) {
147
+ const expectedName = `${componentName}Container.tsx`;
148
+ if (
149
+ fileName !== expectedName &&
150
+ fileName !== `${componentName}Container.jsx`
151
+ ) {
152
+ context.report({
153
+ node: context.getSourceCode().ast,
154
+ messageId: "incorrectFileNaming",
155
+ data: { fileName, expectedName },
156
+ });
157
+ }
158
+ } else if (fileName.endsWith("View.tsx") || fileName.endsWith("View.jsx")) {
159
+ const expectedName = `${componentName}View.tsx`;
160
+ if (
161
+ fileName !== expectedName &&
162
+ fileName !== `${componentName}View.jsx`
163
+ ) {
164
+ context.report({
165
+ node: context.getSourceCode().ast,
166
+ messageId: "incorrectFileNaming",
167
+ data: { fileName, expectedName },
168
+ });
169
+ }
170
+ }
171
+
172
+ // Check for required files in the directory (only once per directory)
173
+ // We'll do this check only for the first file we encounter
174
+ const cache = new Map();
175
+ const checkRequiredFiles = () => {
176
+ try {
177
+ const files = cache.has(dirPath)
178
+ ? cache.get(dirPath)
179
+ : (() => {
180
+ const dirFiles = fs.readdirSync(dirPath);
181
+ cache.set(dirPath, dirFiles);
182
+ return dirFiles;
183
+ })();
184
+ const hasContainer = files.some(
185
+ f =>
186
+ f === `${componentName}Container.tsx` ||
187
+ f === `${componentName}Container.jsx`
188
+ );
189
+ const hasView = files.some(
190
+ f =>
191
+ f === `${componentName}View.tsx` || f === `${componentName}View.jsx`
192
+ );
193
+ const hasIndex = files.some(
194
+ f => f === "index.tsx" || f === "index.jsx"
195
+ );
196
+
197
+ if (!hasContainer) {
198
+ context.report({
199
+ node: context.getSourceCode().ast,
200
+ messageId: "missingContainer",
201
+ data: { componentName },
202
+ });
203
+ }
204
+ if (!hasView) {
205
+ context.report({
206
+ node: context.getSourceCode().ast,
207
+ messageId: "missingView",
208
+ data: { componentName },
209
+ });
210
+ }
211
+ if (!hasIndex) {
212
+ context.report({
213
+ node: context.getSourceCode().ast,
214
+ messageId: "missingIndex",
215
+ data: { componentName },
216
+ });
217
+ }
218
+ } catch (_err) {
219
+ // Directory might not exist or be accessible
220
+ }
221
+ };
222
+
223
+ // Only check once per file
224
+ if (fileName === "index.tsx" || fileName === "index.jsx") {
225
+ checkRequiredFiles();
226
+ }
227
+
228
+ return {};
229
+ },
230
+ };
@@ -0,0 +1,91 @@
1
+ module.exports = {
2
+ meta: {
3
+ type: "problem",
4
+ docs: {
5
+ description:
6
+ "Disallow return statements in View components - use arrow function shorthand",
7
+ category: "Best Practices",
8
+ recommended: true,
9
+ },
10
+ fixable: null,
11
+ schema: [],
12
+ messages: {
13
+ noReturnInView:
14
+ "View components should use arrow function shorthand: () => (...) instead of () => { return (...) }",
15
+ },
16
+ },
17
+
18
+ create(context) {
19
+ const filename = context.getFilename();
20
+ const normalizedPath = filename.replace(/\\/g, "/");
21
+
22
+ // Only check View.tsx and View.jsx files
23
+ if (!filename.endsWith("View.tsx") && !filename.endsWith("View.jsx")) {
24
+ return {};
25
+ }
26
+
27
+ // Check if file is in features/**/components, features/**/screens, or components directory
28
+ const isFeatureComponent =
29
+ normalizedPath.includes("features/") &&
30
+ normalizedPath.includes("/components/");
31
+ const isFeatureScreen =
32
+ normalizedPath.includes("features/") &&
33
+ normalizedPath.includes("/screens/");
34
+ const isComponentsDir =
35
+ normalizedPath.includes("/components/") &&
36
+ !normalizedPath.includes("/components/ui/") &&
37
+ !normalizedPath.includes("/components/custom/ui/");
38
+
39
+ if (!isFeatureComponent && !isFeatureScreen && !isComponentsDir) {
40
+ return {};
41
+ }
42
+
43
+ return {
44
+ ArrowFunctionExpression(node) {
45
+ // Check if this is a component (starts with capital letter or is exported)
46
+ const parent = node.parent;
47
+
48
+ // Helper to check if variable has a View component name
49
+ const isViewComponent = name =>
50
+ /^[A-Z]/.test(name) && name.includes("View");
51
+
52
+ // Determine if this is a component
53
+ const isComponent = (() => {
54
+ // Check if it's a default export
55
+ if (parent.type === "ExportDefaultDeclaration") {
56
+ return true;
57
+ }
58
+
59
+ // Check if it's a variable declaration with PascalCase name
60
+ if (
61
+ parent.type === "VariableDeclarator" &&
62
+ parent.id.type === "Identifier"
63
+ ) {
64
+ return isViewComponent(parent.id.name);
65
+ }
66
+
67
+ // Check if it's part of an export statement
68
+ if (
69
+ parent.type === "VariableDeclarator" &&
70
+ parent.parent.type === "VariableDeclaration" &&
71
+ parent.parent.parent.type === "ExportNamedDeclaration"
72
+ ) {
73
+ return isViewComponent(parent.id.name);
74
+ }
75
+
76
+ return false;
77
+ })();
78
+
79
+ if (!isComponent) return;
80
+
81
+ // Check if the arrow function has a block body (any BlockStatement is forbidden)
82
+ if (node.body.type === "BlockStatement") {
83
+ context.report({
84
+ node,
85
+ messageId: "noReturnInView",
86
+ });
87
+ }
88
+ },
89
+ };
90
+ },
91
+ };
@@ -0,0 +1,178 @@
1
+ /**
2
+ * ESLint rule to enforce React.memo usage with displayName in View components
3
+ *
4
+ * This rule ensures that all View components (*View.tsx, *View.jsx) follow the standardized pattern:
5
+ * - Must be wrapped with memo() or React.memo() in the default export
6
+ * - Must have a displayName property
7
+ *
8
+ * Excludes components/ui/** and components/custom/ui/** directories (third-party generated files)
9
+ * @module eslint-plugin-component-structure/rules/require-memo-in-view
10
+ */
11
+
12
+ module.exports = {
13
+ meta: {
14
+ type: "problem",
15
+ docs: {
16
+ description:
17
+ "Enforce React.memo usage with displayName in View components",
18
+ category: "Best Practices",
19
+ recommended: true,
20
+ },
21
+ schema: [],
22
+ messages: {
23
+ missingMemo:
24
+ "View components must be wrapped with memo(). Expected: export default memo({{componentName}})",
25
+ missingDisplayName:
26
+ 'View components must have a displayName property. Expected: {{componentName}}.displayName = "{{componentName}}"',
27
+ },
28
+ },
29
+
30
+ create(context) {
31
+ const filename = context.getFilename();
32
+ const normalizedPath = filename.replace(/\\/g, "/");
33
+
34
+ // Only check View.tsx and View.jsx files
35
+ if (!filename.endsWith("View.tsx") && !filename.endsWith("View.jsx")) {
36
+ return {};
37
+ }
38
+
39
+ // Exclude components/ui/** and components/custom/ui/** directories
40
+ if (
41
+ normalizedPath.includes("/components/ui/") ||
42
+ normalizedPath.includes("/components/custom/ui/")
43
+ ) {
44
+ return {};
45
+ }
46
+
47
+ // Check if file is in features/**/components, features/**/screens, or components directory
48
+ const isFeatureComponent =
49
+ normalizedPath.includes("features/") &&
50
+ normalizedPath.includes("/components/");
51
+ const isFeatureScreen =
52
+ normalizedPath.includes("features/") &&
53
+ normalizedPath.includes("/screens/");
54
+ const isComponentsDir = normalizedPath.includes("/components/");
55
+
56
+ if (!isFeatureComponent && !isFeatureScreen && !isComponentsDir) {
57
+ return {};
58
+ }
59
+
60
+ const state = {
61
+ componentName: null,
62
+ hasMemoImport: false,
63
+ hasMemoWrapper: false,
64
+ hasDisplayName: false,
65
+ exportNode: null,
66
+ };
67
+
68
+ return {
69
+ ImportDeclaration(node) {
70
+ // Check if memo is imported from 'react'
71
+ if (node.source.value === "react") {
72
+ const memoImport = node.specifiers.find(
73
+ spec =>
74
+ spec.type === "ImportSpecifier" && spec.imported.name === "memo"
75
+ );
76
+ if (memoImport) {
77
+ state.hasMemoImport = true;
78
+ }
79
+ }
80
+ },
81
+
82
+ VariableDeclarator(node) {
83
+ // Find the component name from variable declaration
84
+ if (
85
+ node.id.type === "Identifier" &&
86
+ /^[A-Z]/.test(node.id.name) &&
87
+ node.id.name.includes("View")
88
+ ) {
89
+ state.componentName = node.id.name;
90
+ }
91
+ },
92
+
93
+ AssignmentExpression(node) {
94
+ // Check for displayName assignment
95
+ if (
96
+ node.left.type === "MemberExpression" &&
97
+ node.left.property.name === "displayName" &&
98
+ node.left.object.type === "Identifier"
99
+ ) {
100
+ const componentName = node.left.object.name;
101
+ if (
102
+ componentName === state.componentName ||
103
+ /^[A-Z]/.test(componentName)
104
+ ) {
105
+ state.hasDisplayName = true;
106
+ }
107
+ }
108
+ },
109
+
110
+ ExportDefaultDeclaration(node) {
111
+ state.exportNode = node;
112
+
113
+ // Check if the default export is wrapped with memo()
114
+ if (node.declaration.type === "CallExpression") {
115
+ const callee = node.declaration.callee;
116
+
117
+ // Check for memo() or React.memo()
118
+ const isMemoCall =
119
+ (callee.type === "Identifier" && callee.name === "memo") ||
120
+ (callee.type === "MemberExpression" &&
121
+ callee.object.name === "React" &&
122
+ callee.property.name === "memo");
123
+
124
+ if (isMemoCall) {
125
+ state.hasMemoWrapper = true;
126
+
127
+ // If using React.memo, ensure memo is imported from 'react'
128
+ if (callee.type === "MemberExpression" && !state.hasMemoImport) {
129
+ // React.memo is allowed, but we prefer direct memo import
130
+ // Store that we found React.memo usage
131
+ state.hasReactMemo = true;
132
+ }
133
+
134
+ // Get the component name from the memo argument
135
+ const firstArg = node.declaration.arguments[0];
136
+ if (
137
+ firstArg &&
138
+ firstArg.type === "Identifier" &&
139
+ !state.componentName
140
+ ) {
141
+ state.componentName = firstArg.name;
142
+ }
143
+ }
144
+ } else if (
145
+ node.declaration.type === "Identifier" &&
146
+ !state.componentName
147
+ ) {
148
+ // Component exported without memo wrapper
149
+ state.componentName = node.declaration.name;
150
+ }
151
+ },
152
+
153
+ "Program:exit"() {
154
+ if (!state.exportNode || !state.componentName) {
155
+ return;
156
+ }
157
+
158
+ // Report missing memo wrapper
159
+ if (!state.hasMemoWrapper) {
160
+ context.report({
161
+ node: state.exportNode,
162
+ messageId: "missingMemo",
163
+ data: { componentName: state.componentName },
164
+ });
165
+ }
166
+
167
+ // Report missing displayName
168
+ if (!state.hasDisplayName) {
169
+ context.report({
170
+ node: state.exportNode,
171
+ messageId: "missingDisplayName",
172
+ data: { componentName: state.componentName },
173
+ });
174
+ }
175
+ },
176
+ };
177
+ },
178
+ };