Skip to content

Commit a713803

Browse files
Merge pull request #163 from laststance/chore/react-doctor-findings
chore: address react doctor findings
2 parents b545604 + ae646ab commit a713803

9 files changed

Lines changed: 45 additions & 25 deletions

File tree

e2e/fixtures/electron-app.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export const test = baseTest.extend<ElectronFixtures>({
3434
// eslint-disable-next-line no-empty-pattern
3535
isolatedHome: async ({}, use) => {
3636
const home = createIsolatedHome()
37+
// Playwright's fixture callback is named `use`; this is not a React Hook.
38+
// react-doctor-disable-next-line react-hooks/rules-of-hooks
3739
await use(home)
3840
destroyIsolatedHome(home)
3941
},
@@ -57,12 +59,16 @@ export const test = baseTest.extend<ElectronFixtures>({
5759
E2E_BACKGROUND_LAUNCH: process.env['E2E_BACKGROUND_LAUNCH'] ?? '1',
5860
},
5961
})
62+
// Playwright's fixture callback is named `use`; this is not a React Hook.
63+
// react-doctor-disable-next-line react-hooks/rules-of-hooks
6064
await use(app)
6165
await app.close()
6266
},
6367
appWindow: async ({ electronApp }, use) => {
6468
const window = await electronApp.firstWindow()
6569
await window.waitForLoadState('domcontentloaded')
70+
// Playwright's fixture callback is named `use`; this is not a React Hook.
71+
// react-doctor-disable-next-line react-hooks/rules-of-hooks
6672
await use(window)
6773
},
6874
})

