Skip to content

Commit 2a73e0d

Browse files
committed
Sync skills and rules from ~/.cursor
- typescript-standards: Add generic-component-fc-exception pattern, update no-deprecated NavigationBase pointer to /fix-eslint skill - im/SKILL.md: Document update-eslint-warnings.ts graduation mechanism - fix-eslint/SKILL.md: Updated navigation-base pattern (from prior session) TODO: lint-warnings.sh only reads patterns from typescript-standards.mdc. It should also load patterns from /fix-eslint SKILL.md (or a shared patterns file) so detailed fix guidance is front-loaded in terminal output.
1 parent 3376182 commit 2a73e0d

File tree

4 files changed

+70
-22
lines changed

4 files changed

+70
-22
lines changed

.cursor/rules/typescript-standards.mdc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ Fix: Add return type annotation. Common types:
183183

184184
<pattern id="no-deprecated" rule="@typescript-eslint/no-deprecated">Using deprecated API.
185185
Fix: Check the deprecation message for the replacement API. Common replacements:
186-
- `NavigationBase` → `EdgeAppSceneProps<'routeName'>['navigation']`
186+
- `NavigationBase` → Read `/fix-eslint` skill `navigation-base` pattern for category-based fix guidance
187187
- `uniqueIdentifier` → `EdgeSpendInfo.memos`
188188
- `memo` → `EdgeSpendInfo.memos`
189189
- `networkFee` / `parentNetworkFee` → `networkFees`
@@ -203,6 +203,13 @@ Fix: Rename handler to match the prop pattern.
203203
✅ `export const Component: React.FC<Props> = props => {`
204204
</pattern>
205205

206+
<pattern id="generic-component-fc-exception" rule="edge/react-fc-component-definition">Generic components cannot use `React.FC` because it does not support type parameters.
207+
If the generic is not essential (type param only used internally, can be collapsed into a concrete type), remove the generic and convert to `React.FC<Props>`.
208+
If the generic is essential (callers rely on type inference, e.g. `<EdgeCarousel<MyItem> ...>`), keep the function declaration form with an explicit return type. The warning is accepted.
209+
✅ `export function MyComponent<T>(props: Props<T>): React.ReactElement {`
210+
❌ Converting an essential generic to `React.FC` — this loses type safety for callers.
211+
</pattern>
212+
206213
<pattern id="no-styled" rule="no-restricted-syntax">Avoid `styled()` wrapper components.
207214
Fix: Convert to regular component using `useTheme()` and `cacheStyles()`.
208215
❌ `const StyledView = styled(View)(theme => ({ ... }))`

.cursor/skills/chat-audit/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ metadata:
66
author: j0ntz
77
---
88

9-
<goal>Analyze a Cursor chat export to identify inefficiencies, rule violations, and wasted tool calls against the invoked command's workflow.</goal>
9+
<goal>Analyze current chat or provided Cursor chat export to identify inefficiencies, rule violations, and wasted tool calls against the invoked command's workflow.</goal>
1010

1111
<rules description="Non-negotiable constraints.">
1212
<rule id="use-companion-script">Use `scripts/cursor-chat-extract.js` to parse the export. Do NOT parse the raw JSON inline — it is deeply nested and will consume excessive context.</rule>

.cursor/skills/fix-eslint/SKILL.md

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,81 @@ description: Fix ESLint warnings by applying documented patterns. Use when addre
77

88
<rules description="Non-negotiable constraints.">
99
<rule id="tsc-after-fix">Run `npx tsc --noEmit` after every type change to verify no new type errors are introduced.</rule>
10-
<rule id="no-suppress">Do not suppress deprecation warnings with `eslint-disable` comments. Fix the underlying type reference.</rule>
10+
<rule id="no-suppress">Do not suppress deprecation warnings with `eslint-disable` comments. Fix the underlying type reference.
11+
Exception: `NavigationBase` deprecation in shared cross-navigator code (Categories C, D, F below) is accepted — not suppressed, genuinely not fixable without a broader v7 navigation migration. When the fix scope is too broad, add a TODO comment documenting the required migration pattern and accept the warning.</rule>
1112
<rule id="scope-control">Only modify files with deprecation warnings. Do not refactor downstream declarations unless required for the fix to compile.</rule>
1213
</rules>
1314

