fix: add react doctor and resolve reported errors
Some checks failed
CI — NoteLett / Web — typecheck + test + build (push) Failing after 2s
CI — NoteLett / Backend — typecheck + test + build (push) Failing after 2s
CI — NoteLett / Mobile — typecheck (push) Failing after 1s
CI — NoteLett / E2E — Playwright (push) Failing after 1s

This commit is contained in:
Saravana Kumar 2026-05-28 00:35:28 +00:00
parent 3683ba9dd2
commit fd8afb2742
9 changed files with 1129 additions and 11 deletions

View File

@ -0,0 +1,46 @@
---
name: react-doctor
description: Use when finishing a feature, fixing a bug, before committing React code, or when the user types `/doctor`, asks to scan, triage, or clean up React diagnostics. Covers lint, accessibility, bundle size, architecture. Includes a regression check and a full local-triage workflow that fetches the canonical playbook.
version: "1.1.0"
---
# React Doctor
Scans React codebases for security, performance, correctness, and architecture issues. Outputs a 0100 health score.
## After making React code changes:
Run `npx react-doctor@latest --verbose --diff` and check the score did not regress.
If the score dropped, fix the regressions before committing.
## For general cleanup or code improvement:
Run `npx react-doctor@latest --verbose` (without `--diff`) to scan the full codebase. Fix issues by severity — errors first, then warnings.
## /doctor — full local triage workflow
When the user types `/doctor`, says "run react doctor", or asks for a full triage / cleanup pass (not just a regression check), fetch the canonical local-triage playbook and follow every step in it:
```bash
curl --fail --silent --show-error \
--header 'Cache-Control: no-cache' \
https://www.react.doctor/prompts/react-doctor-agent.md
```
The playbook is the single source of truth — a scan → filter → triage → fix → validate loop that edits the working tree directly (never commits, never opens PRs). Updating the prompt at its source updates every agent on its next fetch — no skill reinstall needed.
Pair it with the matching per-rule prompts at `https://www.react.doctor/prompts/rules/<plugin>/<rule>.md` (fetched on demand inside the playbook) so each fix uses the canonical, reviewer-tested recipe.
## Command
```bash
npx react-doctor@latest --verbose --diff
```
| Flag | Purpose |
| ----------- | --------------------------------------------- |
| `.` | Scan current directory |
| `--verbose` | Show affected files and line numbers per rule |
| `--diff` | Only scan changed files vs base branch |
| `--score` | Output only the numeric score |

View File

@ -0,0 +1,46 @@
---
name: react-doctor
description: Use when finishing a feature, fixing a bug, before committing React code, or when the user types `/doctor`, asks to scan, triage, or clean up React diagnostics. Covers lint, accessibility, bundle size, architecture. Includes a regression check and a full local-triage workflow that fetches the canonical playbook.
version: "1.1.0"
---
# React Doctor
Scans React codebases for security, performance, correctness, and architecture issues. Outputs a 0100 health score.
## After making React code changes:
Run `npx react-doctor@latest --verbose --diff` and check the score did not regress.
If the score dropped, fix the regressions before committing.
## For general cleanup or code improvement:
Run `npx react-doctor@latest --verbose` (without `--diff`) to scan the full codebase. Fix issues by severity — errors first, then warnings.
## /doctor — full local triage workflow
When the user types `/doctor`, says "run react doctor", or asks for a full triage / cleanup pass (not just a regression check), fetch the canonical local-triage playbook and follow every step in it:
```bash
curl --fail --silent --show-error \
--header 'Cache-Control: no-cache' \
https://www.react.doctor/prompts/react-doctor-agent.md
```
The playbook is the single source of truth — a scan → filter → triage → fix → validate loop that edits the working tree directly (never commits, never opens PRs). Updating the prompt at its source updates every agent on its next fetch — no skill reinstall needed.
Pair it with the matching per-rule prompts at `https://www.react.doctor/prompts/rules/<plugin>/<rule>.md` (fetched on demand inside the playbook) so each fix uses the canonical, reviewer-tested recipe.
## Command
```bash
npx react-doctor@latest --verbose --diff
```
| Flag | Purpose |
| ----------- | --------------------------------------------- |
| `.` | Scan current directory |
| `--verbose` | Show affected files and line numbers per rule |
| `--diff` | Only scan changed files vs base branch |
| `--score` | Output only the numeric score |

