@codyswann/lisa 1.47.0 → 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 (216) hide show
  1. package/all/copy-overwrite/.claude/rules/lisa.md +23 -10
  2. package/all/copy-overwrite/.claude/settings.json +10 -230
  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 -231
  26. package/typescript/copy-overwrite/.github/workflows/claude-ci-auto-fix.yml +1 -0
  27. package/typescript/copy-overwrite/.github/workflows/claude-code-review-response.yml +11 -10
  28. package/typescript/copy-overwrite/.github/workflows/claude-deploy-auto-fix.yml +1 -0
  29. package/typescript/copy-overwrite/.github/workflows/claude-nightly-code-complexity.yml +1 -0
  30. package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-coverage.yml +1 -0
  31. package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-improvement.yml +2 -0
  32. package/typescript/copy-overwrite/.github/workflows/claude.yml +1 -0
  33. package/typescript/copy-overwrite/eslint.typescript.ts +1 -1
  34. package/typescript/create-only/.github/workflows/ci.yml +1 -1
  35. package/typescript/deletions.json +12 -1
  36. package/typescript/package-lisa/package.lisa.json +1 -1
  37. package/all/copy-overwrite/.claude/agents/agent-architect.md +0 -310
  38. package/all/copy-overwrite/.claude/agents/architecture-specialist.md +0 -53
  39. package/all/copy-overwrite/.claude/agents/debug-specialist.md +0 -204
  40. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +0 -183
  41. package/all/copy-overwrite/.claude/agents/hooks-expert.md +0 -74
  42. package/all/copy-overwrite/.claude/agents/implementer.md +0 -54
  43. package/all/copy-overwrite/.claude/agents/learner.md +0 -44
  44. package/all/copy-overwrite/.claude/agents/performance-specialist.md +0 -95
  45. package/all/copy-overwrite/.claude/agents/product-specialist.md +0 -72
  46. package/all/copy-overwrite/.claude/agents/quality-specialist.md +0 -55
  47. package/all/copy-overwrite/.claude/agents/security-specialist.md +0 -58
  48. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +0 -246
  49. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +0 -87
  50. package/all/copy-overwrite/.claude/agents/test-specialist.md +0 -64
  51. package/all/copy-overwrite/.claude/agents/verification-specialist.md +0 -189
  52. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +0 -112
  53. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +0 -7
  54. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-and-verify.md +0 -7
  55. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-deploy-and-verify.md +0 -7
  56. package/all/copy-overwrite/.claude/commands/git/commit.md +0 -7
  57. package/all/copy-overwrite/.claude/commands/git/prune.md +0 -6
  58. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +0 -7
  59. package/all/copy-overwrite/.claude/commands/jira/create.md +0 -7
  60. package/all/copy-overwrite/.claude/commands/jira/sync.md +0 -7
  61. package/all/copy-overwrite/.claude/commands/jira/verify.md +0 -7
  62. package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +0 -7
  63. package/all/copy-overwrite/.claude/commands/plan/add-test-coverage.md +0 -7
  64. package/all/copy-overwrite/.claude/commands/plan/create.md +0 -6
  65. package/all/copy-overwrite/.claude/commands/plan/execute.md +0 -7
  66. package/all/copy-overwrite/.claude/commands/plan/fix-linter-error.md +0 -7
  67. package/all/copy-overwrite/.claude/commands/plan/local-code-review.md +0 -6
  68. package/all/copy-overwrite/.claude/commands/plan/lower-code-complexity.md +0 -6
  69. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines-per-function.md +0 -7
  70. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines.md +0 -7
  71. package/all/copy-overwrite/.claude/commands/pull-request/review.md +0 -7
  72. package/all/copy-overwrite/.claude/commands/security/zap-scan.md +0 -6
  73. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +0 -6
  74. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +0 -6
  75. package/all/copy-overwrite/.claude/commands/tasks/load.md +0 -7
  76. package/all/copy-overwrite/.claude/commands/tasks/sync.md +0 -7
  77. package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +0 -61
  78. package/all/copy-overwrite/.claude/hooks/debug-hook.sh +0 -47
  79. package/all/copy-overwrite/.claude/hooks/enforce-plan-rules.sh +0 -15
  80. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +0 -183
  81. package/all/copy-overwrite/.claude/hooks/setup-jira-cli.sh +0 -52
  82. package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +0 -107
  83. package/all/copy-overwrite/.claude/hooks/ticket-sync-reminder.sh +0 -23
  84. package/all/copy-overwrite/.claude/hooks/track-plan-sessions.sh +0 -164
  85. package/all/copy-overwrite/.claude/rules/coding-philosophy.md +0 -428
  86. package/all/copy-overwrite/.claude/rules/verfication.md +0 -541
  87. package/all/copy-overwrite/.claude/skills/agent-design-best-practices/SKILL.md +0 -219
  88. package/all/copy-overwrite/.claude/skills/git-commit/SKILL.md +0 -48
  89. package/all/copy-overwrite/.claude/skills/git-commit-and-submit-pr/SKILL.md +0 -8
  90. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-and-verify/SKILL.md +0 -7
  91. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-deploy-and-verify/SKILL.md +0 -7
  92. package/all/copy-overwrite/.claude/skills/git-prune/SKILL.md +0 -35
  93. package/all/copy-overwrite/.claude/skills/git-submit-pr/SKILL.md +0 -44
  94. package/all/copy-overwrite/.claude/skills/jira-create/SKILL.md +0 -41
  95. package/all/copy-overwrite/.claude/skills/jira-sync/SKILL.md +0 -63
  96. package/all/copy-overwrite/.claude/skills/jira-verify/SKILL.md +0 -29
  97. package/all/copy-overwrite/.claude/skills/lisa-review-implementation/SKILL.md +0 -209
  98. package/all/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -44
  99. package/all/copy-overwrite/.claude/skills/plan-execute/SKILL.md +0 -89
  100. package/all/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  101. package/all/copy-overwrite/.claude/skills/plan-local-code-review/SKILL.md +0 -88
  102. package/all/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -44
  103. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -45
  104. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  105. package/all/copy-overwrite/.claude/skills/pull-request-review/SKILL.md +0 -68
  106. package/all/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  107. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +0 -202
  108. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +0 -210
  109. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  110. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +0 -305
  111. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +0 -112
  112. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +0 -67
  113. package/all/copy-overwrite/.claude/skills/sonarqube-check/SKILL.md +0 -11
  114. package/all/copy-overwrite/.claude/skills/sonarqube-fix/SKILL.md +0 -8
  115. package/all/copy-overwrite/.claude/skills/tasks-load/SKILL.md +0 -88
  116. package/all/copy-overwrite/.claude/skills/tasks-sync/SKILL.md +0 -108
  117. package/eslint-plugin-code-organization/README.md +0 -149
  118. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  119. package/eslint-plugin-code-organization/index.js +0 -28
  120. package/eslint-plugin-code-organization/package.json +0 -10
  121. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
  122. package/expo/copy-overwrite/.claude/agents/ops-specialist.md +0 -124
  123. package/expo/copy-overwrite/.claude/rules/expo-verification.md +0 -261
  124. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +0 -238
  125. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +0 -360
  126. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +0 -360
  127. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +0 -417
  128. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +0 -257
  129. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +0 -233
  130. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +0 -329
  131. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +0 -299
  132. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +0 -749
  133. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +0 -318
  134. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +0 -200
  135. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +0 -209
  136. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +0 -268
  137. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +0 -619
  138. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +0 -340
  139. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +0 -276
  140. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +0 -416
  141. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +0 -202
  142. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +0 -445
  143. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +0 -309
  144. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +0 -417
  145. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +0 -431
  146. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +0 -290
  147. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +0 -171
  148. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +0 -411
  149. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +0 -343
  150. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +0 -307
  151. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +0 -300
  152. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +0 -315
  153. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +0 -362
  154. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +0 -505
  155. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +0 -711
  156. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +0 -446
  157. package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +0 -124
  158. package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +0 -211
  159. package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +0 -119
  160. package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +0 -119
  161. package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +0 -99
  162. package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +0 -165
  163. package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +0 -166
  164. package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +0 -101
  165. package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +0 -56
  166. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +0 -223
  167. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +0 -314
  168. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +0 -420
  169. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +0 -556
  170. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +0 -590
  171. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +0 -291
  172. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +0 -234
  173. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +0 -89
  174. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +0 -201
  175. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +0 -294
  176. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +0 -37
  177. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +0 -10
  178. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +0 -235
  179. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +0 -96
  180. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +0 -183
  181. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +0 -243
  182. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -192
  183. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +0 -31
  184. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +0 -10
  185. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +0 -56
  186. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +0 -60
  187. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +0 -176
  188. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +0 -527
  189. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +0 -483
  190. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +0 -257
  191. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +0 -413
  192. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +0 -513
  193. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +0 -536
  194. package/nestjs/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  195. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +0 -275
  196. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +0 -487
  197. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +0 -450
  198. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +0 -536
  199. package/rails/copy-overwrite/.claude/skills/action-controller-best-practices/SKILL.md +0 -374
  200. package/rails/copy-overwrite/.claude/skills/action-view-best-practices/SKILL.md +0 -335
  201. package/rails/copy-overwrite/.claude/skills/active-record-model-best-practices/SKILL.md +0 -166
  202. package/rails/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -45
  203. package/rails/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  204. package/rails/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -48
  205. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -46
  206. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  207. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +0 -76
  208. package/typescript/copy-overwrite/.claude/hooks/install-pkgs.sh +0 -64
  209. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +0 -105
  210. package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +0 -68
  211. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +0 -432
  212. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +0 -149
  213. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  214. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +0 -28
  215. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +0 -10
  216. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