1415
<patterns>
1516

1617
<pattern id="navigation-base" rule="@typescript-eslint/no-deprecated" symbol="NavigationBase">
17-
`NavigationBase` is a flat navigation type that predates react-navigation's composite `XyzSceneProps` types. It cannot be replaced with scene-specific types in shared code due to variance constraints in composite navigation props.
18+
`NavigationBase` is a flat navigation type hack in `routerTypes.tsx` that unions all navigator param lists (`RootParamList & DrawerParamList & EdgeAppStackParamList & ...`) to pretend the app is flat. It is deprecated because it tracks **react-navigation v7 breaking changes**:
1819

19-
**In scene components** (call sites):
20-
Replace `navigation as NavigationBase` casts with `navigation as AppNavigation`:
20+
1. `navigate()` no longer crosses nested navigator boundaries at runtime.
21+
2. `navigate()` no longer goes back to an existing screen to update params — use `popTo()` or `navigate(screen, params, { pop: true })` instead.
2122

23+
v7 provides `navigateDeprecated()` and `navigationInChildEnabled` as temporary bridges, both removed in v8. **Do NOT create non-deprecated aliases** (like `AppNavigation`) — this hides a real migration requirement.
24+
25+
Fix `NavigationBase` deprecation by identifying which category the usage falls into:
26+
27+
**Category A — Pass-through props** (component accepts `NavigationBase` only to forward it to children or actions):
28+
- Fix: Remove the `navigation` prop. Callers already have navigation in scope. If the child needs navigation, it should use `useNavigation()` or accept specific callbacks.
2229
```typescript
23-
// Before
24-
import type { NavigationBase } from '../../types/routerTypes'
25-
activateWalletTokens(navigation as NavigationBase, wallet, [tokenId])
30+
// Before — CancellableProcessingScene accepts navigation to forward to onError
31+
interface Props { navigation: NavigationBase; onError: (nav: NavigationBase, err: unknown) => void }
2632

27-
// After
28-
import type { AppNavigation } from '../../types/routerTypes'
29-
activateWalletTokens(navigation as AppNavigation, wallet, [tokenId])
33+
// After — remove navigation prop, callers handle navigation in callbacks
34+
interface Props { onError: (err: unknown) => Promise<void> }
3035
```
3136

32-
**In shared actions/utilities** (declaration sites):
33-
Replace `NavigationBase` parameter types with `AppNavigation`:
34-
37+
**Category B — Direct navigation in non-scene components** (component accepts `NavigationBase`, calls `navigate()`/`push()` directly):
38+
- Fix: Replace `navigation: NavigationBase` prop with `useNavigation()` hook typed to the navigator context the component lives in. Or replace with specific navigation callbacks from the parent scene.
3539
```typescript
36-
// Before
37-
import type { NavigationBase } from '../types/routerTypes'
38-
export function myAction(navigation: NavigationBase): ThunkAction<...> {
40+
// Before — BalanceCard accepts NavigationBase, calls navigate directly
41+
interface Props { navigation: NavigationBase }
42+
const BalanceCard: React.FC<Props> = props => {
43+
props.navigation.push('send2', { walletId, tokenId })
44+
}
45+
46+
// After (option 1) — useNavigation hook
47+
const BalanceCard: React.FC<Props> = props => {
48+
const navigation = useNavigation<EdgeAppSceneProps<'home'>['navigation']>()
49+
navigation.push('send2', { walletId, tokenId })
50+
}
51+
52+
// After (option 2) — navigation callbacks
53+
interface Props { onSend: (walletId: string, tokenId: EdgeTokenId) => void }
54+
```
55+
- If the fix would cascade to many callers or require determining the correct navigator context across multiple usages, add a `// TODO: Replace NavigationBase with useNavigation() or callbacks. Requires v7 navigation migration.` comment and move on.
3956

