Clean up LSP diagnostics across backend and frontend
Backend (nvcurve/): - hal/fans.py, hal/limits.py, hal/gpu.py: replace conditional pynvml imports with the established 'pynvml: Any = _pynvml_import' pattern (fixes ~50 'possibly unbound' errors); type the result dicts; guard query_interface() results; explicit uuid/pci-bus parsing (int, hex convention documented); modernize Optional[T] -> T | None - cli.py: fix 'curve_state' possibly-unbound and snap_path None handling in cmd_setup; wrap unchecked int()/open()/makedirs() calls in try/except with clean CLI errors; add module logger for silent except-pass blocks; raise ... from exc; fix unused loop vars and set-comprehension - hal/snapshot.py: filepath: str | None; wrap all file ops; sorted imports; remove unused CT_POINTS import - daemon.py: extract 0o666 to _SOCKET_MODE constant (intentional for /run sockets) with nosemgrep - server.py: nosemgrep for Python 3.7-compat false positive (project requires >= 3.12); log previously-swallowed exception - profiles/native.py, profiles/apply.py: wrap file ops and int(k) profile-key parsing; sorted imports; modernize typing Frontend (frontend/src): - Add .js extensions to all relative imports (standard TS-ESM; Vite resolves .js -> .ts) - React.FormEvent (deprecated in React 19 types) -> React.SubmitEvent - catch (e: any) -> catch (e: unknown) + instanceof Error narrowing - React-hooks: move ref writes from render into effects; convert viewport reset to render-phase state adjustment; split selectPoint(index, multi) into selectPoint + togglePoint (no flag argument); remove non-null assertion - Static inline styles -> Tailwind classes (dynamic positioning/cursor styles kept) - Remove non-standard 'container' option from scrollIntoView (browsers ignore unknown options) which had orphaned a @ts-expect-error - Object.fromEntries for Map -> Record conversion Tooling: - .gitignore: ignore .codegraph/ local tool data Verified: tsc --noEmit, vite production build, python imports, and full LSP scan (0 errors/warnings in both projects).
This commit is contained in:
1 parent
9006c22fde
commit
930e56bd07
33 files changed
+1571
-804
No files matched your search
@@ -8,10 +8,14 @@ import {
|
||||
Star,
|
||||
Fan,
|
||||
} from "lucide-react";
|
||||
import { api } from "../../api/client";
|
||||
import type { ProfileData } from "../../types";
|
||||
import { api } from "../../api/client.js";
|
||||
import type { ProfileData } from "../../types.js";
|
||||
import { toast } from "sonner";
|
||||
import { useCurveStore } from "../../store/curveStore";
|
||||
import { useCurveStore } from "../../store/curveStore.js";
|
||||
|
||||
function errMsg(e: unknown): string {
|
||||
return e instanceof Error ? e.message : String(e);
|
||||
}
|
||||
|
||||
interface ProfilePanelProps {
|
||||
activeProfile: string | null;
|
||||
@@ -65,37 +69,42 @@ export function ProfilePanel({
|
||||
setAutoLoadProfile(name);
|
||||
if (name) toast.success(`"${name}" will load on server start`);
|
||||
else toast.success("Auto-load cleared");
|
||||
} catch (e: any) {
|
||||
toast.error(
|
||||
"Failed to update default profile: " + (e.message || String(e)),
|
||||
);
|
||||
} catch (e: unknown) {
|
||||
toast.error("Failed to update default profile: " + errMsg(e));
|
||||
}
|
||||
}
|
||||
|
||||
// Data fetch on GPU change — setState calls happen after the await, not
|
||||
// synchronously in the effect body (rule false-positive on async fetch).
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
fetchProfiles();
|
||||
}, [selectedGpuIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isSaveOpen) saveInputRef.current?.focus();
|
||||
else setNewName("");
|
||||
}, [isSaveOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (renamingName) renameInputRef.current?.focus();
|
||||
}, [renamingName]);
|
||||
|
||||
async function handleSave(e: React.FormEvent) {
|
||||
function closeSaveForm() {
|
||||
setIsSaveOpen(false);
|
||||
setNewName("");
|
||||
}
|
||||
|
||||
async function handleSave(e: React.SubmitEvent) {
|
||||
e.preventDefault();
|
||||
if (!newName.trim()) return;
|
||||
try {
|
||||
setIsSaving(true);
|
||||
await api.saveProfile(newName.trim(), selectedGpuIndex);
|
||||
toast.success(`Profile "${newName.trim()}" saved`);
|
||||
setIsSaveOpen(false);
|
||||
closeSaveForm();
|
||||
await fetchProfiles();
|
||||
} catch (e: any) {
|
||||
toast.error("Failed to save: " + (e.message || String(e)));
|
||||
} catch (e: unknown) {
|
||||
toast.error("Failed to save: " + errMsg(e));
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
@@ -107,8 +116,8 @@ export function ProfilePanel({
|
||||
await api.applyProfile(name, selectedGpuIndex);
|
||||
onProfileApplied(name);
|
||||
toast.success(`"${name}" applied`);
|
||||
} catch (e: any) {
|
||||
toast.error(`Failed to apply "${name}": ` + (e.message || String(e)));
|
||||
} catch (e: unknown) {
|
||||
toast.error(`Failed to apply "${name}": ` + errMsg(e));
|
||||
} finally {
|
||||
setApplyingName(null);
|
||||
}
|
||||
@@ -123,14 +132,14 @@ export function ProfilePanel({
|
||||
if (autoLoadProfile === name) setAutoLoadProfile(null);
|
||||
setDeletingName(null);
|
||||
await fetchProfiles();
|
||||
} catch (e: any) {
|
||||
toast.error("Failed to delete: " + (e.message || String(e)));
|
||||
} catch (e: unknown) {
|
||||
toast.error("Failed to delete: " + errMsg(e));
|
||||
} finally {
|
||||
setIsDeleting(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRename(e: React.FormEvent, oldName: string) {
|
||||
async function handleRename(e: React.SubmitEvent, oldName: string) {
|
||||
e.preventDefault();
|
||||
if (!renameValue.trim() || renameValue.trim() === oldName) {
|
||||
setRenamingName(null);
|
||||
@@ -144,8 +153,8 @@ export function ProfilePanel({
|
||||
if (autoLoadProfile === oldName) setAutoLoadProfile(renameValue.trim());
|
||||
setRenamingName(null);
|
||||
await fetchProfiles();
|
||||
} catch (e: any) {
|
||||
toast.error("Failed to rename: " + (e.message || String(e)));
|
||||
} catch (e: unknown) {
|
||||
toast.error("Failed to rename: " + errMsg(e));
|
||||
} finally {
|
||||
setIsRenaming(false);
|
||||
}
|
||||
@@ -179,7 +188,7 @@ export function ProfilePanel({
|
||||
value={newName}
|
||||
onChange={(e) => setNewName(e.target.value)}
|
||||
disabled={isSaving}
|
||||
onKeyDown={(e) => e.key === "Escape" && setIsSaveOpen(false)}
|
||||
onKeyDown={(e) => e.key === "Escape" && closeSaveForm()}
|
||||
className="flex-1 min-w-0 bg-zinc-950 border border-zinc-700 rounded px-3 py-1.5 text-sm focus:outline-none focus:border-pink-500 focus:ring-1 focus:ring-pink-500 disabled:opacity-50"
|
||||
/>
|
||||
<button
|
||||
@@ -191,7 +200,7 @@ export function ProfilePanel({
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsSaveOpen(false)}
|
||||
onClick={closeSaveForm}
|
||||
className="px-3 py-1.5 text-zinc-400 hover:text-zinc-200 rounded text-sm transition shrink-0"
|
||||
>
|
||||
Cancel
|
||||
|
||||
Reference in new issue
Block a user