@codyswann/lisa 1.55.3 → 1.56.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.
@@ -134,7 +134,6 @@
134
134
  ],
135
135
  "keep": [
136
136
  "scripts/setup-deploy-key.sh",
137
- ".claude/commands/lisa",
138
137
  ".coderabbit.yml",
139
138
  "HUMAN.md"
140
139
  ]
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "extends": ["@codyswann/lisa/tsconfig/cdk", "./tsconfig.local.json"],
3
+ "compilerOptions": {
4
+ "baseUrl": "./"
5
+ },
3
6
  "include": ["lib/**/*", "bin/**/*", "test/**/*"],
4
7
  "exclude": ["node_modules", "cdk.out"]
5
8
  }
@@ -1,5 +1,12 @@
1
1
  {
2
2
  "extends": ["@codyswann/lisa/tsconfig/expo", "./tsconfig.local.json"],
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "paths": {
6
+ "@/graphql/*": ["./generated/*"],
7
+ "@/*": ["./*"]
8
+ }
9
+ },
3
10
  "include": ["**/*.ts", "**/*.tsx", "nativewind-env.d.ts"],
4
11
  "exclude": ["node_modules", "dist", "web-build", "components/ui"]
5
12
  }
@@ -26,6 +26,7 @@
26
26
  ".claude/skills/ops-verify-health",
27
27
  ".claude/skills/owasp-zap",
28
28
  ".claude/skills/playwright-selectors",
29
+ ".claude/skills/reduce-complexity",
29
30
  ".claude/skills/testing-library",
30
31
  ".github/workflows/build.yml",
31
32
  ".github/workflows/lighthouse.yml",
@@ -1,5 +1,11 @@
1
1
  {
2
2
  "extends": ["@codyswann/lisa/tsconfig/nestjs", "./tsconfig.local.json"],
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "paths": {
6
+ "@/*": ["./src/*"]
7
+ }
8
+ },
3
9
  "include": ["src/**/*"],
4
10
  "exclude": ["node_modules", ".build", "dist", "**/*.test.ts", "**/*.spec.ts"]
5
11
  }
package/package.json CHANGED
@@ -27,8 +27,6 @@
27
27
  "setup:deploy-key": "bash scripts/setup-deploy-key.sh",
28
28
  "lisa:update:local": "bash scripts/lisa-update-local.sh",
29
29
  "lisa:commit-and-pr:local": "bash scripts/lisa-commit-and-pr-local.sh",
30
- "prepack": "bash scripts/strip-workspaces-for-pack.sh",
31
- "postpack": "[ -f package.json.bak ] && mv package.json.bak package.json || true",
32
30
  "prepublishOnly": "$npm_execpath run build",
33
31
  "postinstall": "bash ./scripts/install-claude-plugins.sh || true; [ -d dist/configs ] || tsc || true"
34
32
  },
@@ -39,6 +37,11 @@
39
37
  "bun": "1.3.8",
40
38
  "node": "22.21.1"
41
39
  },
40
+ "workspaces": [
41
+ "eslint-plugin-code-organization",
42
+ "eslint-plugin-component-structure",
43
+ "eslint-plugin-ui-standards"
44
+ ],
42
45
  "files": [
43
46
  "dist",
44
47
  "all",
@@ -69,7 +72,7 @@
69
72
  "axios": ">=1.13.5"
70
73
  },
71
74
  "name": "@codyswann/lisa",
72
- "version": "1.55.3",
75
+ "version": "1.56.0",
73
76
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
74
77
  "main": "dist/index.js",
75
78
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "1.55.3",
3
+ "version": "1.56.0",
4
4
  "description": "Claude Code governance plugin for AWS CDK projects — includes all universal skills, agents, hooks, and rules from Lisa plus TypeScript tooling",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "1.55.3",
3
+ "version": "1.56.0",
4
4
  "description": "Claude Code governance plugin for Expo/React Native projects — includes all universal skills, agents, hooks, and rules from Lisa plus Expo-specific tooling",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,251 @@
