@codyswann/lisa 1.47.1 → 1.48.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 (210) hide show
  1. package/all/copy-overwrite/.claude/rules/lisa.md +23 -10
  2. package/all/copy-overwrite/.claude/settings.json +10 -252
  3. package/all/deletions.json +67 -1
  4. package/cdk/copy-overwrite/.claude/settings.json +80 -0
  5. package/cdk/create-only/.github/workflows/ci.yml +1 -1
  6. package/cdk/create-only/.github/workflows/deploy.yml +1 -1
  7. package/dist/core/lisa.d.ts +14 -0
  8. package/dist/core/lisa.d.ts.map +1 -1
  9. package/dist/core/lisa.js +47 -0
  10. package/dist/core/lisa.js.map +1 -1
  11. package/expo/copy-overwrite/.claude/settings.json +80 -0
  12. package/expo/copy-overwrite/eslint.expo.ts +2 -2
  13. package/expo/create-only/.github/workflows/ci.yml +1 -1
  14. package/expo/create-only/.github/workflows/deploy.yml +1 -1
  15. package/expo/deletions.json +33 -0
  16. package/expo/package-lisa/package.lisa.json +2 -2
  17. package/nestjs/copy-overwrite/.claude/settings.json +80 -0
  18. package/nestjs/create-only/.github/workflows/ci.yml +1 -1
  19. package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
  20. package/nestjs/deletions.json +8 -0
  21. package/package.json +8 -4
  22. package/rails/copy-overwrite/.claude/settings.json +80 -0
  23. package/rails/create-only/.github/workflows/ci.yml +1 -1
  24. package/rails/deletions.json +11 -1
  25. package/typescript/copy-overwrite/.claude/settings.json +13 -253
  26. package/typescript/copy-overwrite/eslint.typescript.ts +1 -1
  27. package/typescript/create-only/.github/workflows/ci.yml +1 -1
  28. package/typescript/deletions.json +12 -1
  29. package/typescript/package-lisa/package.lisa.json +1 -1
  30. package/all/copy-overwrite/.claude/agents/agent-architect.md +0 -310
  31. package/all/copy-overwrite/.claude/agents/architecture-specialist.md +0 -53
  32. package/all/copy-overwrite/.claude/agents/debug-specialist.md +0 -204
  33. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +0 -183
  34. package/all/copy-overwrite/.claude/agents/hooks-expert.md +0 -74
  35. package/all/copy-overwrite/.claude/agents/implementer.md +0 -54
  36. package/all/copy-overwrite/.claude/agents/learner.md +0 -44
  37. package/all/copy-overwrite/.claude/agents/performance-specialist.md +0 -95
  38. package/all/copy-overwrite/.claude/agents/product-specialist.md +0 -72
  39. package/all/copy-overwrite/.claude/agents/quality-specialist.md +0 -55
  40. package/all/copy-overwrite/.claude/agents/security-specialist.md +0 -58
  41. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +0 -246
  42. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +0 -87
  43. package/all/copy-overwrite/.claude/agents/test-specialist.md +0 -64
  44. package/all/copy-overwrite/.claude/agents/verification-specialist.md +0 -189
  45. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +0 -112
  46. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +0 -7
  47. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-and-verify.md +0 -7
  48. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-deploy-and-verify.md +0 -7
  49. package/all/copy-overwrite/.claude/commands/git/commit.md +0 -7
  50. package/all/copy-overwrite/.claude/commands/git/prune.md +0 -6
  51. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +0 -7
  52. package/all/copy-overwrite/.claude/commands/jira/create.md +0 -7
  53. package/all/copy-overwrite/.claude/commands/jira/sync.md +0 -7
  54. package/all/copy-overwrite/.claude/commands/jira/verify.md +0 -7
  55. package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +0 -7
  56. package/all/copy-overwrite/.claude/commands/plan/add-test-coverage.md +0 -7
  57. package/all/copy-overwrite/.claude/commands/plan/create.md +0 -6
  58. package/all/copy-overwrite/.claude/commands/plan/execute.md +0 -7
  59. package/all/copy-overwrite/.claude/commands/plan/fix-linter-error.md +0 -7
  60. package/all/copy-overwrite/.claude/commands/plan/local-code-review.md +0 -6
  61. package/all/copy-overwrite/.claude/commands/plan/lower-code-complexity.md +0 -6
  62. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines-per-function.md +0 -7
  63. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines.md +0 -7
  64. package/all/copy-overwrite/.claude/commands/pull-request/review.md +0 -7
  65. package/all/copy-overwrite/.claude/commands/security/zap-scan.md +0 -6
  66. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +0 -6
  67. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +0 -6
  68. package/all/copy-overwrite/.claude/commands/tasks/load.md +0 -7
  69. package/all/copy-overwrite/.claude/commands/tasks/sync.md +0 -7
  70. package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +0 -61
  71. package/all/copy-overwrite/.claude/hooks/debug-hook.sh +0 -47
  72. package/all/copy-overwrite/.claude/hooks/enforce-plan-rules.sh +0 -15
  73. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +0 -183
  74. package/all/copy-overwrite/.claude/hooks/setup-jira-cli.sh +0 -52
  75. package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +0 -107
  76. package/all/copy-overwrite/.claude/hooks/ticket-sync-reminder.sh +0 -23
  77. package/all/copy-overwrite/.claude/hooks/track-plan-sessions.sh +0 -164
  78. package/all/copy-overwrite/.claude/hooks/verify-completion.sh +0 -77
  79. package/all/copy-overwrite/.claude/rules/coding-philosophy.md +0 -428
  80. package/all/copy-overwrite/.claude/rules/verfication.md +0 -596
  81. package/all/copy-overwrite/.claude/skills/agent-design-best-practices/SKILL.md +0 -219
  82. package/all/copy-overwrite/.claude/skills/git-commit/SKILL.md +0 -48
  83. package/all/copy-overwrite/.claude/skills/git-commit-and-submit-pr/SKILL.md +0 -8
  84. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-and-verify/SKILL.md +0 -7
  85. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-deploy-and-verify/SKILL.md +0 -7
  86. package/all/copy-overwrite/.claude/skills/git-prune/SKILL.md +0 -35
  87. package/all/copy-overwrite/.claude/skills/git-submit-pr/SKILL.md +0 -44
  88. package/all/copy-overwrite/.claude/skills/jira-create/SKILL.md +0 -41
  89. package/all/copy-overwrite/.claude/skills/jira-sync/SKILL.md +0 -63
  90. package/all/copy-overwrite/.claude/skills/jira-verify/SKILL.md +0 -29
  91. package/all/copy-overwrite/.claude/skills/lisa-review-implementation/SKILL.md +0 -209
  92. package/all/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -44
  93. package/all/copy-overwrite/.claude/skills/plan-execute/SKILL.md +0 -89
  94. package/all/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  95. package/all/copy-overwrite/.claude/skills/plan-local-code-review/SKILL.md +0 -88
  96. package/all/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -44
  97. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -45
  98. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  99. package/all/copy-overwrite/.claude/skills/pull-request-review/SKILL.md +0 -68
  100. package/all/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  101. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +0 -202
  102. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +0 -210
  103. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  104. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +0 -305
  105. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +0 -112
  106. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +0 -67
  107. package/all/copy-overwrite/.claude/skills/sonarqube-check/SKILL.md +0 -11
  108. package/all/copy-overwrite/.claude/skills/sonarqube-fix/SKILL.md +0 -8
  109. package/all/copy-overwrite/.claude/skills/tasks-load/SKILL.md +0 -88
  110. package/all/copy-overwrite/.claude/skills/tasks-sync/SKILL.md +0 -108
  111. package/eslint-plugin-code-organization/README.md +0 -149
  112. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  113. package/eslint-plugin-code-organization/index.js +0 -28
  114. package/eslint-plugin-code-organization/package.json +0 -10
  115. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
  116. package/expo/copy-overwrite/.claude/agents/ops-specialist.md +0 -124
  117. package/expo/copy-overwrite/.claude/rules/expo-verification.md +0 -261
  118. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +0 -238
  119. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +0 -360
  120. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +0 -360
  121. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +0 -417
  122. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +0 -257
  123. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +0 -233
  124. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +0 -329
  125. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +0 -299
  126. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +0 -749
  127. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +0 -318
  128. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +0 -200
  129. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +0 -209
  130. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +0 -268
  131. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +0 -619
  132. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +0 -340
  133. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +0 -276
  134. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +0 -416
  135. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +0 -202
  136. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +0 -445
  137. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +0 -309
  138. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +0 -417
  139. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +0 -431
  140. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +0 -290
  141. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +0 -171
  142. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +0 -411
  143. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +0 -343
  144. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +0 -307
  145. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +0 -300
  146. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +0 -315
  147. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +0 -362
  148. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +0 -505
  149. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +0 -711
  150. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +0 -446
  151. package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +0 -124
  152. package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +0 -211
  153. package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +0 -119
  154. package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +0 -119
  155. package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +0 -99
  156. package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +0 -165
  157. package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +0 -166
  158. package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +0 -101
  159. package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +0 -56
  160. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +0 -223
  161. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +0 -314
  162. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +0 -420
  163. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +0 -556
  164. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +0 -590
  165. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +0 -291
  166. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +0 -234
  167. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +0 -89
  168. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +0 -201
  169. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +0 -294
  170. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +0 -37
  171. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +0 -10
  172. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +0 -235
  173. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +0 -96
  174. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +0 -183
  175. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +0 -243
  176. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -192
  177. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +0 -31
  178. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +0 -10
  179. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +0 -56
  180. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +0 -60
  181. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +0 -176
  182. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +0 -527
  183. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +0 -483
  184. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +0 -257
  185. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +0 -413
  186. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +0 -513
  187. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +0 -536
  188. package/nestjs/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  189. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +0 -275
  190. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +0 -487
  191. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +0 -450
  192. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +0 -536
  193. package/rails/copy-overwrite/.claude/skills/action-controller-best-practices/SKILL.md +0 -374
  194. package/rails/copy-overwrite/.claude/skills/action-view-best-practices/SKILL.md +0 -335
  195. package/rails/copy-overwrite/.claude/skills/active-record-model-best-practices/SKILL.md +0 -166
  196. package/rails/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -45
  197. package/rails/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  198. package/rails/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -48
  199. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -46
  200. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  201. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +0 -76
  202. package/typescript/copy-overwrite/.claude/hooks/install-pkgs.sh +0 -64
  203. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +0 -81
  204. package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +0 -68
  205. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +0 -432
  206. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +0 -149
  207. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  208. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +0 -28
  209. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +0 -10
  210. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
