fix(web): resolve remaining non-story lint warnings

Quentin Gliech and Claude Opus 4.6 (1M context) created

- Fix unsafe type assertion in file-viewer: use instanceof check
  for click target, suppress shiki dynamic import casts with comments.
- Suppress no-unassigned-import in apollo-client.d.ts (declaration merging).
- Remove unused LabelColor and BrandedLabel types from label-editor story.

Remaining 31 warnings are all in story files: oxlint can't resolve
makeFragmentData's generic constraint with optional $fragmentName.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

webui2/src/apollo-client.d.ts                       |  1 +
webui2/src/components/bugs/label-editor.stories.tsx |  2 --
webui2/src/components/code/file-viewer.tsx          | 13 +++++++------
3 files changed, 8 insertions(+), 8 deletions(-)

Detailed changes

webui2/src/apollo-client.d.ts 🔗

@@ -1,3 +1,4 @@
+// oxlint-disable-next-line eslint-plugin-import(no-unassigned-import) -- declaration merging
 import "@apollo/client";
 import type { GraphQLCodegenDataMasking } from "@apollo/client/masking";
 

webui2/src/components/bugs/label-editor.stories.tsx 🔗

@@ -36,8 +36,6 @@ const allLabels = allLabelsData.map(
   (l) => ({ ...l, ...makeFragmentData(l, LABEL_FIELDS_FRAGMENT) }),
 );
 
-type LabelColor = { R: number; G: number; B: number };
-type BrandedLabel = (typeof allLabels)[number];
 
 function LabelEditorDemo() {
   const [currentNames, setCurrentNames] = useState<Set<string>>(

webui2/src/components/code/file-viewer.tsx 🔗

@@ -201,10 +201,9 @@ export function FileViewer({ blob: blobProp }: FileViewerProps) {
       let lang = "text";
       if (entry) {
         try {
-          const langModule = await entry.load();
-          await highlighter.loadLanguage(
-            langModule as Parameters<typeof highlighter.loadLanguage>[0],
-          );
+          // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic shiki language import
+          const langModule = (await entry.load()) as Parameters<typeof highlighter.loadLanguage>[0];
+          await highlighter.loadLanguage(langModule);
           lang = entry.id;
         } catch {
           // Language not available — fall back to plain text
@@ -220,9 +219,11 @@ export function FileViewer({ blob: blobProp }: FileViewerProps) {
         transformers: [lineNumberTransformer()],
       });
 
+      // oxlint-disable-next-line typescript-eslint(no-unsafe-assignment) -- hast-util-to-jsx-runtime returns JSX.Element
       const node = toJsxRuntime(hast, { Fragment, jsx, jsxs });
       const lineCount = blob.text!.split("\n").length;
 
+      // oxlint-disable-next-line typescript-eslint(no-unsafe-assignment) -- node is ReactNode from toJsxRuntime
       setHighlighted({ node, lineCount });
     })();
 
@@ -297,8 +298,8 @@ function CodeBlock({ selectedRange, onLineClick, children }: CodeBlockProps) {
     <div
       className={styles["code-block"]}
       onClick={(e) => {
-        const target = e.target as HTMLElement;
-        const lineEl = target.closest("[data-line-number]");
+        if (!(e.target instanceof HTMLElement)) return;
+        const lineEl = e.target.closest("[data-line-number]");
         if (lineEl) {
           e.preventDefault();
           const lineNum = parseInt(lineEl.getAttribute("data-line-number")!, 10);