1
+ ---
2
+ name: reduce-complexity
3
+ description: This skill provides strategies and patterns for reducing cognitive complexity in React components. It should be used when ESLint reports sonarjs/cognitive-complexity violations, when refactoring complex View components, or when planning how to break down large components. The skill enforces this project's Container/View pattern requirements when extracting components.
4
+ ---
5
+
6
+ # Reduce Complexity
7
+
8
+ This skill provides systematic approaches for reducing cognitive complexity in React components while adhering to this project's Container/View pattern requirements.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - ESLint reports `sonarjs/cognitive-complexity` violations (threshold: 28)
13
+ - A View component exceeds 200 lines
14
+ - A component has deeply nested conditionals or repeated patterns
15
+ - Planning refactoring of a complex component
16
+ - Deciding between extracting helper functions vs full components
17
+
18
+ ## Complexity Sources in React Components
19
+
20
+ Cognitive complexity increases with:
21
+
22
+ | Source | Complexity Impact | Common in View Components |
23
+ | ---------------------- | ----------------- | ------------------------- |
24
+ | Nested conditionals | +1 per nesting | Yes |
25
+ | Ternary expressions | +1 each | Yes |
26
+ | Logical operators (&&) | +1 each | Yes |
27
+ | Loops (map, filter) | +1 each | Yes |
28
+ | Switch/case statements | +1 per case | Rare |
29
+ | Catch blocks | +1 each | No (Container only) |
30
+ | Nested functions | +1 per nesting | Yes |
31
+
32
+ ## Decision Framework: Helper Function vs Full Component
33
+
34
+ Before extracting code, determine the appropriate strategy:
35
+
36
+ ### Extract as Helper Function When:
37
+
38
+ - The JSX renders a static or simple section with no logic of its own
39
+ - The section does not need its own state, hooks, or callbacks
40
+ - The pattern appears only in this file
41
+ - The complexity comes from rendering, not behavior
42
+
43
+ ```tsx
44
+ // Helper function - no logic, just rendering
45
+ function renderSectionHeader(props: {
46
+ readonly title: string;
47
+ readonly count: number;
48
+ }) {
49
+ return (
50
+ <HStack className="justify-between">
51
+ <Text className="font-bold">{props.title}</Text>
52
+ <Text className="text-sm">({props.count})</Text>
53
+ </HStack>
54
+ );
55
+ }
56
+ ```
57
+
58
+ ### Extract as Full Component (Container/View) When:
59
+
60
+ - The section has reusable logic or could be used elsewhere
61
+ - The section would benefit from its own state management
62
+ - The pattern repeats across multiple files
63
+ - The section has 3+ props that could be simplified with a Container
64
+ - Extracting would create a meaningful, named abstraction
65
+
66
+ ```
67
+ FilterChipList/
68
+ ├── FilterChipListContainer.tsx # Handles selection logic
69
+ ├── FilterChipListView.tsx # Renders chip list
70
+ └── index.tsx # Exports Container
71
+ ```
72
+
73
+ ## Refactoring Process
74
+
75
+ ### Step 1: Analyze Complexity Sources
76
+
77
+ Run ESLint to identify the violation:
78
+
79
+ ```bash
80
+ bun run lint 2>&1 | grep "cognitive-complexity"
81
+ ```
82
+
83
+ > **Note:** Replace `bun` with your project's package manager (`npm`, `yarn`, `pnpm`) as needed.
84
+
85
+ Read the file and identify:
86
+
87
+ 1. Which function has the violation (line number from ESLint)
88
+ 2. What patterns repeat (copy-pasted JSX with slight variations)
89
+ 3. What conditionals nest deeply (ternaries inside ternaries)
90
+ 4. What could be pre-computed in Container
91
+
92
+ ### Step 2: Choose Extraction Strategy
93
+
94
+ Use the decision framework above. For View components:
95
+
96
+ | Situation | Strategy |
97
+ | -------------------------- | --------------------------------- |
98
+ | Repeated JSX, no logic | Helper function |
99
+ | Repeated JSX, needs props | Helper function with props object |
100
+ | Repeated pattern, 3+ files | Full Container/View component |
101
+ | Complex section, own state | Full Container/View component |
102
+ | Deeply nested ternaries | Pre-compute flags in Container |
103
+
104
+ ### Step 3: Write Tests First (TDD)
105
+
106
+ Before refactoring, ensure test coverage exists:
107
+
108
+ ```bash
109
+ # Check existing coverage
110
+ bun run test:unit --coverage --collectCoverageFrom='<file-path>'
111
+ ```
112
+
113
+ If no tests exist, write tests that verify current behavior before refactoring.
114
+
115
+ ### Step 4: Implement Extraction
116
+
117
+ For helper functions, see `references/extraction-strategies.md`.
118
+ For full components, use the Container/View pattern skill.
119
+
120
+ ### Step 5: Verify Complexity Resolved
121
+
122
+ ```bash
123
+ bun run lint 2>&1 | grep "cognitive-complexity"
124
+ bun run test:unit
125
+ ```
126
+
127
+ ## Quick Fixes for Common Patterns
128
+
129
+ ### Repeated Conditional Styling
130
+
131
+ **Before (high complexity):**
132
+
133
+ ```tsx
134
+ <Pressable
135
+ style={{
136
+ backgroundColor: selected.includes(item) ? colors.primary : colors.bg,
137
+ borderColor: selected.includes(item) ? colors.primary : colors.border,
138
+ }}
139
+ >
140
+ <Text style={{ color: selected.includes(item) ? "#FFF" : colors.text }}>
141
+ {item}
142
+ </Text>
143
+ </Pressable>
144
+ ```
145
+
146
+ **After (reduced complexity):**
147
+
148
+ ```tsx
149
+ // In Container - pre-compute selection state
150
+ const itemStates = useMemo(
151
+ () =>
152
+ items.map(item => ({
153
+ item,
154
+ isSelected: selected.includes(item),
155
+ })),
156
+ [items, selected]
157
+ );
158
+
159
+ // In View - simple conditional
160
+ <Pressable style={isSelected ? styles.selected : styles.default}>
161
+ <Text style={isSelected ? styles.selectedText : styles.defaultText}>
162
+ {item}
163
+ </Text>
164
+ </Pressable>;
165
+ ```
166
+
167
+ ### Repeated Section Patterns
168
+
169
+ **Before (4x repeated pattern = high complexity):**
170
+
171
+ ```tsx
172
+ {positions.length > 0 && (
173
+ <VStack>
174
+ <Text>Positions</Text>
175
+ <HStack>{positions.map(p => <Chip key={p} ... />)}</HStack>
176
+ </VStack>
177
+ )}
178
+ {tags.length > 0 && (
179
+ <VStack>
180
+ <Text>Tags</Text>
181
+ <HStack>{tags.map(t => <Chip key={t.id} ... />)}</HStack>
182
+ </VStack>
183
+ )}
184
+ // ... repeated 2 more times
185
+ ```
186
+
187
+ **After (extract FilterChipList component):**
188
+
189
+ ```tsx
190
+ <FilterChipList
191
+ title="Positions"
192
+ items={positions}
193
+ selectedItems={filters.positions}
194
+ onToggle={onPositionToggle}
195
+ />
196
+ <FilterChipList
197
+ title="Tags"
198
+ items={tags}
199
+ selectedItems={filters.tags}
200
+ onToggle={onTagToggle}
201
+ />
202
+ ```
203
+
204
+ ### Nested Ternaries
205
+
206
+ **Before:**
207
+
208
+ ```tsx
209
+ {
210
+ isLoading ? (
211
+ <Spinner />
212
+ ) : hasError ? (
213
+ <Error />
214
+ ) : isEmpty ? (
215
+ <Empty />
216
+ ) : (
217
+ <Content />
218
+ );
219
+ }
220
+ ```
221
+
222
+ **After (pre-compute state in Container):**
223
+
224
+ ```tsx
225
+ // Container
226
+ const viewState = useMemo(() => {
227
+ if (isLoading) return "loading";
228
+ if (hasError) return "error";
229
+ if (isEmpty) return "empty";
230
+ return "content";
231
+ }, [isLoading, hasError, isEmpty]);
232
+
233
+ // View - map directly
234
+ const VIEW_STATES = {
235
+ loading: <Spinner />,
236
+ error: <Error />,
237
+ empty: <Empty />,
238
+ content: <Content />,
239
+ } as const;
240
+
241
+ {
242
+ VIEW_STATES[viewState];
243
+ }
244
+ ```
245
+
246
+ ## Reference Documentation
247
+
248
+ For detailed patterns and complete examples:
249
+
250
+ - `references/extraction-strategies.md` - Helper function patterns and when to use each
251
+ - `references/refactoring-patterns.md` - Step-by-step refactoring examples with before/after code