@@ -1,428 +0,0 @@
1
- # Coding Philosophy
2
-
3
- This rule enforces the core coding philosophy: **immutability**, **predictable structure**, **functional transformations**, **test-driven development**, **clean deletion**, and **simplicity**.
4
-
5
- ## Guiding Principles: YAGNI + SOLID + DRY + KISS
6
-
7
- Follow these software engineering principles, **deferring to Occam's Razor/KISS whenever principles conflict**:
8
-
9
- ### KISS (Keep It Simple, Stupid) - The Tiebreaker
10
-
11
- When principles conflict, **always choose the simpler solution**.
12
-
13
- ```typescript
14
- // KISS: Simple direct approach
15
- const isAdmin = user.role === "admin";
16
-
17
- // Over-engineered: Abstraction without value
18
- const isAdmin = RoleChecker.getInstance().checkRole(user, RoleTypes.ADMIN);
19
- ```
20
-
21
- ### YAGNI (You Ain't Gonna Need It)
22
-
23
- Don't build features, abstractions, or flexibility you don't need **right now**.
24
-
25
- ```typescript
26
- // Correct: Solve today's problem
27
- const formatDate = (date: Date) => date.toISOString().split("T")[0];
28
-
29
- // Wrong: Building for hypothetical future needs
30
- const formatDate = (date: Date, format?: string, locale?: string, timezone?: string) => {
31
- // 50 lines handling cases that may never be used
32
- };
33
- ```
34
-
35
- ### DRY (Don't Repeat Yourself) - With KISS Constraint
36
-
37
- Extract duplication only when:
38
- 1. The same logic appears **3+ times**
39
- 2. The abstraction is **simpler** than the duplication
40
- 3. The extracted code has a **clear single purpose**
41
-
42
- ### SOLID Principles - Applied Pragmatically
43
-
44
- | Principle | Apply When | Skip When |
45
- | ------------------------- | --------------------------------------------- | --------------------------------------- |
46
- | **S**ingle Responsibility | Function does 2+ unrelated things | Splitting adds complexity |
47
- | **O**pen/Closed | Extension points have clear use cases | No foreseeable extensions |
48
- | **L**iskov Substitution | Using inheritance hierarchies | Using composition (preferred) |
49
- | **I**nterface Segregation | Consumers need different subsets | Interface is already small |
50
- | **D**ependency Inversion | Testing requires mocking external services | Direct dependency is simpler |
51
-
52
- ### Decision Framework
53
-
54
- When unsure, ask in order:
55
- 1. **Do I need this now?** (YAGNI) - If no, don't build it
56
- 2. **Is there a simpler way?** (KISS) - Choose the simpler option
57
- 3. **Am I repeating myself 3+ times?** (DRY) - Extract if the abstraction is simpler
58
- 4. **Does this function do one thing?** (SOLID-SRP) - Split only if clearer
59
-
60
- ---
61
-
62
- ## Core Principles
63
-
64
- ### 1. Immutability First
65
-
66
- Never mutate data. Always create new references.
67
-
68
- ```typescript
69
- // Correct - spread creates new object
70
- const updated = { ...user, name: "New Name" };
71
-
72
- // Incorrect - mutation
73
- user.name = "New Name";
74
- ```
75
-
76
- ### 2. Function Structure Ordering
77
-
78
- All functions, hooks, and components follow a strict ordering:
79
-
80
- ```text
81
- 1. Variable definitions and derived state (const, useState, useMemo, useCallback)
82
- 2. Side effects (useEffect, function calls with no return value)
83
- 3. Return statement
84
- ```
85
-
86
- ### 3. Functional Transformations
87
-
88
- Use `map`, `filter`, `reduce` instead of imperative loops and mutations.
89
-
90
- ```typescript
91
- // Correct - functional transformation
92
- const names = users.map(u => u.name);
93
-
94
- // Incorrect - imperative mutation
95
- const names = [];
96
- users.forEach(u => names.push(u.name));
97
- ```
98
-
99
- ### 4. Test-Driven Development (TDD)
100
-
101
- **Always write failing tests before implementation code.** This is mandatory, not optional.
102
-
103
- ```text
104
- TDD Cycle:
105
- 1. RED: Write a failing test that defines expected behavior
106
- 2. GREEN: Write the minimum code to make the test pass
107
- 3. REFACTOR: Clean up while keeping tests green
108
- ```
109
-
110
- ### 5. Clean Deletion
111
-
112
- **Delete old code completely.** No deprecation warnings, migration shims, or backward-compatibility layers unless explicitly requested.
113
-
114
- ```typescript
115
- // Correct: Remove the old code entirely
116
- const calculateScore = (player: Player): number => player.stats.overall;
117
-
118
- // Wrong: Keeping deprecated versions around
119
- /** @deprecated Use calculateScore instead */
120
- const getPlayerScore = (player: Player): number => calculateScore(player);
121
- ```
122
-
123
- **Clean deletion rules:**
124
- - When replacing code, delete the old version completely
125
- - Never create `V2`, `New`, or `Old` suffixed functions/variables
126
- - Never add `@deprecated` comments - just remove the code
127
- - Never write migration code unless explicitly asked
128
- - Trust git history for recovery if needed
129
-
130
- ---
131
-
132
- ## Quick Reference
133
-
134
- ### Variable Declaration
135
-
136
- | Pattern | Status | Example |
137
- | ------- | --------- | ----------------------------- |
138
- | `const` | Required | `const value = calculate();` |
139
- | `let` | Forbidden | Use ternary or reduce instead |
140
- | `var` | Forbidden | Never use |
141
-
142
- ### Array Operations
143
-
144
- | Instead of | Use |
145
- | ----------------------- | -------------------------------------------- |
146
- | `arr.push(item)` | `[...arr, item]` |
147
- | `arr.pop()` | `arr.slice(0, -1)` |
148
- | `arr.splice(i, 1)` | `arr.filter((_, idx) => idx !== i)` |
149
- | `arr.sort()` | `[...arr].sort()` |
150
- | `arr[i] = value` | `arr.map((v, idx) => idx === i ? value : v)` |
151
- | `forEach` with mutation | `reduce` or `map` |
152
-
153
- ### Object Operations
154
-
155
- | Instead of | Use |
156
- | ------------------------- | ----------------------------- |
157
- | `obj.key = value` | `{ ...obj, key: value }` |
158
- | `delete obj.key` | `({ key: _, ...rest } = obj)` |
159
- | `Object.assign(obj, ...)` | `{ ...obj, ...other }` |
160
-
161
- ### Building Lookup Objects
162
-
163
- ```typescript
164
- // Correct - reduce with spread
165
- const lookup = items.reduce(
166
- (acc, item) => ({ ...acc, [item.id]: item }),
167
- {} as Record<string, Item>
168
- );
169
-
170
- // Incorrect - forEach with Map.set
171
- const lookup = new Map();
172
- items.forEach(item => lookup.set(item.id, item));
173
- ```
174
-
175
- ### Conditional Values
176
-
177
- ```typescript
178
- // Correct - ternary expression
179
- const status = isComplete ? "done" : "pending";
180
-
181
- // Incorrect - let with reassignment
182
- let status = "pending";
183
- if (isComplete) {
184
- status = "done";
185
- }
186
- ```
187
-
188
- ---
189
-
190
- ## Hook Structure Example
191
-
192
- ```typescript
193
- export const usePlayerData = (playerId: string) => {
194
- // 1. VARIABLES & STATE (first)
195
- const [isLoading, setIsLoading] = useState(true);
196
- const { data } = useQuery(GetPlayerDocument, { variables: { playerId } });
197
-
198
- const playerName = useMemo(() => data?.player?.name ?? "Unknown", [data]);
199
-
200
- const handleRefresh = useCallback(() => {
201
- refetch();
202
- }, [refetch]);
203
-
204
- // 2. SIDE EFFECTS (second)
205
- useEffect(() => {
206
- console.log("Player loaded:", playerName);
207
- }, [playerName]);
208
-
209
- // 3. RETURN (last)
210
- return { playerName, isLoading, handleRefresh };
211
- };
212
- ```
213
-
214
- ## Container Component Example
215
-
216
- ```typescript
217
- const PlayerCardContainer: React.FC<Props> = ({ playerId }) => {
218
- // 1. VARIABLES & STATE
219
- const { data, loading } = useQuery(GetPlayerDocument, { variables: { playerId } });
220
- const { colors } = useTheme();
221
-
222
- const formattedStats = useMemo(
223
- () => data?.stats?.map(s => ({ ...s, display: formatStat(s) })) ?? [],
224
- [data?.stats]
225
- );
226
-
227
- const handlePress = useCallback(() => {
228
- router.push(`/players/${playerId}`);
229
- }, [playerId]);
230
-
231
- // 2. SIDE EFFECTS (none in this example)
232
-
233
- // 3. RETURN
234
- return (
235
- <PlayerCardView
236
- stats={formattedStats}
237
- colors={colors}
238
- loading={loading}
239
- onPress={handlePress}
240
- />
241
- );
242
- };
243
- ```
244
-
245
- ## Utility Function Example
246
-
247
- ```typescript
248
- export const calculateTeamRankings = (
249
- players: readonly Player[]
250
- ): readonly TeamRanking[] => {
251
- // 1. VARIABLES & DERIVED VALUES
252
- const validPlayers = players.filter(p => p.team && p.score != null);
253
-
254
- const teamScores = validPlayers.reduce(
255
- (acc, player) => ({
256
- ...acc,
257
- [player.team.id]: {
258
- teamId: player.team.id,
259
- totalScore: (acc[player.team.id]?.totalScore ?? 0) + player.score,
260
- count: (acc[player.team.id]?.count ?? 0) + 1,
261
- },
262
- }),
263
- {} as Record<string, { teamId: string; totalScore: number; count: number }>
264
- );
265
-
266
- const rankings = Object.values(teamScores).map(t => ({
267
- teamId: t.teamId,
268
- avgScore: t.totalScore / t.count,
269
- }));
270
-
271
- const sorted = [...rankings].sort((a, b) => b.avgScore - a.avgScore);
272
-
273
- // 2. NO SIDE EFFECTS IN PURE FUNCTIONS
274
-
275
- // 3. RETURN
276
- return sorted;
277
- };
278
- ```
279
-
280
- ---
281
-
282
- ## Anti-Patterns to Avoid
283
-
284
- ### Never use `let` for conditional assignment
285
-
286
- ```typescript
287
- // Wrong
288
- let result;
289
- if (condition) {
290
- result = valueA;
291
- } else {
292
- result = valueB;
293
- }
294
-
295
- // Correct
296
- const result = condition ? valueA : valueB;
297
- ```
298
-
299
- ### Never mutate arrays
300
-
301
- ```typescript
302
- // Wrong
303
- const items = [];
304
- data.forEach(d => items.push(transform(d)));
305
-
306
- // Correct
307
- const items = data.map(d => transform(d));
308
- ```
309
-
310
- ### Never use Map when Record suffices
311
-
312
- ```typescript
313
- // Wrong
314
- const lookup = new Map<string, User>();
315
- users.forEach(u => lookup.set(u.id, u));
316
- const user = lookup.get(userId);
317
-
318
- // Correct
319
- const lookup = users.reduce(
320
- (acc, u) => ({ ...acc, [u.id]: u }),
321
- {} as Record<string, User>
322
- );
323
- const user = lookup[userId];
324
- ```
325
-
326
- ### Never sort in place
327
-
328
- ```typescript
329
- // Wrong - mutates original
330
- const sorted = items.sort((a, b) => a.value - b.value);
331
-
332
- // Correct - creates new array
333
- const sorted = [...items].sort((a, b) => a.value - b.value);
334
- ```
335
-
336
- ### Never place useEffect before variable definitions
337
-
338
- ```typescript
339
- // Wrong
340
- useEffect(() => {
341
- /* ... */
342
- }, [value]);
343
- const value = useMemo(() => calculate(), [dep]);
344
-
345
- // Correct
346
- const value = useMemo(() => calculate(), [dep]);
347
- useEffect(() => {
348
- /* ... */
349
- }, [value]);
350
- ```
351
-
352
- ---
353
-
354
- ## Immutable Patterns Reference
355
-
356
- ### Building Lookup Objects with Reduce
357
-
358
- ```typescript
359
- const colorMap =
360
- edges?.reduce(
361
- (acc, edge) => (edge.color ? { ...acc, [edge.tagId]: edge.color } : acc),
362
- {} as Record<string, string>
363
- ) ?? {};
364
- ```
365
-
366
- ### Accumulating Multiple Properties
367
-
368
- ```typescript
369
- const teamGprAccumulator = validPlayers.reduce(
370
- (acc, player) => {
371
- const teamId = player.team?.id;
372
- if (!teamId) return acc;
373
-
374
- const existing = acc[teamId];
375
- return {
376
- ...acc,
377
- [teamId]: {
378
- teamId,
379
- teamName: player.team.name,
380
- gprSum: (existing?.gprSum ?? 0) + player.gpr,
381
- playerCount: (existing?.playerCount ?? 0) + 1,
382
- },
383
- };
384
- },
385
- {} as Record<string, { teamId: string; teamName: string; gprSum: number; playerCount: number }>
386
- );
387
- ```
388
-
389
- ### Nested Object Updates
390
-
391
- ```typescript
392
- const updated = {
393
- ...state,
394
- user: {
395
- ...state.user,
396
- profile: {
397
- ...state.user.profile,
398
- avatar: newAvatar,
399
- },
400
- },
401
- };
402
- ```
403
-
404
- ### Conditional Property Addition
405
-
406
- ```typescript
407
- const result = {
408
- ...baseObj,
409
- ...(condition && { optionalProp: value }),
410
- };
411
- ```
412
-
413
- ### Ternary Chain for Multiple Conditions
414
-
415
- ```typescript
416
- const priority = score > 90 ? "high" : score > 70 ? "medium" : "low";
417
- ```
418
-
419
- ### Readonly Types for Function Parameters
420
-
421
- ```typescript
422
- export const calculateTeamGprRank = (
423
- leaguePlayers: readonly (PlayerWithScores | null | undefined)[],
424
- myTeamId: string | null | undefined
425
- ): number | null => {
426
- // ...
427
- };
428
- ```