@@ -1,299 +0,0 @@
1
- ---
2
- name: container-view-pattern
3
- description: This skill enforces the Container/View pattern for React components. It should be used when creating new components, validating existing components, or refactoring components to follow the separation of concerns pattern where Container handles logic and View handles presentation.
4
- ---
5
-
6
- # Container/View Pattern
7
-
8
- This skill provides guidance and validation for the Container/View component pattern used in this codebase.
9
-
10
- ## Pattern Overview
11
-
12
- The Container/View pattern separates components into two distinct files:
13
-
14
- - **Container** (`*Container.tsx`): Handles logic, state, API calls, data fetching, and event handlers
15
- - **View** (`*View.tsx`): Handles rendering UI only, receiving all data and callbacks as props
16
- - **Index** (`index.tsx`): Exports the Container as the default component
17
-
18
- ## Where This Pattern Applies
19
-
20
- The Container/View pattern is **required** in these directories:
21
-
22
- | Directory | Applies | Notes |
23
- | ------------------------ | ------- | ------------------------- |
24
- | `features/*/components/` | Yes | All feature components |
25
- | `features/*/screens/` | Yes | All feature screens |
26
- | `components/` | Yes | Shared components |
27
- | `screens/` | Yes | Shared screens |
28
- | `components/ui/` | No | UI primitives (GlueStack) |
29
- | `components/shared/` | No | Simple shared utilities |
30
- | `components/icons/` | No | Icon components |
31
-
32
- ## When to Use This Skill
33
-
34
- - Creating a new component in any of the directories above
35
- - Validating that existing components follow the pattern
36
- - Refactoring a component to follow the pattern
37
- - Reviewing code for pattern compliance
38
-
39
- ## Creating a New Component
40
-
41
- ### Option 1: Use the Skill Generator Script
42
-
43
- Run the skill's generator script for any component type:
44
-
45
- ```bash
46
- python3 .claude/skills/container-view-pattern/scripts/create_component.py <type> <name> [feature]
47
- ```
48
-
49
- **Component Types:**
50
-
51
- | Type | Command | Creates in |
52
- | ----------------- | ---------------------------------------------------------------- | ----------------------------------------------- |
53
- | Global component | `create_component.py global-component PlayerCard` | `components/PlayerCard/` |
54
- | Feature component | `create_component.py feature-component PlayerCard player-kanban` | `features/player-kanban/components/PlayerCard/` |
55
- | Global screen | `create_component.py global-screen Settings` | `screens/Settings/` |
56
- | Feature screen | `create_component.py feature-screen Main dashboard` | `features/dashboard/screens/Main/` |
57
-
58
-
59
- ### Option 2: Manual Creation
60
-
61
- Create the following directory structure:
62
-
63
- ```
64
- ComponentName/
65
- ├── ComponentNameContainer.tsx
66
- ├── ComponentNameView.tsx
67
- └── index.tsx
68
- ```
69
-
70
- ## Container Component Requirements
71
-
72
- Container components handle all business logic:
73
-
74
- 1. **Single View render**: Container must ONLY render its corresponding View component - no other UI elements or components
75
- 2. **State management**: Use `useState`, `useReducer`
76
- 3. **Data fetching**: Use GraphQL hooks, API calls
77
- 4. **Memoization**: Wrap all computed values in `useMemo`
78
- 5. **Event handlers**: Wrap all handlers in `useCallback` with proper dependencies
79
- 6. **Formatting**: All data transformation and formatting logic
80
- 7. **Conditional logic**: Determine what state to pass to View (loading, error, empty flags)
81
-
82
- ### Container Code Order (enforced by ESLint)
83
-
84
- Containers must follow this specific order:
85
-
86
- ```tsx
87
- const ExampleContainer = () => {
88
- // 1. Variables, state, useMemo, useCallback (same group)
89
- const [state, setState] = useState();
90
- const computed = useMemo(() => state * 2, [state]);
91
- const handleClick = useCallback(() => {}, []);
92
-
93
- // 2. useEffect hooks
94
- useEffect(() => {
95
- // side effects
96
- }, []);
97
-
98
- // 3. Return statement (always last)
99
- return <ExampleView />;
100
- };
101
- ```
102
-
103
- ### Container Template
104
-
105
- ```tsx
106
- import { useCallback, useMemo, useState } from "react";
107
- import ComponentNameView from "./ComponentNameView";
108
-
109
- /**
110
- * Props for the ComponentName component.
111
- */
112
- interface ComponentNameProps {
113
- readonly id: string;
114
- }
115
-
116
- /**
117
- * Container component that manages state and logic for ComponentName.
118
- * @param props - Component properties
119
- * @param props.id - The unique identifier
120
- */
121
- const ComponentNameContainer = ({ id }: ComponentNameProps) => {
122
- // State
123
- const [isLoading, setIsLoading] = useState(false);
124
-
125
- // Memoized computed values
126
- const formattedData = useMemo(() => {
127
- return data?.toUpperCase() ?? "";
128
- }, [data]);
129
-
130
- // Event handlers wrapped in useCallback
131
- const handleSubmit = useCallback(() => {
132
- setIsLoading(true);
133
- }, []);
134
-
135
- return (
136
- <ComponentNameView
137
- formattedData={formattedData}
138
- isLoading={isLoading}
139
- onSubmit={handleSubmit}
140
- />
141
- );
142
- };
143
-
144
- export default ComponentNameContainer;
145
- ```
146
-
147
- ## View Component Requirements
148
-
149
- View components are pure presentation:
150
-
151
- 1. **Arrow function shorthand**: Use `() => (...)` not `() => { return (...); }`
152
- 2. **No return statements**: The component body must be a single JSX expression
153
- 3. **memo wrapper**: Export with `memo()` for performance optimization
154
- 4. **displayName**: Set `ComponentName.displayName = "ComponentName"`
155
- 5. **Readonly props**: All props should be marked as `readonly`
156
- 6. **No hooks**: View should not contain `useState`, `useEffect`, `useMemo`, etc.
157
- 7. **No logic**: All conditional rendering should use ternary expressions in JSX
158
-
159
- ### View Template
160
-
161
- ```tsx
162
- import { memo } from "react";
163
-
164
- import { Box } from "@/components/ui/box";
165
- import { Text } from "@/components/ui/text";
166
-
167
- /**
168
- * Props for the ComponentNameView component.
169
- */
170
- interface ComponentNameViewProps {
171
- readonly formattedData: string;
172
- readonly isLoading: boolean;
173
- readonly onSubmit: () => void;
174
- }
175
-
176
- /**
177
- * View component that renders the ComponentName UI.
178
- * @param props - Component properties
179
- * @param props.formattedData - Pre-formatted display data
180
- * @param props.isLoading - Loading state indicator
181
- * @param props.onSubmit - Submit handler callback
182
- */
183
- const ComponentNameView = ({
184
- formattedData,
185
- isLoading,
186
- onSubmit,
187
- }: ComponentNameViewProps) => (
188
- <Box testID="COMPONENT_NAME.CONTAINER">
189
- {isLoading ? <Text>Loading...</Text> : <Text>{formattedData}</Text>}
190
- </Box>
191
- );
192
-
193
- ComponentNameView.displayName = "ComponentNameView";
194
-
195
- export default memo(ComponentNameView);
196
- ```
197
-
198
- ## Index File
199
-
200
- Export the Container as the default:
201
-
202
- ```tsx
203
- export { default } from "./ComponentNameContainer";
204
- ```
205
-
206
- ## Validation
207
-
208
- ### ESLint Rules
209
-
210
- The following ESLint rules enforce the pattern:
211
-
212
- | Rule | Description |
213
- | ------------------------------------------------- | --------------------------------------------- |
214
- | `component-structure/enforce-component-structure` | Validates directory structure and file naming |
215
- | `component-structure/no-return-in-view` | Ensures View uses arrow shorthand |
216
- | `component-structure/require-memo-in-view` | Ensures View uses memo and displayName |
217
- | `component-structure/single-component-per-file` | One component per file |
218
-
219
- ### Manual Validation
220
-
221
- Run the validation script to check a component:
222
-
223
- ```bash
224
- python3 .claude/skills/container-view-pattern/scripts/validate_component.py <path-to-component-directory>
225
- ```
226
-
227
- Run ESLint to check all components:
228
-
229
- ```bash
230
- bun run lint
231
- ```
232
-
233
- > **Note:** Replace `bun` with your project's package manager (`npm`, `yarn`, `pnpm`) as needed.
234
-
235
- ## Common Violations
236
-
237
- ### Container Violations
238
-
239
- | Issue | Resolution |
240
- | ------------------------------------ | ----------------------------------------------------------- |
241
- | Rendering UI elements besides View | Container must ONLY return the corresponding View component |
242
- | Rendering multiple components | Move all UI to View; Container returns only View |
243
- | Missing `useMemo` for objects/arrays | Wrap computed values in `useMemo` |
244
- | Missing `useCallback` for functions | Wrap handlers in `useCallback` |
245
- | Logic in View component | Move logic to Container |
246
- | Inline function props | Create memoized handler |
247
-
248
- ### View Violations
249
-
250
- | Issue | Resolution |
251
- | ----------------------------- | ------------------------------------------------- |
252
- | Using block body `{ return }` | Convert to arrow shorthand `() => (...)` |
253
- | Missing `memo` wrapper | Add `export default memo(ComponentView)` |
254
- | Missing `displayName` | Add `ComponentView.displayName = "ComponentView"` |
255
- | Contains hooks | Move hooks to Container |
256
- | Contains state | Move state to Container |
257
-
258
- ## Extracting Helper Functions
259
-
260
- When View components exceed ESLint's cognitive complexity threshold (28), extract render helper functions. For simple cases, prefer inline JSX:
261
-
262
- ```tsx
263
- /**
264
- * Renders the loading skeleton state.
265
- * @param props - Helper function properties
266
- * @param props.isDark - Whether dark mode is active
267
- */
268
- function renderLoadingState(props: { readonly isDark: boolean }) {
269
- const { isDark } = props;
270
- return <LoadingSkeleton isDark={isDark} />;
271
- }
272
-
273
- const ComponentView = ({ isLoading, isDark }: Props) => (
274
- <Box>{isLoading ? renderLoadingState({ isDark }) : <Content />}</Box>
275
- );
276
- ```
277
-
278
- ## Event Handler Naming Convention
279
-
280
- - **Container**: Use `handle*` prefix (e.g., `handleSubmit`, `handleClick`)
281
- - **View props**: Use `on*` prefix (e.g., `onSubmit`, `onClick`)
282
-
283
- ```tsx
284
- // Container
285
- const handleSubmit = useCallback(() => { ... }, []);
286
- return <ComponentView onSubmit={handleSubmit} />;
287
-
288
- // View
289
- const ComponentView = ({ onSubmit }: Props) => (
290
- <Button onPress={onSubmit}>Submit</Button>
291
- );
292
- ```
293
-
294
- ## Reference Documentation
295
-
296
- For detailed examples and edge cases, read:
297
-
298
- - `references/patterns.md` - Common patterns and anti-patterns
299
- - `references/examples.md` - Complete component examples