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/mobile-chat.ts b/webui/src/web-components/mobile-chat.ts
index 26ef963..bd3a9e3 100644
--- a/webui/src/web-components/mobile-chat.ts
+++ b/webui/src/web-components/mobile-chat.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
@@ -479,9 +480,7 @@
return html`
<div class="tool-calls">
${message.tool_calls.map((toolCall) => {
- const statusIcon = this.getToolStatusIcon(toolCall);
const summary = this.getToolSummary(toolCall);
- const duration = this.getToolDuration(toolCall);
return html`
<div class="tool-call-item ${toolCall.name}">
@@ -494,7 +493,7 @@
`;
}
- private getToolStatusIcon(toolCall: any): string {
+ private getToolStatusIcon(_toolCall: any): string {
// Don't show status icons for mobile
return "";
}
@@ -503,6 +502,7 @@
try {
const input = JSON.parse(toolCall.input || "{}");
+ /* eslint-disable no-case-declarations */
switch (toolCall.name) {
case "bash":
const command = input.command || "";
@@ -571,12 +571,13 @@
? inputStr.substring(0, 50) + "..."
: inputStr;
}
- } catch (e) {
+ /* eslint-enable no-case-declarations */
+ } catch {
return "Tool call";
}
}
- private getToolDuration(toolCall: any): string {
+ private getToolDuration(_toolCall: any): string {
// Don't show duration for mobile
return "";
}
@@ -605,7 +606,7 @@
: displayMessages.map((message) => {
const role = this.getMessageRole(message);
const text = this.getMessageText(message);
- const timestamp = message.timestamp;
+ // const timestamp = message.timestamp; // Unused for mobile layout
return html`
<div class="message ${role}">