View File

@ -134,8 +134,8 @@ export default function CaptureScreen() {
const isActive = workspace.id === activeWorkspaceId;
return (
<Pressable
{...buttonA11y(`Select workspace ${workspace.name}`, { selected: isActive })}
key={workspace.id}
{...buttonA11y(`Select workspace ${workspace.name}`, { selected: isActive })}
onPress={() => setActiveWorkspace(workspace.id)}
style={[styles.workspaceChip, isActive ? styles.workspaceChipActive : null]}
>

View File

@ -55,8 +55,8 @@ export default function HomeScreen() {
return (
<Pressable
{...buttonA11y(`Filter by ${workspace.name}`, { selected: isActive })}
key={workspace.id}
{...buttonA11y(`Filter by ${workspace.name}`, { selected: isActive })}
onPress={() => setActiveWorkspace(workspace.id)}
style={[styles.workspaceChip, isActive ? styles.workspaceChipActive : null]}
>
@ -70,7 +70,7 @@ export default function HomeScreen() {
{isLoading ? <Text style={styles.empty}>Loading notes</Text> : null}
{recentNotes.map((note: (typeof recentNotes)[number]) => (
<Pressable {...buttonA11y(`Open note ${note.title}`)} key={note.id} onPress={() => router.push(`/note/${note.id}`)} style={styles.card}>
<Pressable key={note.id} {...buttonA11y(`Open note ${note.title}`)} onPress={() => router.push(`/note/${note.id}`)} style={styles.card}>
<View style={styles.badgeRow}>
<Text style={styles.badge}>{note.workspace}</Text>
</View>

View File

@ -50,7 +50,7 @@ export default function SearchScreen() {
<View style={styles.list}>
{isLoading ? <Text style={styles.empty}>Loading searchable notes</Text> : null}
{results.map((note: MobileNote) => (
<Pressable {...buttonA11y(`Open note ${note.title}`)} key={note.id} onPress={() => router.push(`/note/${note.id}`)} style={styles.row}>
<Pressable key={note.id} {...buttonA11y(`Open note ${note.title}`)} onPress={() => router.push(`/note/${note.id}`)} style={styles.row}>
<Text style={styles.rowText}>{note.title}</Text>
</Pressable>
))}

View File

@ -69,8 +69,8 @@ export default function SettingsScreen() {
const isActive = type === feedbackType;
return (
<Pressable
{...buttonA11y(`Select ${type} feedback type`, { selected: isActive })}
key={type}
{...buttonA11y(`Select ${type} feedback type`, { selected: isActive })}
style={[styles.typeChip, isActive ? styles.typeChipActive : null]}
onPress={() => setFeedbackType(type)}
>

View File

@ -20,10 +20,12 @@
"audit:ui:ratchet:update": "bash scripts/ui-drift-ratchet.sh --update",
"dependency:health": "bash scripts/dependency-health.sh",
"verify": "pnpm run typecheck && pnpm run test && pnpm run build",
"prepare": "husky"
"prepare": "husky",
"doctor": "react-doctor --project @notelett/web,@notelett/mobile"
},
"devDependencies": {
"husky": "^9.0.0"
"husky": "^9.0.0",
"react-doctor": "^0.2.9"
},
"pnpm": {
"overrides": {

1030
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -205,7 +205,7 @@ export function AppShellNavItem({ className, ...props }: AppShellNavItemProps) {
return <BytelystAppShellNavItem className={className} {...props} />;
}
export function getStatusTone(status: NoteLettStatus): StatusTone {
function getStatusTone(status: NoteLettStatus): StatusTone {
return statusToneMap[status];
}