Skip to content

v2.1: Linter Output Parsers — eslint, ruff, mypy, golangci-lint #104

@dean0x

Description

@dean0x

v2.1: Linter Output Parsers

Parent: #96 (Command Coverage Expansion)
Priority: High — linters are the noisiest developer tools, highest token waste
Depends on: Nothing (v2.x track, independent of v3)

Overview

Linter output is one of the highest-value compression targets: verbose, repetitive, and heavily consumed by AI agents during code review and fix cycles. All major linters support structured JSON output, making them ideal for our three-tier degradation pattern.

Parsers to Implement

eslint (JavaScript/TypeScript)

  • Structured: eslint --format json → parse JSON array of file results
  • Compression strategy:
    • Group by rule (e.g., all no-unused-vars together)
    • Deduplicate identical messages
    • Show: file, line, rule, message, severity
    • Strip: column numbers, node types, fix suggestions (unless agent is fixing)
  • Expected savings: 60-80%
  • Fixture: Real eslint output from a medium project (~50 violations)

ruff (Python)

  • Structured: ruff check --output-format json → parse JSON array
  • Compression strategy:
    • Group by rule code (e.g., E501, F841)
    • Show: file, line, code, message
    • Strip: byte offsets, fix applicability metadata
  • Expected savings: 60-75%
  • Fixture: Real ruff output from a Python project (~30 violations)

mypy (Python)

  • Structured: mypy --output json → parse JSON lines
  • Compression strategy:
    • Group by error code (e.g., arg-type, name-defined)
    • Deduplicate identical type errors across files
    • Show: file, line, severity, message
    • Strip: column numbers, internal error codes
  • Expected savings: 50-70%
  • Fixture: Real mypy output with type errors (~20 violations)

golangci-lint (Go)

  • Structured: golangci-lint run --out-format json → parse JSON
  • Compression strategy:
    • Group by linter name (e.g., govet, errcheck, staticcheck)
    • Show: file, line, linter, message
    • Strip: source line text (agent can read the file), column info
  • Expected savings: 60-75%
  • Fixture: Real golangci-lint output from a Go project

Implementation Pattern

Each parser follows the established three-tier degradation:

```rust
pub fn parse_eslint(raw: &str) -> ParseResult {
// Tier 1: Structured (JSON)
if let Ok(results) = serde_json::from_str::<Vec>(raw) {
return compress_eslint_json(results);
}

// Tier 2: Regex fallback
if let Some(compressed) = compress_eslint_regex(raw) {
    return compressed;
}

// Tier 3: Passthrough (never corrupt)
ParseResult::passthrough(raw)

}
```

CLI Integration

```bash

Direct usage

eslint src/ --format json | skim lint
eslint src/ --format json | skim lint --format eslint

Via skim rewrite (hook mode)

skim rewrite "eslint src/"

→ Rewrites to: eslint src/ --format json 2>&1 | skim lint --format eslint

Auto-detection

eslint src/ | skim lint # Detects eslint from output patterns
ruff check . | skim lint # Detects ruff
mypy src/ | skim lint # Detects mypy
golangci-lint run | skim lint # Detects golangci-lint
```

Subcommand: skim lint

New subcommand alongside existing skim test, skim git, skim build:

```rust
// crates/rskim/src/commands/lint.rs
pub fn compress_lint_output(raw: &str, format: Option) -> Result {
let format = format.unwrap_or_else(|| detect_lint_format(raw));
match format {
LintFormat::Eslint => parse_eslint(raw),
LintFormat::Ruff => parse_ruff(raw),
LintFormat::Mypy => parse_mypy(raw),
LintFormat::GolangciLint => parse_golangci_lint(raw),
}
}
```

Testing

  • Unit tests per parser with real output fixtures
  • Three-tier degradation: verify each tier activates correctly
  • Guardrail: compressed output never larger than raw
  • Integration: skim init adds lint command hooks
  • Integration: skim rewrite generates correct lint commands

Acceptance Criteria

  • All 4 linter parsers implemented with three-tier degradation
  • Each parser has real-world output fixtures (not synthetic)
  • Token savings: 50-80% across all linters
  • skim lint subcommand with auto-detection
  • skim init updated to hook lint commands for supported agents
  • skim rewrite generates correct rewrite rules
  • Zero regression in existing parser tests
  • Analytics tracking for lint command savings

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestphase-bPhase B: Command Output Optimization

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions