@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,300 @@
1
+ # Spacing Scale Reference
2
+
3
+ This reference provides the complete spacing scale for NativeWind/Tailwind CSS. Use only these values for consistent, maintainable layouts.
4
+
5
+ ## Standard Spacing Scale
6
+
7
+ | Class Suffix | Pixels | Rem | Usage |
8
+ | ------------ | ------ | -------- | -------------------------------- |
9
+ | `0` | 0px | 0rem | Reset spacing |
10
+ | `px` | 1px | - | Hairline borders, minimal offset |
11
+ | `0.5` | 2px | 0.125rem | Micro spacing |
12
+ | `1` | 4px | 0.25rem | Tight spacing |
13
+ | `1.5` | 6px | 0.375rem | Compact spacing |
14
+ | `2` | 8px | 0.5rem | Small spacing |
15
+ | `2.5` | 10px | 0.625rem | Small-medium spacing |
16
+ | `3` | 12px | 0.75rem | Medium-small spacing |
17
+ | `3.5` | 14px | 0.875rem | Medium spacing |
18
+ | `4` | 16px | 1rem | **Default** - standard spacing |
19
+ | `5` | 20px | 1.25rem | Medium-large spacing |
20
+ | `6` | 24px | 1.5rem | Large spacing |
21
+ | `7` | 28px | 1.75rem | Large+ spacing |
22
+ | `8` | 32px | 2rem | Extra large spacing |
23
+ | `9` | 36px | 2.25rem | XL spacing |
24
+ | `10` | 40px | 2.5rem | XXL spacing |
25
+ | `11` | 44px | 2.75rem | Touch target minimum |
26
+ | `12` | 48px | 3rem | Section spacing |
27
+ | `14` | 56px | 3.5rem | Large section spacing |
28
+ | `16` | 64px | 4rem | Major section spacing |
29
+ | `20` | 80px | 5rem | Page section spacing |
30
+ | `24` | 96px | 6rem | Hero spacing |
31
+ | `28` | 112px | 7rem | Extra hero spacing |
32
+ | `32` | 128px | 8rem | Maximum spacing |
33
+ | `36` | 144px | 9rem | Oversized spacing |
34
+ | `40` | 160px | 10rem | Oversized spacing |
35
+ | `44` | 176px | 11rem | Oversized spacing |
36
+ | `48` | 192px | 12rem | Oversized spacing |
37
+ | `52` | 208px | 13rem | Oversized spacing |
38
+ | `56` | 224px | 14rem | Oversized spacing |
39
+ | `60` | 240px | 15rem | Oversized spacing |
40
+ | `64` | 256px | 16rem | Oversized spacing |
41
+ | `72` | 288px | 18rem | Oversized spacing |
42
+ | `80` | 320px | 20rem | Oversized spacing |
43
+ | `96` | 384px | 24rem | Maximum oversized |
44
+
45
+ ## Spacing Properties
46
+
47
+ ### Padding
48
+
49
+ | Property | Classes |
50
+ | ----------------- | ------------ |
51
+ | All sides | `p-{scale}` |
52
+ | Horizontal | `px-{scale}` |
53
+ | Vertical | `py-{scale}` |
54
+ | Top | `pt-{scale}` |
55
+ | Right | `pr-{scale}` |
56
+ | Bottom | `pb-{scale}` |
57
+ | Left | `pl-{scale}` |
58
+ | Start (RTL-aware) | `ps-{scale}` |
59
+ | End (RTL-aware) | `pe-{scale}` |
60
+
61
+ ```tsx
62
+ // Uniform padding
63
+ <Box className="p-4" /> // 16px all sides
64
+
65
+ // Horizontal and vertical
66
+ <Box className="px-6 py-4" /> // 24px horizontal, 16px vertical
67
+
68
+ // Individual sides
69
+ <Box className="pt-2 pr-4 pb-6 pl-4" />
70
+ ```
71
+
72
+ ### Margin
73
+
74
+ | Property | Classes |
75
+ | ----------------- | ------------------------------------ |
76
+ | All sides | `m-{scale}` |
77
+ | Horizontal | `mx-{scale}` |
78
+ | Vertical | `my-{scale}` |
79
+ | Top | `mt-{scale}` |
80
+ | Right | `mr-{scale}` |
81
+ | Bottom | `mb-{scale}` |
82
+ | Left | `ml-{scale}` |
83
+ | Start (RTL-aware) | `ms-{scale}` |
84
+ | End (RTL-aware) | `me-{scale}` |
85
+ | Auto | `m-auto`, `mx-auto`, `my-auto`, etc. |
86
+
87
+ ```tsx
88
+ // Centered horizontally
89
+ <Box className="mx-auto" />
90
+
91
+ // Stack spacing
92
+ <Box className="mb-4" /> // 16px bottom margin
93
+
94
+ // Negative margin (use sparingly)
95
+ <Box className="-mt-2" /> // -8px top margin
96
+ ```
97
+
98
+ ### Gap (Flexbox/Grid)
99
+
100
+ | Property | Classes |
101
+ | ---------- | --------------- |
102
+ | Both axes | `gap-{scale}` |
103
+ | Row gap | `gap-y-{scale}` |
104
+ | Column gap | `gap-x-{scale}` |
105
+
106
+ ```tsx
107
+ // Uniform gap in flex container
108
+ <Box className="flex flex-row gap-4">
109
+ <Item />
110
+ <Item />
111
+ <Item />
112
+ </Box>
113
+
114
+ // Grid with different gaps
115
+ <Box className="grid grid-cols-3 gap-x-6 gap-y-4">
116
+ <Item />
117
+ <Item />
118
+ <Item />
119
+ </Box>
120
+ ```
121
+
122
+ ### Space Between (Legacy Alternative)
123
+
124
+ Use `gap-*` instead when possible, but `space-*` is available:
125
+
126
+ | Property | Classes |
127
+ | ---------- | ----------------- |
128
+ | Horizontal | `space-x-{scale}` |
129
+ | Vertical | `space-y-{scale}` |
130
+
131
+ ```tsx
132
+ // Vertical stack with space between
133
+ <Box className="flex flex-col space-y-4">
134
+ <Item />
135
+ <Item />
136
+ </Box>
137
+ ```
138
+
139
+ ## Common Spacing Patterns
140
+
141
+ ### Card Padding
142
+
143
+ ```tsx
144
+ // Compact card
145
+ <Box className="p-3" /> // 12px
146
+
147
+ // Standard card
148
+ <Box className="p-4" /> // 16px
149
+
150
+ // Spacious card
151
+ <Box className="p-6" /> // 24px
152
+ ```
153
+
154
+ ### List Item Spacing
155
+
156
+ ```tsx
157
+ // Tight list
158
+ <Box className="py-2 px-3" /> // 8px vertical, 12px horizontal
159
+
160
+ // Standard list
161
+ <Box className="py-3 px-4" /> // 12px vertical, 16px horizontal
162
+
163
+ // Spacious list
164
+ <Box className="py-4 px-6" /> // 16px vertical, 24px horizontal
165
+ ```
166
+
167
+ ### Section Spacing
168
+
169
+ ```tsx
170
+ // Between sections
171
+ <Box className="my-8" /> // 32px vertical margin
172
+
173
+ // Page sections
174
+ <Box className="py-12" /> // 48px vertical padding
175
+
176
+ // Hero sections
177
+ <Box className="py-16" /> // 64px vertical padding
178
+ ```
179
+
180
+ ### Button Padding
181
+
182
+ ```tsx
183
+ // Small button
184
+ <Button className="px-3 py-1.5" /> // 12px horizontal, 6px vertical
185
+
186
+ // Medium button
187
+ <Button className="px-4 py-2" /> // 16px horizontal, 8px vertical
188
+
189
+ // Large button
190
+ <Button className="px-6 py-3" /> // 24px horizontal, 12px vertical
191
+ ```
192
+
193
+ ### Form Field Spacing
194
+
195
+ ```tsx
196
+ // Form field group
197
+ <Box className="space-y-4"> // 16px between fields
198
+ <Input />
199
+ <Input />
200
+ <Button />
201
+ </Box>
202
+
203
+ // Form section
204
+ <Box className="space-y-6"> // 24px between sections
205
+ <FormSection />
206
+ <FormSection />
207
+ </Box>
208
+ ```
209
+
210
+ ### Touch Targets
211
+
212
+ Minimum touch target size is 44x44px (11 spacing units):
213
+
214
+ ```tsx
215
+ // Icon button with minimum touch target
216
+ <Pressable className="h-11 w-11 items-center justify-center">
217
+ <Icon />
218
+ </Pressable>
219
+
220
+ // Touch target with padding
221
+ <Pressable className="p-3"> // At least 12px padding
222
+ <Text>Tappable</Text>
223
+ </Pressable>
224
+ ```
225
+
226
+ ## Prohibited Patterns
227
+
228
+ ### Arbitrary Values
229
+
230
+ Never use bracket notation for spacing:
231
+
232
+ ```tsx
233
+ // WRONG
234
+ <Box className="p-[13px]" />
235
+ <Box className="m-[27px]" />
236
+ <Box className="gap-[15px]" />
237
+
238
+ // CORRECT - use nearest scale value
239
+ <Box className="p-3" /> // 12px instead of 13px
240
+ <Box className="m-7" /> // 28px instead of 27px
241
+ <Box className="gap-4" /> // 16px instead of 15px
242
+ ```
243
+
244
+ ### Inline Style Spacing
245
+
246
+ Never use inline styles for spacing:
247
+
248
+ ```tsx
249
+ // WRONG
250
+ <Box style={{ padding: 13 }} />
251
+ <Box style={{ marginTop: 27 }} />
252
+
253
+ // CORRECT
254
+ <Box className="p-3" />
255
+ <Box className="mt-7" />
256
+ ```
257
+
258
+ ### Non-Scale Decimals
259
+
260
+ Only use defined decimal values:
261
+
262
+ ```tsx
263
+ // WRONG
264
+ <Box className="p-2.7" />
265
+ <Box className="m-4.3" />
266
+
267
+ // CORRECT - allowed decimals: 0.5, 1.5, 2.5, 3.5
268
+ <Box className="p-2.5" />
269
+ <Box className="m-4" />
270
+ ```
271
+
272
+ ## Responsive Spacing
273
+
274
+ Apply different spacing at breakpoints:
275
+
276
+ ```tsx
277
+ // Smaller padding on mobile, larger on desktop
278
+ <Box className="p-4 md:p-6 lg:p-8" />
279
+
280
+ // Responsive gap
281
+ <Box className="gap-2 md:gap-4 lg:gap-6" />
282
+
283
+ // Responsive margin
284
+ <Box className="mt-4 md:mt-8 lg:mt-12" />
285
+ ```
286
+
287
+ ## Spacing Decision Guide
288
+
289
+ | Context | Recommended Values |
290
+ | ----------------- | -------------------------------- |
291
+ | Icon spacing | `1`, `1.5`, `2` |
292
+ | Text line spacing | `1`, `2`, `3` |
293
+ | Button padding | `2-3` vertical, `3-6` horizontal |
294
+ | Card padding | `3`, `4`, `6` |
295
+ | List item padding | `2-4` vertical, `3-4` horizontal |
296
+ | Section spacing | `6`, `8`, `12`, `16` |
297
+ | Page margins | `4`, `6`, `8` |
298
+ | Modal padding | `4`, `6` |
299
+ | Form field gap | `3`, `4` |
300
+ | Touch targets | minimum `11` (44px) |
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Validates Gluestack UI v3 and NativeWind v4 styling patterns.
4
+
5
+ This script detects common styling violations:
6
+ 1. Direct React Native imports with Gluestack equivalents
7
+ 2. Raw color values without semantic tokens
8
+ 3. Inline style objects where className could be used
9
+ 4. Arbitrary bracket notation values
10
+ 5. Non-scale spacing values
11
+
12
+ Usage:
13
+ python3 validate_styling.py [path]
14
+
15
+ Arguments:
16
+ path Optional path to validate. Defaults to current directory.
17
+ Can be a file or directory.
18
+ """
19
+
20
+ import os
21
+ import re
22
+ import sys
23
+ from dataclasses import dataclass
24
+ from pathlib import Path
25
+ from typing import Optional
26
+
27
+
28
+ @dataclass
29
+ class Violation:
30
+ """Represents a styling violation."""
31
+ file: str
32
+ line: int
33
+ rule: str
34
+ message: str
35
+ severity: str = "error"
36
+
37
+
38
+ # React Native components that have Gluestack equivalents
39
+ RN_TO_GLUESTACK_MAP = {
40
+ "View": "Box",
41
+ "Text": "Text (from @/components/ui/text)",
42
+ "TouchableOpacity": "Pressable",
43
+ "TouchableHighlight": "Pressable",
44
+ "TouchableWithoutFeedback": "Pressable",
45
+ "Image": "Image (from @/components/ui/image)",
46
+ "ScrollView": "ScrollView (from @/components/ui/scroll-view)",
47
+ "TextInput": "Input + InputField",
48
+ "FlatList": "FlashList",
49
+ "SectionList": "FlashList",
50
+ "ActivityIndicator": "Spinner",
51
+ "Modal": "Modal (from @/components/ui/modal)",
52
+ }
53
+
54
+ # Raw colors that should be semantic tokens
55
+ RAW_COLOR_PATTERNS = [
56
+ # Tailwind raw colors (red, green, blue, yellow, gray, etc.)
57
+ r'\b(text|bg|border|ring|fill|stroke)-(red|green|blue|yellow|orange|purple|pink|indigo|cyan|teal|emerald|lime|amber|violet|fuchsia|rose|sky|slate|gray|zinc|neutral|stone)-\d{2,3}\b',
58
+ # White/black that should be typography-0 or typography-950
59
+ r'\btext-white\b',
60
+ r'\btext-black\b',
61
+ r'\bbg-white\b',
62
+ r'\bbg-black\b',
63
+ ]
64
+
65
+ # Semantic tokens that ARE allowed
66
+ ALLOWED_SEMANTIC_PATTERNS = [
67
+ r'\b(text|bg|border|ring)-(primary|secondary|tertiary|error|success|warning|info|typography|outline|background|indicator)-',
68
+ ]
69
+
70
+ # Arbitrary value patterns (bracket notation)
71
+ ARBITRARY_VALUE_PATTERNS = [
72
+ r'\b[a-z]+-\[\d+px\]', # p-[13px], m-[27px]
73
+ r'\b[a-z]+-\[\d+rem\]', # p-[1.3rem]
74
+ r'\b[a-z]+-\[\d+%\]', # w-[50%] (sometimes acceptable)
75
+ r'\bgap-\[\d+', # gap-[15px]
76
+ r'\bspace-[xy]-\[\d+', # space-x-[10px]
77
+ ]
78
+
79
+ # Non-standard spacing values (not in Tailwind scale)
80
+ # Valid values: 0, px, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
81
+ VALID_SPACING_VALUES = {
82
+ "0", "px", "0.5", "1", "1.5", "2", "2.5", "3", "3.5", "4", "5", "6",
83
+ "7", "8", "9", "10", "11", "12", "14", "16", "20", "24", "28", "32",
84
+ "36", "40", "44", "48", "52", "56", "60", "64", "72", "80", "96"
85
+ }
86
+
87
+ # Inline style patterns that could be className
88
+ INLINE_STYLE_PATTERNS = [
89
+ r'style=\{\{[^}]*backgroundColor\s*:',
90
+ r'style=\{\{[^}]*color\s*:',
91
+ r'style=\{\{[^}]*padding\s*:',
92
+ r'style=\{\{[^}]*margin\s*:',
93
+ r'style=\{\{[^}]*borderRadius\s*:',
94
+ r'style=\{\{[^}]*borderColor\s*:',
95
+ r'style=\{\{[^}]*borderWidth\s*:',
96
+ ]
97
+
98
+ # Exceptions - files/patterns to skip
99
+ SKIP_PATTERNS = [
100
+ r'node_modules',
101
+ r'\.test\.',
102
+ r'\.spec\.',
103
+ r'__tests__',
104
+ r'components/ui/', # UI primitives are allowed to use any styling
105
+ r'\.d\.ts$',
106
+ r'tailwind\.config',
107
+ r'\.config\.',
108
+ ]
109
+
110
+
111
+ def should_skip_file(file_path: str) -> bool:
112
+ """Check if file should be skipped."""
113
+ for pattern in SKIP_PATTERNS:
114
+ if re.search(pattern, file_path):
115
+ return True
116
+ return False
117
+
118
+
119
+ def is_semantic_color(match: str) -> bool:
120
+ """Check if a color class uses semantic tokens."""
121
+ for pattern in ALLOWED_SEMANTIC_PATTERNS:
122
+ if re.search(pattern, match):
123
+ return True
124
+ return False
125
+
126
+
127
+ def check_rn_imports(content: str, file_path: str) -> list[Violation]:
128
+ """Check for React Native imports that should be Gluestack."""
129
+ violations = []
130
+ lines = content.split('\n')
131
+
132
+ for i, line in enumerate(lines, 1):
133
+ # Check for import from react-native
134
+ if 'from "react-native"' in line or "from 'react-native'" in line:
135
+ for rn_component, gluestack_equiv in RN_TO_GLUESTACK_MAP.items():
136
+ # Check if component is imported
137
+ if re.search(rf'\b{rn_component}\b', line):
138
+ violations.append(Violation(
139
+ file=file_path,
140
+ line=i,
141
+ rule="gluestack-components",
142
+ message=f"Use Gluestack '{gluestack_equiv}' instead of React Native '{rn_component}'",
143
+ ))
144
+
145
+ return violations
146
+
147
+
148
+ def check_raw_colors(content: str, file_path: str) -> list[Violation]:
149
+ """Check for raw color values instead of semantic tokens."""
150
+ violations = []
151
+ lines = content.split('\n')
152
+
153
+ for i, line in enumerate(lines, 1):
154
+ # Skip comments
155
+ if line.strip().startswith('//') or line.strip().startswith('*'):
156
+ continue
157
+
158
+ for pattern in RAW_COLOR_PATTERNS:
159
+ matches = re.findall(pattern, line)
160
+ for match in matches:
161
+ if isinstance(match, tuple):
162
+ match = '-'.join(match)
163
+ if not is_semantic_color(match):
164
+ violations.append(Violation(
165
+ file=file_path,
166
+ line=i,
167
+ rule="semantic-tokens",
168
+ message=f"Use semantic color token instead of raw color '{match}'",
169
+ ))
170
+
171
+ return violations
172
+
173
+
174
+ def check_arbitrary_values(content: str, file_path: str) -> list[Violation]:
175
+ """Check for arbitrary bracket notation values."""
176
+ violations = []
177
+ lines = content.split('\n')
178
+
179
+ for i, line in enumerate(lines, 1):
180
+ # Skip comments
181
+ if line.strip().startswith('//') or line.strip().startswith('*'):
182
+ continue
183
+
184
+ for pattern in ARBITRARY_VALUE_PATTERNS:
185
+ matches = re.findall(pattern, line)
186
+ for match in matches:
187
+ violations.append(Violation(
188
+ file=file_path,
189
+ line=i,
190
+ rule="no-arbitrary-values",
191
+ message=f"Avoid arbitrary values '{match}'. Use spacing scale instead.",
192
+ severity="warning",
193
+ ))
194
+
195
+ return violations
196
+
197
+
198
+ def check_inline_styles(content: str, file_path: str) -> list[Violation]:
199
+ """Check for inline styles that could be className."""
200
+ violations = []
201
+ lines = content.split('\n')
202
+
203
+ for i, line in enumerate(lines, 1):
204
+ # Skip comments
205
+ if line.strip().startswith('//') or line.strip().startswith('*'):
206
+ continue
207
+
208
+ for pattern in INLINE_STYLE_PATTERNS:
209
+ if re.search(pattern, line):
210
+ # Check for exceptions (dynamic values, animations)
211
+ if 'bottomInset' in line or 'Animated' in line or 'animatedValue' in line:
212
+ continue
213
+ if 'Platform.select' in line or 'Platform.OS' in line:
214
+ continue
215
+
216
+ violations.append(Violation(
217
+ file=file_path,
218
+ line=i,
219
+ rule="no-inline-styles",
220
+ message="Prefer className over inline style for static styling",
221
+ severity="warning",
222
+ ))
223
+
224
+ return violations
225
+
226
+
227
+ def check_non_scale_spacing(content: str, file_path: str) -> list[Violation]:
228
+ """Check for spacing values not in the standard scale."""
229
+ violations = []
230
+ lines = content.split('\n')
231
+
232
+ # Pattern to match spacing classes: p-X, m-X, gap-X, etc.
233
+ spacing_pattern = r'\b(p|px|py|pt|pr|pb|pl|ps|pe|m|mx|my|mt|mr|mb|ml|ms|me|gap|gap-x|gap-y|space-x|space-y)-(\d+\.?\d*)\b'
234
+
235
+ for i, line in enumerate(lines, 1):
236
+ # Skip comments
237
+ if line.strip().startswith('//') or line.strip().startswith('*'):
238
+ continue
239
+
240
+ matches = re.findall(spacing_pattern, line)
241
+ for prefix, value in matches:
242
+ if value not in VALID_SPACING_VALUES:
243
+ violations.append(Violation(
244
+ file=file_path,
245
+ line=i,
246
+ rule="spacing-scale",
247
+ message=f"Spacing value '{value}' is not in the standard scale. Use a valid value: {', '.join(sorted(VALID_SPACING_VALUES, key=lambda x: float(x) if x != 'px' else 0.1))}",
248
+ severity="warning",
249
+ ))
250
+
251
+ return violations
252
+
253
+
254
+ def validate_file(file_path: str) -> list[Violation]:
255
+ """Validate a single file for styling violations."""
256
+ if should_skip_file(file_path):
257
+ return []
258
+
259
+ # Only check TypeScript/JavaScript files
260
+ if not file_path.endswith(('.tsx', '.ts', '.jsx', '.js')):
261
+ return []
262
+
263
+ try:
264
+ with open(file_path, 'r', encoding='utf-8') as f:
265
+ content = f.read()
266
+ except (IOError, UnicodeDecodeError):
267
+ return []
268
+
269
+ violations = []
270
+ violations.extend(check_rn_imports(content, file_path))
271
+ violations.extend(check_raw_colors(content, file_path))
272
+ violations.extend(check_arbitrary_values(content, file_path))
273
+ violations.extend(check_inline_styles(content, file_path))
274
+ violations.extend(check_non_scale_spacing(content, file_path))
275
+
276
+ return violations
277
+
278
+
279
+ def validate_directory(directory: str) -> list[Violation]:
280
+ """Validate all files in a directory recursively."""
281
+ violations = []
282
+
283
+ for root, dirs, files in os.walk(directory):
284
+ # Skip node_modules and other excluded directories
285
+ dirs[:] = [d for d in dirs if not should_skip_file(os.path.join(root, d))]
286
+
287
+ for file in files:
288
+ file_path = os.path.join(root, file)
289
+ violations.extend(validate_file(file_path))
290
+
291
+ return violations
292
+
293
+
294
+ def format_violation(violation: Violation) -> str:
295
+ """Format a violation for display."""
296
+ severity_icon = "āŒ" if violation.severity == "error" else "āš ļø"
297
+ return f"{severity_icon} {violation.file}:{violation.line} [{violation.rule}] {violation.message}"
298
+
299
+
300
+ def main():
301
+ """Main entry point."""
302
+ # Get path from command line or use current directory
303
+ path = sys.argv[1] if len(sys.argv) > 1 else "."
304
+
305
+ # Resolve to absolute path
306
+ path = os.path.abspath(path)
307
+
308
+ if not os.path.exists(path):
309
+ print(f"āŒ Path not found: {path}")
310
+ sys.exit(1)
311
+
312
+ print(f"šŸ” Validating styling patterns in: {path}\n")
313
+
314
+ # Validate
315
+ if os.path.isfile(path):
316
+ violations = validate_file(path)
317
+ else:
318
+ violations = validate_directory(path)
319
+
320
+ # Report results
321
+ if not violations:
322
+ print("āœ… No styling violations found!")
323
+ sys.exit(0)
324
+
325
+ # Group by file
326
+ by_file: dict[str, list[Violation]] = {}
327
+ for v in violations:
328
+ if v.file not in by_file:
329
+ by_file[v.file] = []
330
+ by_file[v.file].append(v)
331
+
332
+ # Print violations
333
+ error_count = 0
334
+ warning_count = 0
335
+
336
+ for file_path, file_violations in sorted(by_file.items()):
337
+ print(f"\nšŸ“„ {file_path}")
338
+ for v in sorted(file_violations, key=lambda x: x.line):
339
+ print(f" {format_violation(v)}")
340
+ if v.severity == "error":
341
+ error_count += 1
342
+ else:
343
+ warning_count += 1
344
+
345
+ print(f"\nšŸ“Š Summary: {error_count} errors, {warning_count} warnings")
346
+
347
+ # Exit with error if there are errors
348
+ if error_count > 0:
349
+ sys.exit(1)
350
+ sys.exit(0)
351
+
352
+
353
+ if __name__ == "__main__":
354
+ main()