e2e/helpers/redux.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export async function getStoreState<T, A = undefined>(
5757
'window.__store__ is not exposed. Did you build with E2E_BUILD=1?',
5858
)
5959
}
60+
// Test selectors are trusted code passed by specs; dynamic rebuild is
61+
// what preserves helpful selector-source errors across the browser wall.
62+
// react-doctor-disable-next-line react-doctor/no-eval
6063
const fn = new Function(
6164
'state',
6265
'args',

src/renderer/src/bootstrap.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import { readFileSync } from 'node:fs'
2222
import { resolve } from 'node:path'
23+
import { runInThisContext } from 'node:vm'
2324

2425
import { beforeEach, describe, expect, it } from 'vitest'
2526

@@ -119,10 +120,9 @@ function installStorageMock(): StorageMock {
119120

120121
function runBootstrap(): void {
121122
const script = loadBootstrapScript()
122-
// Using `new Function` (not `eval`) keeps the script in its own lexical
123-
// scope so test-file locals can't leak in. The IIFE wrapper inside the
124-
// script provides its own isolation on top of that.
125-
new Function(script)()
123+
// Run the inline script in the global VM context so test-file locals cannot
124+
// leak in while `document` and `localStorage` stay available.
125+
runInThisContext(script, { filename: 'renderer-theme-bootstrap.js' })
126126
}
127127

128128
beforeEach(() => {

src/renderer/src/components/skills/UndoToast.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const UndoToast = React.memo(function UndoToast({
7575
toastId,
7676
}: UndoToastProps): React.ReactElement {
7777
const expiresAtMs = new Date(expiresAt).getTime()
78-
const [remainingMs, setRemainingMs] = useState(
78+
const [remainingMs, setRemainingMs] = useState(() =>
7979
Math.max(0, expiresAtMs - Date.now()),
8080
)
8181
const [isRestoring, setIsRestoring] = useState(false)

website/src/app/page.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
import type { Metadata } from 'next'
2+
13
import { Hero } from '@/components/Hero'
24
import { Features } from '@/components/Features'
35
import { Download } from '@/components/Download'
46
import { Footer } from '@/components/Footer'
57

8+
export const metadata: Metadata = {
9+
title: 'Skills Desktop - AI Agent Skills Manager',
10+
description:
11+
'Visualize and manage installed Skills across AI agents, inspect symlink status, and keep local coding tools in sync.',
12+
}
13+
614
export default function Home() {
715
return (
816
<main className="min-h-screen">

website/src/components/Download.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ export function Download() {
88
<div className="container mx-auto px-4">
99
<div className="relative overflow-hidden rounded-2xl border border-border bg-card/30">
1010
{/* Background decoration */}
11-
<div className="absolute -right-20 -top-20 h-64 w-64 rounded-full bg-primary/10 blur-3xl" />
12-
<div className="absolute -bottom-20 -left-20 h-64 w-64 rounded-full bg-accent/10 blur-3xl" />
11+
<div className="absolute -right-20 -top-20 size-64 rounded-full bg-primary/10 blur-3xl" />
12+
<div className="absolute -bottom-20 -left-20 size-64 rounded-full bg-accent/10 blur-3xl" />
1313

1414
<div className="relative p-8 sm:p-12 lg:p-16">
1515
<div className="mx-auto max-w-3xl text-center">
16-
<h2 className="mb-4 text-3xl font-bold tracking-tight sm:text-4xl">
16+
<h2 className="mb-4 text-3xl font-semibold tracking-tight sm:text-4xl">
1717
Ready to Get Started?
1818
</h2>
1919
<p className="mb-10 text-lg text-muted-foreground">
@@ -28,7 +28,7 @@ export function Download() {
2828
href="https://github.com/laststance/skills-desktop/releases/download/v0.17.0/skills-desktop-0.17.0-arm64.dmg"
2929
className="inline-flex w-full items-center justify-center gap-3 rounded-xl bg-primary px-8 py-4 text-lg font-semibold text-primary-foreground transition-all hover:bg-primary/90 hover:scale-105 sm:w-auto"
3030
>
31-
<Apple className="h-6 w-6" />
31+
<Apple className="size-6" />
3232
<div className="text-left">
3333
<div>Download for Mac</div>
3434
<div className="text-xs font-normal opacity-80">
@@ -41,7 +41,7 @@ export function Download() {
4141
href="https://github.com/laststance/skills-desktop/releases/download/v0.17.0/skills-desktop-0.17.0-x64.dmg"
4242
className="inline-flex w-full items-center justify-center gap-3 rounded-xl border border-border bg-card/50 px-8 py-4 text-lg font-semibold transition-all hover:bg-card hover:scale-105 sm:w-auto"
4343
>
44-
<Cpu className="h-6 w-6" />
44+
<Cpu className="size-6" />
4545
<div className="text-left">
4646
<div>Download for Mac</div>
4747
<div className="text-xs font-normal text-muted-foreground">
@@ -57,7 +57,7 @@ export function Download() {
5757
href="https://github.com/laststance/skills-desktop/releases"
5858
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
5959
>
60-
<DownloadIcon className="h-4 w-4" />
60+
<DownloadIcon className="size-4" />
6161
View all releases on GitHub
6262
</a>
6363
</div>

website/src/components/Features.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export function Features() {
4747
<div className="container mx-auto px-4">
4848
{/* Section header */}
4949
<div className="mb-16 text-center">
50-
<h2 className="mb-4 text-3xl font-bold tracking-tight sm:text-4xl">
50+
<h2 className="mb-4 text-3xl font-semibold tracking-tight sm:text-4xl">
5151
Everything You Need to Manage Skills
5252
</h2>
5353
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">
@@ -58,13 +58,13 @@ export function Features() {
5858

5959
{/* Feature grid */}
6060
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
61-
{features.map((feature, index) => (
61+
{features.map((feature) => (
6262
<div
63-
key={index}
63+
key={feature.title}
6464
className="group relative rounded-xl border border-border bg-card/30 p-6 transition-all hover:border-primary/50 hover:bg-card/50"
6565
>
6666
<div className="mb-4 inline-flex rounded-lg bg-primary/10 p-3 text-primary">
67-
<feature.icon className="h-6 w-6" />
67+
<feature.icon className="size-6" />
6868
</div>
6969
<h3 className="mb-2 text-xl font-semibold">{feature.title}</h3>
7070
<p className="text-muted-foreground">{feature.description}</p>

website/src/components/Footer.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ export function Footer() {
2323
target="_blank"
2424
rel="noopener noreferrer"
2525
>
26-
<Github className="h-5 w-5" />
26+
<Github className="size-5" />
2727
</a>
2828
<a
2929
href="https://twitter.com/laaboratory"
3030
className="text-muted-foreground hover:text-foreground"
3131
target="_blank"
3232
rel="noopener noreferrer"
3333
>
34-
<Twitter className="h-5 w-5" />
34+
<Twitter className="size-5" />
3535
</a>
3636
</div>
3737

38-
<div className="text-sm text-muted-foreground">
38+
<div
39+
className="text-sm text-muted-foreground"
40+
suppressHydrationWarning
41+
>
3942
© {new Date().getFullYear()} Laststance.io. MIT License.
4043
</div>
4144
</div>

website/src/components/Hero.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ export function Hero() {
1212
<div className="flex flex-col items-center text-center">
1313
{/* Badge */}
1414
<div className="mb-6 inline-flex items-center gap-2 rounded-full border border-border bg-card/50 px-4 py-1.5 text-sm text-muted-foreground">
15-
<span className="h-2 w-2 rounded-full bg-primary animate-pulse" />
15+
<span className="size-2 rounded-full bg-primary animate-pulse" />
1616
Now available for macOS
1717
</div>
1818

1919
{/* Title */}
20-
<h1 className="mb-6 max-w-4xl text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
20+
<h1 className="mb-6 max-w-4xl text-4xl font-semibold tracking-tight sm:text-5xl lg:text-6xl">
2121
Manage Your AI Agent <span className="gradient-text">Skills</span>{' '}
2222
in One Place
2323
</h1>
@@ -34,7 +34,7 @@ export function Hero() {
3434
href="https://github.com/laststance/skills-desktop/releases/download/v0.17.0/skills-desktop-0.17.0-arm64.dmg"
3535
className="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-8 py-3 text-lg font-semibold text-primary-foreground transition-all hover:bg-primary/90 hover:scale-105"
3636
>
37-
<Apple className="h-5 w-5" />
37+
<Apple className="size-5" />
3838
<div className="text-left">
3939
<div>Download for Mac</div>
4040
<div className="text-xs font-normal opacity-80">
@@ -46,7 +46,7 @@ export function Hero() {
4646
href="https://github.com/laststance/skills-desktop/releases/download/v0.17.0/skills-desktop-0.17.0-x64.dmg"
4747
className="inline-flex items-center justify-center gap-2 rounded-lg border border-border bg-card/50 px-8 py-3 text-lg font-semibold transition-all hover:bg-card hover:scale-105"
4848
>
49-
<Cpu className="h-5 w-5" />
49+
<Cpu className="size-5" />
5050
<div className="text-left">
5151
<div>Download for Mac</div>
5252
<div className="text-xs font-normal text-muted-foreground">
@@ -69,9 +69,9 @@ export function Hero() {
6969
<div className="absolute -inset-4 rounded-2xl bg-gradient-to-r from-primary/20 via-accent/20 to-primary/20 blur-2xl" />
7070
<div className="glass relative overflow-hidden rounded-xl shadow-2xl">
7171
<div className="flex h-8 items-center gap-2 border-b border-border/50 bg-card/80 px-4">
72-
<div className="h-3 w-3 rounded-full bg-red-500" />
73-
<div className="h-3 w-3 rounded-full bg-yellow-500" />
74-
<div className="h-3 w-3 rounded-full bg-green-500" />
72+
<div className="size-3 rounded-full bg-red-500" />
73+
<div className="size-3 rounded-full bg-yellow-500" />
74+
<div className="size-3 rounded-full bg-green-500" />
7575
<span className="ml-4 text-sm text-muted-foreground">
7676
Skills Desktop
7777
</span>

0 commit comments

Comments
 (0)