diff --git a/backend/eslint.config.mjs b/backend/eslint.config.mjs index 5e51e519..869f8ac9 100644 --- a/backend/eslint.config.mjs +++ b/backend/eslint.config.mjs @@ -9,6 +9,18 @@ export default tseslint.config( languageOptions: { ecmaVersion: 2022 }, rules: { '@typescript-eslint/no-explicit-any': 'warn', + // Allow unused catch-clause vars (catch (error) { ... }) and _-prefixed intentional ignores + '@typescript-eslint/no-unused-vars': ['error', { + caughtErrors: 'none', + varsIgnorePattern: '^_', + argsIgnorePattern: '^_', + }], + // Pre-existing patterns — warn rather than error until addressed + '@typescript-eslint/ban-ts-comment': 'warn', + '@typescript-eslint/no-namespace': 'warn', + 'no-empty': 'warn', + // Terminal output processing intentionally uses control characters in regexes + 'no-control-regex': 'off', 'no-console': 'off', }, }, diff --git a/backend/src/index.ts b/backend/src/index.ts index 9eaf9472..9fe152a9 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -16,8 +16,6 @@ import si from 'systeminformation'; import http from 'http'; import httpProxy from 'http-proxy'; import { createProxyMiddleware } from 'http-proxy-middleware'; -import { spawn, exec } from 'child_process'; -import { promisify } from 'util'; import path from 'path'; import { HostTerminalService } from './services/HostTerminalService'; import { DatabaseService } from './services/DatabaseService'; @@ -31,8 +29,6 @@ import { isValidStackName, isValidRemoteUrl } from './utils/validation'; import YAML from 'yaml'; import fs, { promises as fsPromises } from 'fs'; -const execAsync = promisify(exec); - // Suppress [DEP0060] DeprecationWarning emitted by http-proxy@1.18.1 which calls // util._extend internally. The warning fires at runtime when createProxyServer() is // first invoked (NOT at import time), so intercepting process.emitWarning here - @@ -1147,7 +1143,7 @@ app.get('/api/logs/global', async (req: Request, res: Response) => { await Promise.all(containers.map(async (c) => { const stackName = c.Labels?.['com.docker.compose.project'] || 'system'; - let rawName = c.Names?.[0]?.replace(/^\//, '') || c.Id.substring(0, 12); + const rawName = c.Names?.[0]?.replace(/^\//, '') || c.Id.substring(0, 12); // Standardize naming: Strip stack name prefix if it exists let containerName = rawName; @@ -1247,7 +1243,7 @@ app.get('/api/logs/global/stream', async (req: Request, res: Response) => { await Promise.all(containers.map(async (c) => { const stackName = c.Labels?.['com.docker.compose.project'] || 'system'; - let rawName = c.Names?.[0]?.replace(/^\//, '') || c.Id.substring(0, 12); + const rawName = c.Names?.[0]?.replace(/^\//, '') || c.Id.substring(0, 12); let containerName = rawName; if (rawName.startsWith(`${stackName}-`)) containerName = rawName.replace(`${stackName}-`, '').replace(/-1$/, ''); else if (rawName.startsWith(`${stackName}_`)) containerName = rawName.replace(`${stackName}_`, '').replace(/_1$/, ''); diff --git a/backend/src/services/ComposeService.ts b/backend/src/services/ComposeService.ts index 7cbb2855..76f07ea8 100644 --- a/backend/src/services/ComposeService.ts +++ b/backend/src/services/ComposeService.ts @@ -110,7 +110,7 @@ export class ComposeService { if (exitCode !== 0) { const logs = await container.logs({ stdout: true, stderr: true, tail: 50 }); - let logStr = logs.toString('utf-8'); + const logStr = logs.toString('utf-8'); throw new Error(`CONTAINER_CRASHED\nExit Code: ${exitCode}\n${logStr}`); } } @@ -157,7 +157,7 @@ export class ComposeService { let activeProcesses = 0; let streamEndedHandled = false; - let localProcesses: ReturnType[] = []; + const localProcesses: ReturnType[] = []; const onWsClose = () => { localProcesses.forEach(cp => { try { cp.kill(); } catch { } }); diff --git a/backend/src/services/DockerController.ts b/backend/src/services/DockerController.ts index 5c60c7c3..36d90c2c 100644 --- a/backend/src/services/DockerController.ts +++ b/backend/src/services/DockerController.ts @@ -65,7 +65,7 @@ class DockerController { const calculateReclaimableVolumes = (items: any[]) => { if (!items || !Array.isArray(items)) return 0; return items.filter(i => i.UsageData?.RefCount === 0).reduce((acc, item) => { - let size = item.UsageData?.Size || 0; + const size = item.UsageData?.Size || 0; return acc + size; }, 0); }; @@ -551,7 +551,7 @@ class DockerController { } } -export let globalDockerNetwork = { rxSec: 0, txSec: 0 }; +export const globalDockerNetwork = { rxSec: 0, txSec: 0 }; let lastNetSum = { rx: 0, tx: 0, timestamp: Date.now() }; export const updateGlobalDockerNetwork = async () => { diff --git a/backend/src/services/FileSystemService.ts b/backend/src/services/FileSystemService.ts index 91e06bca..54889602 100644 --- a/backend/src/services/FileSystemService.ts +++ b/backend/src/services/FileSystemService.ts @@ -1,5 +1,4 @@ import path from 'path'; -import fs from 'fs'; import { promises as fsPromises } from 'fs'; import { NodeRegistry } from './NodeRegistry'; diff --git a/backend/src/services/LogFormatter.ts b/backend/src/services/LogFormatter.ts index c582b304..dd78464a 100644 --- a/backend/src/services/LogFormatter.ts +++ b/backend/src/services/LogFormatter.ts @@ -51,7 +51,7 @@ export class LogFormatter { // Fast JSON Check (Starts with { and ends with }) if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) { try { - const parsed = JSON.parse(trimmedLine); + JSON.parse(trimmedLine); // If valid, lightly highlight it (e.g., colorize string representation slightly) // We re-stringify it to ensure it's on one line, but maybe just highlight properties processedLine = LogFormatter.highlightJson(trimmedLine); diff --git a/backend/src/services/MonitorService.ts b/backend/src/services/MonitorService.ts index 4a09b252..81865318 100644 --- a/backend/src/services/MonitorService.ts +++ b/backend/src/services/MonitorService.ts @@ -164,7 +164,7 @@ export class MonitorService { try { const parsed = JSON.parse(line); // RECLAIMABLE might be something like "1.2GB" or "400MB" Let's parse it manually or just use raw sizes from docker api. Actually docker system df JSON format gives Reclaimable field as string e.g. "1.196GB" (or "0B"). - let reclaimStr = parsed.Reclaimable; + const reclaimStr = parsed.Reclaimable; if (reclaimStr) { // Extract the number and the unit. e.g "1.196GB" (92%) -> 1.196 const match = reclaimStr.match(/^([0-9.]+)([a-zA-Z]+)/);