fix linting

This commit is contained in:
Noah Waldner
2026-02-27 11:37:40 +01:00
parent 8be7c9eb59
commit 1424373895
9 changed files with 29 additions and 28 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ export default tseslint.config(
tseslint.configs.recommended, tseslint.configs.recommended,
{ {
rules: { rules: {
'no-console': 'warn', 'no-console': 'off',
'no-debugger': 'error', 'no-debugger': 'error',
// Relax some rules that conflict with existing patterns // Relax some rules that conflict with existing patterns
'@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-explicit-any': 'warn',
+2 -2
View File
@@ -1892,7 +1892,7 @@ export class RalphTracker extends EventEmitter {
* @fires phraseValidationWarning - When a risky phrase is detected * @fires phraseValidationWarning - When a risky phrase is detected
*/ */
private validateCompletionPhrase(phrase: string): void { private validateCompletionPhrase(phrase: string): void {
const normalized = phrase.toUpperCase().replace(/[\s_\-\.]+/g, ''); const normalized = phrase.toUpperCase().replace(/[\s_\-.]+/g, '');
// Generate a suggested unique phrase // Generate a suggested unique phrase
const uniqueSuffix = Date.now().toString(36).slice(-4).toUpperCase(); const uniqueSuffix = Date.now().toString(36).slice(-4).toUpperCase();
@@ -3520,7 +3520,7 @@ export class RalphTracker extends EventEmitter {
const tasksHeaderPattern = /^##\s*Tasks/i; const tasksHeaderPattern = /^##\s*Tasks/i;
// Pattern for todo items // Pattern for todo items
const todoPattern = /^-\s*\[([ x\-])\]\s*(.+)$/; const todoPattern = /^-\s*\[([ x-])\]\s*(.+)$/;
let inCompletedSection = false; let inCompletedSection = false;
+1 -1
View File
@@ -62,7 +62,7 @@ export class SessionLifecycleLog {
} }
const lines = raw.trim().split('\n').filter(Boolean); const lines = raw.trim().split('\n').filter(Boolean);
let entries: LifecycleEntry[] = []; const entries: LifecycleEntry[] = [];
// Parse in reverse (newest first) for efficiency with limit // Parse in reverse (newest first) for efficiency with limit
for (let i = lines.length - 1; i >= 0 && entries.length < limit; i--) { for (let i = lines.length - 1; i >= 0 && entries.length < limit; i--) {
+3
View File
@@ -80,6 +80,7 @@ const GRACEFUL_SHUTDOWN_DELAY_MS = 100;
// Filter out terminal focus escape sequences (focus in/out reports) // Filter out terminal focus escape sequences (focus in/out reports)
// ^[[I (focus in), ^[[O (focus out), and the enable/disable sequences // ^[[I (focus in), ^[[O (focus out), and the enable/disable sequences
// eslint-disable-next-line no-control-regex
const FOCUS_ESCAPE_FILTER = /\x1b\[\?1004[hl]|\x1b\[[IO]/g; const FOCUS_ESCAPE_FILTER = /\x1b\[\?1004[hl]|\x1b\[[IO]/g;
// Pattern to match Task tool invocations in terminal output // Pattern to match Task tool invocations in terminal output
@@ -90,8 +91,10 @@ const TASK_TOOL_PATTERN = /\b(Explore|Task|Bash|Plan|general-purpose)\(([^)]+)\)
// Pre-compiled patterns for hot paths (avoid regex compilation per call) // Pre-compiled patterns for hot paths (avoid regex compilation per call)
/** Pattern to strip leading ANSI escapes and whitespace from terminal buffer */ /** Pattern to strip leading ANSI escapes and whitespace from terminal buffer */
// eslint-disable-next-line no-control-regex
const LEADING_ANSI_WHITESPACE_PATTERN = /^(\x1b\[\??[\d;]*[A-Za-z]|[\s\r\n])+/; const LEADING_ANSI_WHITESPACE_PATTERN = /^(\x1b\[\??[\d;]*[A-Za-z]|[\s\r\n])+/;
/** Pattern to match Ctrl+L (form feed) characters */ /** Pattern to match Ctrl+L (form feed) characters */
// eslint-disable-next-line no-control-regex
const CTRL_L_PATTERN = /\x0c/g; const CTRL_L_PATTERN = /\x0c/g;
/** Pattern to split by newlines (CR or LF) */ /** Pattern to split by newlines (CR or LF) */
const NEWLINE_SPLIT_PATTERN = /\r?\n/; const NEWLINE_SPLIT_PATTERN = /\r?\n/;
+1 -1
View File
@@ -894,7 +894,7 @@ export class SubagentWatcher extends EventEmitter {
const MAX_LEN = SMART_TITLE_MAX_LENGTH; const MAX_LEN = SMART_TITLE_MAX_LENGTH;
// Get first line/sentence // Get first line/sentence
let title = text.split('\n')[0].trim(); const title = text.split('\n')[0].trim();
// If already short enough, use it // If already short enough, use it
if (title.length <= MAX_LEN) { if (title.length <= MAX_LEN) {
+6 -3
View File
@@ -17,8 +17,8 @@
* Use this when you need complete ANSI stripping including OSC sequences. * Use this when you need complete ANSI stripping including OSC sequences.
* Note: Has global flag - reset lastIndex before exec() if reusing. * Note: Has global flag - reset lastIndex before exec() if reusing.
*/ */
export const ANSI_ESCAPE_PATTERN_FULL = // eslint-disable-next-line no-control-regex
/\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g; export const ANSI_ESCAPE_PATTERN_FULL = /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g;
/** /**
* Simple ANSI CSI-only pattern for basic escape code stripping. * Simple ANSI CSI-only pattern for basic escape code stripping.
@@ -27,6 +27,7 @@ export const ANSI_ESCAPE_PATTERN_FULL =
* Use this for faster stripping when OSC sequences aren't a concern. * Use this for faster stripping when OSC sequences aren't a concern.
* Note: Has global flag - reset lastIndex before exec() if reusing. * Note: Has global flag - reset lastIndex before exec() if reusing.
*/ */
// eslint-disable-next-line no-control-regex
export const ANSI_ESCAPE_PATTERN_SIMPLE = /\x1b\[[0-9;]*[A-Za-z]/g; export const ANSI_ESCAPE_PATTERN_SIMPLE = /\x1b\[[0-9;]*[A-Za-z]/g;
/** /**
@@ -44,6 +45,7 @@ export const TOKEN_PATTERN = /(\d+(?:\.\d+)?)\s*([kKmM])?\s*tokens/;
* Use when you need a pattern without shared lastIndex state. * Use when you need a pattern without shared lastIndex state.
*/ */
export function createAnsiPatternFull(): RegExp { export function createAnsiPatternFull(): RegExp {
// eslint-disable-next-line no-control-regex
return /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g; return /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g;
} }
@@ -52,6 +54,7 @@ export function createAnsiPatternFull(): RegExp {
* Use when you need a pattern without shared lastIndex state. * Use when you need a pattern without shared lastIndex state.
*/ */
export function createAnsiPatternSimple(): RegExp { export function createAnsiPatternSimple(): RegExp {
// eslint-disable-next-line no-control-regex
return /\x1b\[[0-9;]*[A-Za-z]/g; return /\x1b\[[0-9;]*[A-Za-z]/g;
} }
@@ -75,4 +78,4 @@ export function stripAnsi(text: string): string {
*/ */
export const SPINNER_PATTERN = /[⠋⠙⠹⠸⠼⠴⠦⠧]/; export const SPINNER_PATTERN = /[⠋⠙⠹⠸⠼⠴⠦⠧]/;
export const SAFE_PATH_PATTERN = /^[a-zA-Z0-9_\/\-. ~]+$/; export const SAFE_PATH_PATTERN = /^[a-zA-Z0-9_/\-. ~]+$/;
+10 -16
View File
@@ -245,29 +245,23 @@ export class StaleExpirationMap<K, V> implements Disposable {
/** /**
* Get all keys (non-expired). * Get all keys (non-expired).
*/ */
keys(): IterableIterator<K> { *keys(): IterableIterator<K> {
const self = this; for (const [key, entry] of this.entries) {
return (function* () { if (!this.isExpired(entry)) {
for (const [key, entry] of self.entries) { yield key;
if (!self.isExpired(entry)) {
yield key;
}
} }
})(); }
} }
/** /**
* Get all values (non-expired). * Get all values (non-expired).
*/ */
values(): IterableIterator<V> { *values(): IterableIterator<V> {
const self = this; for (const [, entry] of this.entries) {
return (function* () { if (!this.isExpired(entry)) {
for (const [, entry] of self.entries) { yield entry.value;
if (!self.isExpired(entry)) {
yield entry.value;
}
} }
})(); }
} }
/** /**
+1 -1
View File
@@ -139,7 +139,7 @@ export function isSimilarByDistance(a: string, b: string, maxDistance = 2): bool
export function normalizePhrase(phrase: string): string { export function normalizePhrase(phrase: string): string {
return phrase return phrase
.toUpperCase() .toUpperCase()
.replace(/[\s_\-\.]+/g, '') // Remove whitespace, underscores, hyphens, dots .replace(/[\s_\-.]+/g, '') // Remove whitespace, underscores, hyphens, dots
.trim(); .trim();
} }
+4 -3
View File
@@ -195,7 +195,9 @@ const ITERATION_PAUSE_MS = 2000;
// Set high (32KB) to allow effective batching; avg Ink events are ~14KB // Set high (32KB) to allow effective batching; avg Ink events are ~14KB
const BATCH_FLUSH_THRESHOLD = 32 * 1024; const BATCH_FLUSH_THRESHOLD = 32 * 1024;
// Pre-compiled regex for terminal buffer cleaning (avoids per-request compilation) // Pre-compiled regex for terminal buffer cleaning (avoids per-request compilation)
// eslint-disable-next-line no-control-regex
const CLAUDE_BANNER_PATTERN = /\x1b\[1mClaud/; const CLAUDE_BANNER_PATTERN = /\x1b\[1mClaud/;
// eslint-disable-next-line no-control-regex
const CTRL_L_PATTERN = /\x0c/g; const CTRL_L_PATTERN = /\x0c/g;
const LEADING_WHITESPACE_PATTERN = /^[\s\r\n]+/; const LEADING_WHITESPACE_PATTERN = /^[\s\r\n]+/;
@@ -445,7 +447,6 @@ export class WebServer extends EventEmitter {
// Flag to prevent new timers during shutdown // Flag to prevent new timers during shutdown
private _isStopping: boolean = false; private _isStopping: boolean = false;
// Cached light state for SSE init (avoids rebuilding on every reconnect) // Cached light state for SSE init (avoids rebuilding on every reconnect)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private cachedLightState: { data: Record<string, unknown>; timestamp: number } | null = null; private cachedLightState: { data: Record<string, unknown>; timestamp: number } | null = null;
private static readonly LIGHT_STATE_CACHE_TTL_MS = 1000; private static readonly LIGHT_STATE_CACHE_TTL_MS = 1000;
// Cached sessions list for getLightSessionsState() (avoids re-serializing all sessions on every call) // Cached sessions list for getLightSessionsState() (avoids re-serializing all sessions on every call)
@@ -3019,7 +3020,7 @@ export class WebServer extends EventEmitter {
status: 'pending' | 'in_progress' | 'completed'; status: 'pending' | 'in_progress' | 'completed';
priority: string | null; priority: string | null;
}> = []; }> = [];
const todoPattern = /^-\s*\[([ xX\-])\]\s*(.+)$/; const todoPattern = /^-\s*\[([ xX-])\]\s*(.+)$/;
const p0HeaderPattern = /^##\s*(High Priority|Critical|P0|Critical Path)/i; const p0HeaderPattern = /^##\s*(High Priority|Critical|P0|Critical Path)/i;
const p1HeaderPattern = /^##\s*(Standard|P1|Medium Priority)/i; const p1HeaderPattern = /^##\s*(Standard|P1|Medium Priority)/i;
const p2HeaderPattern = /^##\s*(Nice to Have|P2|Low Priority)/i; const p2HeaderPattern = /^##\s*(Nice to Have|P2|Low Priority)/i;
@@ -4040,8 +4041,8 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
.replace(/\n/g, '\\n') .replace(/\n/g, '\\n')
.replace(/\r/g, '\\r') .replace(/\r/g, '\\r')
.replace(/\t/g, '\\t') .replace(/\t/g, '\\t')
// eslint-disable-next-line no-control-regex
.replace( .replace(
// eslint-disable-next-line no-control-regex
/[\x00-\x1f]/g, /[\x00-\x1f]/g,
(c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}` (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`
) )