@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,443 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Directory Structure Validation Script
4
+
5
+ Validates that files and directories follow the project's documented structure:
6
+ - Feature module structure (components/, screens/, hooks/, etc.)
7
+ - Container/View pattern compliance
8
+ - Test file placement in __tests__/ directories
9
+ - Route file thin wrapper pattern
10
+ - Proper naming conventions
11
+
12
+ Usage:
13
+ python3 validate_structure.py [path]
14
+
15
+ If no path provided, validates from current directory.
16
+ """
17
+
18
+ import os
19
+ import re
20
+ import sys
21
+ from pathlib import Path
22
+ from typing import List, Tuple, NamedTuple
23
+ from dataclasses import dataclass, field
24
+
25
+
26
+ @dataclass
27
+ class ValidationResult:
28
+ """Result of a validation check."""
29
+ passed: bool
30
+ message: str
31
+ file_path: str = ""
32
+ suggestion: str = ""
33
+
34
+
35
+ @dataclass
36
+ class ValidationReport:
37
+ """Complete validation report."""
38
+ errors: List[ValidationResult] = field(default_factory=list)
39
+ warnings: List[ValidationResult] = field(default_factory=list)
40
+ passed: List[ValidationResult] = field(default_factory=list)
41
+
42
+ @property
43
+ def has_errors(self) -> bool:
44
+ return len(self.errors) > 0
45
+
46
+ @property
47
+ def has_warnings(self) -> bool:
48
+ return len(self.warnings) > 0
49
+
50
+
51
+ # Directories that should contain __tests__/ subdirectories for test files
52
+ TESTABLE_DIRS = {'hooks', 'utils', 'stores', 'providers'}
53
+
54
+ # Valid feature subdirectories
55
+ FEATURE_SUBDIRS = {'components', 'screens', 'hooks', 'stores', 'utils', 'types', 'constants', 'config'}
56
+
57
+ # Files that can exist at feature root level
58
+ FEATURE_ROOT_FILES = {'types.ts', 'constants.ts', 'operations.graphql', 'index.ts', 'index.tsx'}
59
+
60
+ # Pattern for Container/View files
61
+ CONTAINER_PATTERN = re.compile(r'^([A-Z][a-zA-Z0-9]*)Container\.tsx$')
62
+ VIEW_PATTERN = re.compile(r'^([A-Z][a-zA-Z0-9]*)View\.tsx$')
63
+
64
+ # Directories to skip during validation
65
+ SKIP_DIRS = {
66
+ 'node_modules', '.git', 'dist', 'build', '.expo',
67
+ '.next', 'coverage', '__pycache__', '.claude'
68
+ }
69
+
70
+
71
+ def find_project_root(start_path: Path) -> Path:
72
+ """Find the project root by looking for package.json."""
73
+ current = start_path.resolve()
74
+ while current != current.parent:
75
+ if (current / 'package.json').exists():
76
+ return current
77
+ current = current.parent
78
+ return start_path.resolve()
79
+
80
+
81
+ def validate_test_file_placement(root: Path) -> List[ValidationResult]:
82
+ """Check that test files are in __tests__/ subdirectories."""
83
+ results = []
84
+ test_pattern = re.compile(r'\.(test|spec)\.(ts|tsx|js|jsx)$')
85
+
86
+ for dirpath, dirnames, filenames in os.walk(root):
87
+ # Skip excluded directories
88
+ dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
89
+
90
+ path = Path(dirpath)
91
+
92
+ # Skip if we're inside __tests__ directory
93
+ if '__tests__' in path.parts:
94
+ continue
95
+
96
+ # Skip e2e directory (has different structure)
97
+ if 'e2e' in path.parts:
98
+ continue
99
+
100
+ for filename in filenames:
101
+ if test_pattern.search(filename):
102
+ file_path = path / filename
103
+ rel_path = file_path.relative_to(root)
104
+
105
+ # Check if parent directory should have __tests__
106
+ parent_name = path.name
107
+
108
+ results.append(ValidationResult(
109
+ passed=False,
110
+ message=f"Test file not in __tests__/ directory",
111
+ file_path=str(rel_path),
112
+ suggestion=f"Move to {path}/__tests__/{filename}"
113
+ ))
114
+
115
+ return results
116
+
117
+
118
+ def validate_component_structure(component_dir: Path, root: Path) -> List[ValidationResult]:
119
+ """Validate Container/View pattern in a component directory."""
120
+ results = []
121
+ rel_path = component_dir.relative_to(root)
122
+
123
+ if not component_dir.is_dir():
124
+ return results
125
+
126
+ files = list(component_dir.iterdir())
127
+ file_names = [f.name for f in files if f.is_file()]
128
+
129
+ component_name = component_dir.name
130
+
131
+ expected_container = f"{component_name}Container.tsx"
132
+ expected_view = f"{component_name}View.tsx"
133
+ expected_index = "index.tsx"
134
+
135
+ has_container = expected_container in file_names
136
+ has_view = expected_view in file_names
137
+ has_index = expected_index in file_names or "index.ts" in file_names
138
+
139
+ # Check for Container
140
+ if not has_container:
141
+ # Check for any Container file
142
+ containers = [f for f in file_names if CONTAINER_PATTERN.match(f)]
143
+ if containers:
144
+ results.append(ValidationResult(
145
+ passed=False,
146
+ message=f"Container file name mismatch",
147
+ file_path=str(rel_path),
148
+ suggestion=f"Rename {containers[0]} to {expected_container}"
149
+ ))
150
+ else:
151
+ results.append(ValidationResult(
152
+ passed=False,
153
+ message=f"Missing Container file",
154
+ file_path=str(rel_path),
155
+ suggestion=f"Create {expected_container}"
156
+ ))
157
+
158
+ # Check for View
159
+ if not has_view:
160
+ views = [f for f in file_names if VIEW_PATTERN.match(f)]
161
+ if views:
162
+ results.append(ValidationResult(
163
+ passed=False,
164
+ message=f"View file name mismatch",
165
+ file_path=str(rel_path),
166
+ suggestion=f"Rename {views[0]} to {expected_view}"
167
+ ))
168
+ else:
169
+ results.append(ValidationResult(
170
+ passed=False,
171
+ message=f"Missing View file",
172
+ file_path=str(rel_path),
173
+ suggestion=f"Create {expected_view}"
174
+ ))
175
+
176
+ # Check for index
177
+ if not has_index:
178
+ results.append(ValidationResult(
179
+ passed=False,
180
+ message=f"Missing index.tsx",
181
+ file_path=str(rel_path),
182
+ suggestion=f"Create index.tsx that exports Container"
183
+ ))
184
+
185
+ return results
186
+
187
+
188
+ def validate_feature_structure(feature_dir: Path, root: Path) -> List[ValidationResult]:
189
+ """Validate feature module structure."""
190
+ results = []
191
+ rel_path = feature_dir.relative_to(root)
192
+
193
+ if not feature_dir.is_dir():
194
+ return results
195
+
196
+ # Check components directory
197
+ components_dir = feature_dir / 'components'
198
+ if components_dir.exists():
199
+ for item in components_dir.iterdir():
200
+ if item.is_dir() and not item.name.startswith('_'):
201
+ results.extend(validate_component_structure(item, root))
202
+
203
+ # Check screens directory
204
+ screens_dir = feature_dir / 'screens'
205
+ if screens_dir.exists():
206
+ for item in screens_dir.iterdir():
207
+ if item.is_dir() and not item.name.startswith('_'):
208
+ results.extend(validate_component_structure(item, root))
209
+
210
+ # Check hooks have __tests__ if there are test files
211
+ hooks_dir = feature_dir / 'hooks'
212
+ if hooks_dir.exists():
213
+ tests_dir = hooks_dir / '__tests__'
214
+ hook_files = [f for f in hooks_dir.iterdir() if f.is_file() and f.suffix in {'.ts', '.tsx'}]
215
+ if hook_files and not tests_dir.exists():
216
+ results.append(ValidationResult(
217
+ passed=False,
218
+ message=f"Missing __tests__/ directory for hooks",
219
+ file_path=str(rel_path / 'hooks'),
220
+ suggestion=f"Create {rel_path}/hooks/__tests__/ for test files"
221
+ ))
222
+
223
+ # Check utils have __tests__ if there are test files
224
+ utils_dir = feature_dir / 'utils'
225
+ if utils_dir.exists():
226
+ tests_dir = utils_dir / '__tests__'
227
+ util_files = [f for f in utils_dir.iterdir() if f.is_file() and f.suffix in {'.ts', '.tsx'}]
228
+ if util_files and not tests_dir.exists():
229
+ results.append(ValidationResult(
230
+ passed=False,
231
+ message=f"Missing __tests__/ directory for utils",
232
+ file_path=str(rel_path / 'utils'),
233
+ suggestion=f"Create {rel_path}/utils/__tests__/ for test files"
234
+ ))
235
+
236
+ return results
237
+
238
+
239
+ def validate_app_directory(app_dir: Path, root: Path) -> List[ValidationResult]:
240
+ """Validate that app/ directory only contains thin route wrappers."""
241
+ results = []
242
+
243
+ if not app_dir.exists():
244
+ return results
245
+
246
+ # Patterns that indicate non-wrapper code
247
+ business_logic_patterns = [
248
+ (re.compile(r'useState\s*\('), "useState hook usage"),
249
+ (re.compile(r'useEffect\s*\('), "useEffect hook usage"),
250
+ (re.compile(r'useCallback\s*\('), "useCallback hook usage"),
251
+ (re.compile(r'useMemo\s*\('), "useMemo hook usage"),
252
+ (re.compile(r'useQuery\s*\('), "useQuery hook usage"),
253
+ (re.compile(r'useMutation\s*\('), "useMutation hook usage"),
254
+ ]
255
+
256
+ # Files that are allowed (layout files, etc.)
257
+ allowed_patterns = {'_layout.tsx', '_layout.ts', '+not-found.tsx', '+html.tsx'}
258
+
259
+ for dirpath, dirnames, filenames in os.walk(app_dir):
260
+ dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
261
+ path = Path(dirpath)
262
+
263
+ for filename in filenames:
264
+ if not filename.endswith(('.tsx', '.ts')):
265
+ continue
266
+
267
+ if filename in allowed_patterns:
268
+ continue
269
+
270
+ if filename.startswith('_') or filename.startswith('+'):
271
+ continue
272
+
273
+ file_path = path / filename
274
+ rel_path = file_path.relative_to(root)
275
+
276
+ try:
277
+ content = file_path.read_text()
278
+
279
+ for pattern, description in business_logic_patterns:
280
+ if pattern.search(content):
281
+ results.append(ValidationResult(
282
+ passed=False,
283
+ message=f"Route file contains business logic: {description}",
284
+ file_path=str(rel_path),
285
+ suggestion="Move business logic to features/ directory"
286
+ ))
287
+ break # Only report first violation per file
288
+
289
+ except Exception as e:
290
+ pass # Skip files we can't read
291
+
292
+ return results
293
+
294
+
295
+ def validate_naming_conventions(root: Path) -> List[ValidationResult]:
296
+ """Validate file and directory naming conventions."""
297
+ results = []
298
+
299
+ # Feature directory names should be kebab-case
300
+ features_dir = root / 'features'
301
+ if features_dir.exists():
302
+ kebab_pattern = re.compile(r'^[a-z][a-z0-9]*(-[a-z0-9]+)*$')
303
+ for item in features_dir.iterdir():
304
+ if item.is_dir() and not item.name.startswith('.'):
305
+ if not kebab_pattern.match(item.name):
306
+ results.append(ValidationResult(
307
+ passed=False,
308
+ message=f"Feature directory not in kebab-case",
309
+ file_path=f"features/{item.name}",
310
+ suggestion=f"Rename to kebab-case (e.g., 'my-feature')"
311
+ ))
312
+
313
+ # Component directories should be PascalCase
314
+ pascal_pattern = re.compile(r'^[A-Z][a-zA-Z0-9]*$')
315
+
316
+ def check_component_dirs(base_dir: Path, dir_type: str):
317
+ if not base_dir.exists():
318
+ return
319
+ for item in base_dir.iterdir():
320
+ if item.is_dir() and not item.name.startswith('_'):
321
+ if not pascal_pattern.match(item.name):
322
+ rel_path = item.relative_to(root)
323
+ results.append(ValidationResult(
324
+ passed=False,
325
+ message=f"{dir_type} directory not in PascalCase",
326
+ file_path=str(rel_path),
327
+ suggestion=f"Rename to PascalCase (e.g., 'MyComponent')"
328
+ ))
329
+
330
+ # Check components directory (skip special subdirectories)
331
+ components_dir = root / 'components'
332
+ if components_dir.exists():
333
+ for item in components_dir.iterdir():
334
+ # Skip special directories that are allowed to be lowercase
335
+ if item.name in {'ui', 'icons', 'custom', 'shared'}:
336
+ continue
337
+ if item.is_dir() and not item.name.startswith('_'):
338
+ if not pascal_pattern.match(item.name):
339
+ rel_path = item.relative_to(root)
340
+ results.append(ValidationResult(
341
+ passed=False,
342
+ message=f"Component directory not in PascalCase",
343
+ file_path=str(rel_path),
344
+ suggestion=f"Rename to PascalCase (e.g., 'MyComponent')"
345
+ ))
346
+
347
+ # Check feature components and screens
348
+ if features_dir.exists():
349
+ for feature in features_dir.iterdir():
350
+ if feature.is_dir():
351
+ check_component_dirs(feature / 'components', 'Component')
352
+ check_component_dirs(feature / 'screens', 'Screen')
353
+
354
+ return results
355
+
356
+
357
+ def run_validation(path: Path) -> ValidationReport:
358
+ """Run all validations and return a report."""
359
+ report = ValidationReport()
360
+ root = find_project_root(path)
361
+
362
+ print(f"Validating directory structure from: {root}\n")
363
+
364
+ # Run all validations
365
+ report.errors.extend(validate_test_file_placement(root))
366
+ report.errors.extend(validate_naming_conventions(root))
367
+ report.errors.extend(validate_app_directory(root / 'app', root))
368
+
369
+ # Validate features
370
+ features_dir = root / 'features'
371
+ if features_dir.exists():
372
+ for feature in features_dir.iterdir():
373
+ if feature.is_dir() and not feature.name.startswith('.'):
374
+ report.errors.extend(validate_feature_structure(feature, root))
375
+
376
+ # Validate global components
377
+ components_dir = root / 'components'
378
+ if components_dir.exists():
379
+ for item in components_dir.iterdir():
380
+ # Skip ui/, icons/, custom/ as they have different structure
381
+ if item.name in {'ui', 'icons', 'custom', 'shared'}:
382
+ continue
383
+ if item.is_dir() and not item.name.startswith('_'):
384
+ report.errors.extend(validate_component_structure(item, root))
385
+
386
+ return report
387
+
388
+
389
+ def print_report(report: ValidationReport) -> None:
390
+ """Print the validation report."""
391
+ if report.errors:
392
+ print("=" * 60)
393
+ print(f"ERRORS ({len(report.errors)})")
394
+ print("=" * 60)
395
+ for result in report.errors:
396
+ print(f"\n❌ {result.message}")
397
+ if result.file_path:
398
+ print(f" File: {result.file_path}")
399
+ if result.suggestion:
400
+ print(f" Fix: {result.suggestion}")
401
+
402
+ if report.warnings:
403
+ print("\n" + "=" * 60)
404
+ print(f"WARNINGS ({len(report.warnings)})")
405
+ print("=" * 60)
406
+ for result in report.warnings:
407
+ print(f"\n⚠️ {result.message}")
408
+ if result.file_path:
409
+ print(f" File: {result.file_path}")
410
+ if result.suggestion:
411
+ print(f" Fix: {result.suggestion}")
412
+
413
+ print("\n" + "=" * 60)
414
+ print("SUMMARY")
415
+ print("=" * 60)
416
+ print(f"Errors: {len(report.errors)}")
417
+ print(f"Warnings: {len(report.warnings)}")
418
+
419
+ if not report.has_errors and not report.has_warnings:
420
+ print("\n✅ All directory structure validations passed!")
421
+ elif report.has_errors:
422
+ print("\n❌ Validation failed with errors")
423
+ else:
424
+ print("\n⚠️ Validation passed with warnings")
425
+
426
+
427
+ def main():
428
+ """Main entry point."""
429
+ path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.cwd()
430
+
431
+ if not path.exists():
432
+ print(f"Error: Path does not exist: {path}")
433
+ sys.exit(1)
434
+
435
+ report = run_validation(path)
436
+ print_report(report)
437
+
438
+ # Exit with error code if there are errors
439
+ sys.exit(1 if report.has_errors else 0)
440
+
441
+
442
+ if __name__ == '__main__':
443
+ main()