40-
// After
41-
import type { AppNavigation } from '../types/routerTypes'
42-
export function myAction(navigation: AppNavigation): ThunkAction<...> {
57+
**Category C — Shared action/thunk functions** (functions in `src/actions/` accept `NavigationBase`):
58+
- Fix: Invert control. Replace the `navigation: NavigationBase` parameter with a callback for the navigation action the function needs.
59+
```typescript
60+
// Before — function navigates internally
61+
function activateWalletTokens(navigation: NavigationBase, wallet, tokenIds): ThunkAction<Promise<void>> {
62+
// ... calls navigation.navigate('editToken', ...) internally
63+
}
64+
65+
// After — caller provides the navigate action
66+
function activateWalletTokens(wallet, tokenIds, onNavigate: (route: string, params: object) => void): ThunkAction<Promise<void>> {
67+
// ... calls onNavigate('editToken', ...) instead
68+
}
4369
```
70+
- Simpler alternative for single-navigate functions: Return the target route + params instead of navigating; let the caller dispatch.
71+
- If the function has many navigate calls to different screens or the refactoring would touch many callers, add a `// TODO: Remove NavigationBase dependency. Requires inversion of navigation control for v7 migration.` comment and move on.
72+
73+
**Category D — Shared modal components** (modals accept `NavigationBase`, navigate after user interaction):
74+
- Fix: Modal returns a result via Airship bridge resolve; caller handles navigation based on the result. Or modal accepts navigation callbacks.
75+
- If the modal's navigation logic is complex (multiple paths), add a comment and move on.
76+
77+
**Category E — Scene component casts** (`navigation as NavigationBase`):
78+
- These casts exist because the scene passes navigation to a Category A-D consumer.
79+
- Fix: No direct fix needed — casts disappear automatically when the consumer is migrated.
80+
- If the scene has its own `NavigationBase` usage unrelated to shared code, apply Category B fix.
4481

45-
**Why `as` casts are still required**: Composite scene navigation types (e.g. `WalletsTabSceneProps<'transactionList'>['navigation']`) are not structurally assignable to flat navigation types due to `PrivateValueStore` phantom types and contravariance in `dispatch`. The cast is the intended escape hatch.
82+
**Category F — Service components** (non-scene services: `DeepLinkingManager`, `AccountCallbackManager`, etc.):
83+
- These are the broadest migration cases. Always add: `// TODO: Remove NavigationBase dependency. Requires broader v7 navigation migration for service-level navigation.`
84+
- Do not attempt to fix these incrementally — they are cross-cutting and require dedicated migration work.
4685
</pattern>
4786

4887
<pattern id="route-prop" rule="@typescript-eslint/no-deprecated" symbol="RouteProp">

.cursor/skills/im/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ If the script auto-fixes files or remaining findings exist:
8181
`lint-commit.sh` treats passed file arguments as the primary commit scope, auto-includes generated companion files like `src/locales/strings`, `eslint.config.mjs`, and snapshots, and reports any additional non-generated files it stages.
8282

8383
This ensures the subsequent feature commit introduces zero pre-existing lint findings. This is the initial pass — if you discover additional files to modify during Step 3, the same check applies (see Step 3).
84+
85+
**Warning graduation (edge-react-gui)**: `edge-react-gui` has a suppression list in `eslint.config.mjs` that turns `explicit-function-return-type`, `strict-boolean-expressions`, `use-unknown-in-catch-callback-variable`, and `ban-ts-comment` to warning severity for ~300+ files. When `lint-commit.sh` commits a file, `update-eslint-warnings.ts` removes it from this list — "graduating" the file to full error enforcement. If a graduated file has pre-existing violations on lines you touched, `lint-commit.sh` Step 2b will block the commit. Running `lint-warnings.sh` here in Step 2 catches and fixes these issues before graduation occurs.
8486
</step>
8587

8688
<step id="3" name="Implementation">

0 commit comments

Comments
 (0)