webui: add ESLint and eslint-typescript
I've historically found this stuff worthwhile, so let's swallow the pill.
Fortunately, sketch was happy to oblige.
- Install ESLint, @eslint/js, and typescript-eslint packages
- Configure eslint.config.mjs with recommended TypeScript ESLint rules
- Add browser globals support for DOM and web APIs
- Integrate ESLint into npm test workflow via package.json scripts
- Update Makefile to run lint checks as part of test suite
- Fix 249+ linting issues including:
* Remove unused imports and variables (with _ prefix convention)
* Fix case declaration issues with eslint-disable blocks
* Remove unnecessary escape characters
* Address prefer-const violations
* Handle unused function parameters appropriately
- Configure ignore patterns to exclude dist/ and node_modules/
- Set rules to allow explicit 'any' types temporarily
- Convert warnings for ts-ignore, async promise executors, and unsafe optional chaining
Results:
- ESLint now runs successfully with 0 errors and only 6 warnings
- TypeScript compilation continues to work correctly
- Linting integrated into test workflow for continuous quality enforcement
- Codebase follows consistent ESLint TypeScript recommended practices
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sd7b538be0a28d294k
diff --git a/webui/src/web-components/demo/chat-input.ts b/webui/src/web-components/demo/chat-input.ts
index 7ddcc7e..746d9ce 100644
--- a/webui/src/web-components/demo/chat-input.ts
+++ b/webui/src/web-components/demo/chat-input.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo fixture for sketch-chat-input component
*/
diff --git a/webui/src/web-components/demo/demo-fixtures/view-mode-select.ts b/webui/src/web-components/demo/demo-fixtures/view-mode-select.ts
index 5e2df2d..8747e6e 100644
--- a/webui/src/web-components/demo/demo-fixtures/view-mode-select.ts
+++ b/webui/src/web-components/demo/demo-fixtures/view-mode-select.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Shared demo fixtures for SketchViewModeSelect component
*/
diff --git a/webui/src/web-components/demo/demo-framework/demo-runner.ts b/webui/src/web-components/demo/demo-framework/demo-runner.ts
index a547c0a..1c9160c 100644
--- a/webui/src/web-components/demo/demo-framework/demo-runner.ts
+++ b/webui/src/web-components/demo/demo-framework/demo-runner.ts
@@ -1,13 +1,9 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo runner that dynamically loads and executes demo modules
*/
-import {
- DemoModule,
- DemoRegistry,
- DemoRunnerOptions,
- DemoNavigationEvent,
-} from "./types";
+import { DemoModule, DemoRunnerOptions, DemoNavigationEvent } from "./types";
export class DemoRunner {
private container: HTMLElement;
diff --git a/webui/src/web-components/demo/mocks/browser.ts b/webui/src/web-components/demo/mocks/browser.ts
index 0e05730..30e2210 100644
--- a/webui/src/web-components/demo/mocks/browser.ts
+++ b/webui/src/web-components/demo/mocks/browser.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";
diff --git a/webui/src/web-components/demo/mocks/handlers.ts b/webui/src/web-components/demo/mocks/handlers.ts
index 29f0710..b5753a1 100644
--- a/webui/src/web-components/demo/mocks/handlers.ts
+++ b/webui/src/web-components/demo/mocks/handlers.ts
@@ -1,6 +1,5 @@
-import { http, HttpResponse, delay } from "msw";
+import { http, HttpResponse } from "msw";
import { initialState, initialMessages } from "../../../fixtures/dummy";
-import { AgentMessage, State } from "../../../types";
// Mock state updates for SSE simulation
const EMPTY_CONVERSATION =
@@ -43,11 +42,10 @@
}
// Simulate heartbeats and new messages
- let heartbeatInterval;
let messageInterval;
// Send heartbeats every 30 seconds
- heartbeatInterval = setInterval(() => {
+ const heartbeatInterval = setInterval(() => {
controller.enqueue(
encoder.encode(
formatSSE("heartbeat", { timestamp: new Date().toISOString() }),
diff --git a/webui/src/web-components/demo/sketch-app-shell.demo.ts b/webui/src/web-components/demo/sketch-app-shell.demo.ts
index d0ee53c..332b0fb 100644
--- a/webui/src/web-components/demo/sketch-app-shell.demo.ts
+++ b/webui/src/web-components/demo/sketch-app-shell.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-app-shell component
*/
diff --git a/webui/src/web-components/demo/sketch-call-status.demo.ts b/webui/src/web-components/demo/sketch-call-status.demo.ts
index 44b8c21..f01b190 100644
--- a/webui/src/web-components/demo/sketch-call-status.demo.ts
+++ b/webui/src/web-components/demo/sketch-call-status.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-call-status component
*/
diff --git a/webui/src/web-components/demo/sketch-chat-input.demo.ts b/webui/src/web-components/demo/sketch-chat-input.demo.ts
index f18c0b9..ac5f756 100644
--- a/webui/src/web-components/demo/sketch-chat-input.demo.ts
+++ b/webui/src/web-components/demo/sketch-chat-input.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-chat-input component
*/
diff --git a/webui/src/web-components/demo/sketch-container-status.demo.ts b/webui/src/web-components/demo/sketch-container-status.demo.ts
index b57412d..da0e435 100644
--- a/webui/src/web-components/demo/sketch-container-status.demo.ts
+++ b/webui/src/web-components/demo/sketch-container-status.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-container-status component
*/
diff --git a/webui/src/web-components/demo/sketch-timeline.demo.ts b/webui/src/web-components/demo/sketch-timeline.demo.ts
index 0a41250..845967b 100644
--- a/webui/src/web-components/demo/sketch-timeline.demo.ts
+++ b/webui/src/web-components/demo/sketch-timeline.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-timeline component
*/
@@ -38,7 +39,7 @@
name: "bash",
input: `echo "Tool call example ${i}"`,
tool_call_id: `call_${i}`,
- args: `{"command": "echo \"Tool call example ${i}\""}`,
+ args: `{"command": "echo 'Tool call example ${i}'"}`,
result: `Tool call example ${i}`,
},
]
diff --git a/webui/src/web-components/demo/sketch-tool-calls.demo.ts b/webui/src/web-components/demo/sketch-tool-calls.demo.ts
index f279657..80eda26 100644
--- a/webui/src/web-components/demo/sketch-tool-calls.demo.ts
+++ b/webui/src/web-components/demo/sketch-tool-calls.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-tool-calls component
*/
diff --git a/webui/src/web-components/demo/sketch-view-mode-select.demo.ts b/webui/src/web-components/demo/sketch-view-mode-select.demo.ts
index c187fbd..523f371 100644
--- a/webui/src/web-components/demo/sketch-view-mode-select.demo.ts
+++ b/webui/src/web-components/demo/sketch-view-mode-select.demo.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Demo module for sketch-view-mode-select component
*/
@@ -253,7 +254,7 @@
examplesContainer.style.cssText =
"display: flex; flex-direction: column; gap: 20px; margin: 20px 0;";
- containerExamples.forEach((example, index) => {
+ containerExamples.forEach((example) => {
// Create container wrapper
const wrapper = document.createElement("div");
wrapper.style.cssText = `