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
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,7 @@
|
||||
import { useState, useMemo, useEffect } from 'react';
|
||||
import { ZoomIn, RotateCcw, Minus } from 'lucide-react';
|
||||
import { useCurveStore } from '../../store/curveStore';
|
||||
import type { VFPoint } from '../../types';
|
||||
import { useState, useMemo } from "react";
|
||||
import { ZoomIn, RotateCcw, Minus } from "lucide-react";
|
||||
import { useCurveStore } from "../../store/curveStore.js";
|
||||
import type { VFPoint } from "../../types.js";
|
||||
|
||||
interface Props {
|
||||
/** All curve points — used by global offset slider */
|
||||
@@ -18,23 +18,44 @@ interface Props {
|
||||
onZoomChange: (factor: number) => void;
|
||||
}
|
||||
|
||||
export function CurveToolbar({ activePts, onResetZoom, isZoomed, readOnly, zoomFactor, onZoomChange }: Props) {
|
||||
const { pendingDeltas, selectedPoints, anchorPoint, curve, stageRangeEdit, flattenToAnchor } = useCurveStore();
|
||||
export function CurveToolbar({
|
||||
activePts,
|
||||
onResetZoom,
|
||||
isZoomed,
|
||||
readOnly,
|
||||
zoomFactor,
|
||||
onZoomChange,
|
||||
}: Props) {
|
||||
const {
|
||||
pendingDeltas,
|
||||
selectedPoints,
|
||||
anchorPoint,
|
||||
curve,
|
||||
stageRangeEdit,
|
||||
flattenToAnchor,
|
||||
} = useCurveStore();
|
||||
|
||||
const [offsetMhz, setOffsetMhz] = useState(0);
|
||||
|
||||
const uniformDeltaMhz = useMemo(() => {
|
||||
if (activePts.length === 0) return 0;
|
||||
const firstD = pendingDeltas.get(activePts[0].index) ?? activePts[0].delta_khz;
|
||||
const uniform = activePts.every((p) => (pendingDeltas.get(p.index) ?? p.delta_khz) === firstD);
|
||||
const firstD =
|
||||
pendingDeltas.get(activePts[0].index) ?? activePts[0].delta_khz;
|
||||
const uniform = activePts.every(
|
||||
(p) => (pendingDeltas.get(p.index) ?? p.delta_khz) === firstD,
|
||||
);
|
||||
return uniform ? firstD / 1000 : null;
|
||||
}, [activePts, pendingDeltas]);
|
||||
|
||||
useEffect(() => {
|
||||
if (uniformDeltaMhz !== null) {
|
||||
setOffsetMhz(uniformDeltaMhz);
|
||||
}
|
||||
}, [uniformDeltaMhz]);
|
||||
// Sync the slider to the uniform delta when it changes (adjust state during
|
||||
// render instead of an effect; undefined sentinel so the first render syncs).
|
||||
const [lastUniformDelta, setLastUniformDelta] = useState<
|
||||
number | null | undefined
|
||||
>();
|
||||
if (uniformDeltaMhz !== null && lastUniformDelta !== uniformDeltaMhz) {
|
||||
setLastUniformDelta(uniformDeltaMhz);
|
||||
setOffsetMhz(uniformDeltaMhz);
|
||||
}
|
||||
|
||||
function handleOffsetChange(mhz: number) {
|
||||
setOffsetMhz(mhz);
|
||||
@@ -44,7 +65,10 @@ export function CurveToolbar({ activePts, onResetZoom, isZoomed, readOnly, zoomF
|
||||
return (
|
||||
<div className="flex flex-wrap items-center gap-2 px-1 pb-2">
|
||||
{/* Zoom control */}
|
||||
<div className="flex items-center gap-1.5 px-2 py-1 rounded bg-zinc-800/60 border border-zinc-700/40" title="Zoom x-axis (Alt+scroll also works)">
|
||||
<div
|
||||
className="flex items-center gap-1.5 px-2 py-1 rounded bg-zinc-800/60 border border-zinc-700/40"
|
||||
title="Zoom x-axis (Alt+scroll also works)"
|
||||
>
|
||||
<ZoomIn size={11} className="text-zinc-500 shrink-0" />
|
||||
<input
|
||||
type="range"
|
||||
@@ -55,7 +79,9 @@ export function CurveToolbar({ activePts, onResetZoom, isZoomed, readOnly, zoomF
|
||||
onChange={(e) => onZoomChange(Number(e.target.value))}
|
||||
className="w-20 h-1 cursor-pointer accent-cyan-400"
|
||||
/>
|
||||
<span className={`text-xs font-mono w-8 tabular-nums ${isZoomed ? 'text-cyan-400' : 'text-zinc-600'}`}>
|
||||
<span
|
||||
className={`text-xs font-mono w-8 tabular-nums ${isZoomed ? "text-cyan-400" : "text-zinc-600"}`}
|
||||
>
|
||||
{zoomFactor.toFixed(1)}×
|
||||
</span>
|
||||
{isZoomed && (
|
||||
@@ -75,7 +101,9 @@ export function CurveToolbar({ activePts, onResetZoom, isZoomed, readOnly, zoomF
|
||||
{/* Global offset slider — GPU only */}
|
||||
{!readOnly && uniformDeltaMhz !== null && (
|
||||
<div className="flex items-center gap-1.5 min-w-[260px]">
|
||||
<span className="text-zinc-500 text-xs whitespace-nowrap">Global Offset</span>
|
||||
<span className="text-zinc-500 text-xs whitespace-nowrap">
|
||||
Global Offset
|
||||
</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-1000}
|
||||
@@ -84,46 +112,63 @@ export function CurveToolbar({ activePts, onResetZoom, isZoomed, readOnly, zoomF
|
||||
value={offsetMhz}
|
||||
onChange={(e) => handleOffsetChange(Number(e.target.value))}
|
||||
className="w-32 accent-cyan-400"
|
||||
title={`${offsetMhz > 0 ? '+' : ''}${offsetMhz} MHz`}
|
||||
title={`${offsetMhz > 0 ? "+" : ""}${offsetMhz} MHz`}
|
||||
/>
|
||||
<span
|
||||
className={[
|
||||
'text-xs font-mono w-16',
|
||||
offsetMhz > 0 ? 'text-cyan-400' : offsetMhz < 0 ? 'text-orange-400' : 'text-zinc-500',
|
||||
].join(' ')}
|
||||
"text-xs font-mono w-16",
|
||||
offsetMhz > 0
|
||||
? "text-cyan-400"
|
||||
: offsetMhz < 0
|
||||
? "text-orange-400"
|
||||
: "text-zinc-500",
|
||||
].join(" ")}
|
||||
>
|
||||
{offsetMhz > 0 ? '+' : ''}{offsetMhz} MHz
|
||||
{offsetMhz > 0 ? "+" : ""}
|
||||
{offsetMhz} MHz
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Flatten — visible when 2+ points are selected */}
|
||||
{!readOnly && selectedPoints.size >= 2 && (() => {
|
||||
const anchor = anchorPoint !== null && selectedPoints.has(anchorPoint)
|
||||
? anchorPoint
|
||||
: Math.min(...selectedPoints);
|
||||
const anchorDelta =
|
||||
pendingDeltas.get(anchor) ??
|
||||
curve?.points.find(p => p.index === anchor)?.delta_khz ??
|
||||
0;
|
||||
const label = `·${anchor} ${anchorDelta >= 0 ? '+' : ''}${anchorDelta / 1000} MHz`;
|
||||
return (
|
||||
<button
|
||||
onClick={flattenToAnchor}
|
||||
className="flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium text-amber-400 hover:text-amber-300 hover:bg-zinc-800 border border-zinc-700/40 transition"
|
||||
title={`Flatten all selected points to anchor point ${anchor} (${anchorDelta >= 0 ? '+' : ''}${anchorDelta / 1000} MHz)`}
|
||||
>
|
||||
<Minus size={11} />
|
||||
Flatten to {label}
|
||||
</button>
|
||||
);
|
||||
})()}
|
||||
{!readOnly &&
|
||||
selectedPoints.size >= 2 &&
|
||||
(() => {
|
||||
const anchor =
|
||||
anchorPoint !== null && selectedPoints.has(anchorPoint)
|
||||
? anchorPoint
|
||||
: Math.min(...selectedPoints);
|
||||
const anchorDelta =
|
||||
pendingDeltas.get(anchor) ??
|
||||
curve?.points.find((p) => p.index === anchor)?.delta_khz ??
|
||||
0;
|
||||
const label = `·${anchor} ${anchorDelta >= 0 ? "+" : ""}${anchorDelta / 1000} MHz`;
|
||||
return (
|
||||
<button
|
||||
onClick={flattenToAnchor}
|
||||
className="flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium text-amber-400 hover:text-amber-300 hover:bg-zinc-800 border border-zinc-700/40 transition"
|
||||
title={`Flatten all selected points to anchor point ${anchor} (${anchorDelta >= 0 ? "+" : ""}${anchorDelta / 1000} MHz)`}
|
||||
>
|
||||
<Minus size={11} />
|
||||
Flatten to {label}
|
||||
</button>
|
||||
);
|
||||
})()}
|
||||
|
||||
{/* Legend — right-aligned */}
|
||||
<div className="flex items-center gap-3 text-xs text-zinc-500 ml-auto">
|
||||
<span className="flex items-center gap-1"><span className="inline-block w-3 h-0.5 bg-emerald-400 rounded" /> effective</span>
|
||||
<span className="flex items-center gap-1"><span className="inline-block w-3 h-px border-t-2 border-dashed border-cyan-400" /> pending</span>
|
||||
<span className="flex items-center gap-1"><span className="inline-block w-2 h-2 rounded-full bg-yellow-400" /> current</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="inline-block w-3 h-0.5 bg-emerald-400 rounded" />{" "}
|
||||
effective
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="inline-block w-3 h-px border-t-2 border-dashed border-cyan-400" />{" "}
|
||||
pending
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="inline-block w-2 h-2 rounded-full bg-yellow-400" />{" "}
|
||||
current
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fmt } from '../../utils/units';
|
||||
import type { VFPoint } from '../../types';
|
||||
import { fmt } from '../../utils/units.js';
|
||||
import type { VFPoint } from '../../types.js';
|
||||
|
||||
interface Props {
|
||||
point: VFPoint;
|
||||
@@ -21,15 +21,7 @@ export function CurveTooltip({ point, pendingDeltaKhz, isClamped }: Props) {
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
pointerEvents: 'none',
|
||||
zIndex: 50,
|
||||
width: 172,
|
||||
}}
|
||||
className="bg-zinc-800 border border-zinc-700 rounded-md p-2 text-xs shadow-xl"
|
||||
className="absolute right-4 bottom-4 pointer-events-none z-50 w-[172px] bg-zinc-800 border border-zinc-700 rounded-md p-2 text-xs shadow-xl"
|
||||
>
|
||||
<div className="text-zinc-400 mb-1">Point {point.index}</div>
|
||||
<div className="text-zinc-200">
|
||||
|
||||
Reference in new issue
Block a user