Get the FREE Ultimate OpenClaw Setup Guide →

ls-lint

npx machina-cli add skill PaulRBerg/agent-skills/ls-lint --openclaw
Files (1)
SKILL.md
7.8 KB

ls-lint v2.3

Version Notice: This skill documents ls-lint v2.3 specifically. Before proceeding, verify the installed version matches:

ls-lint --version
# or
npx @ls-lint/ls-lint --version

If a different version is installed, stop and consult the official documentation for that version at https://ls-lint.org or the GitHub repository at https://github.com/loeffel-io/ls-lint. Configuration syntax and available rules may differ between versions.

An extremely fast directory and filename linter that enforces naming conventions across project filesystems.

Official Resources:

Key features:

  • Processes thousands of files in milliseconds
  • Minimal configuration via .ls-lint.yml
  • Cross-platform: Windows, macOS, Linux
  • Full Unicode support
  • Minimal dependencies (go-yaml, doublestar)

Installation

# NPM (recommended)
npm install -D @ls-lint/ls-lint

# NPX (no install)
npx @ls-lint/ls-lint

# Homebrew (macOS/Linux)
brew install ls-lint

# Direct download (Linux amd64)
curl -sL -o ls-lint https://github.com/loeffel-io/ls-lint/releases/download/v2.3.1/ls-lint-linux-amd64
chmod +x ls-lint

Configuration Basics

Create .ls-lint.yml in the project root with two main sections:

ls:
  # Rules for directories and file extensions
  .js: kebab-case
  .ts: kebab-case

ignore:
  # Paths to exclude from linting
  - .git
  - node_modules

Running ls-lint

# Run with default config (.ls-lint.yml)
npx @ls-lint/ls-lint

# Custom config path
ls-lint --config path/to/.ls-lint.yml

# Custom working directory
ls-lint --workdir /path/to/project

Built-in Rules

Six naming convention rules are available:

RuleDescriptionExample
lowercaseAll lowercase letters, ignores non-lettersreadme, test
camelCasecamelCase, letters and digits onlymyFile
PascalCasePascalCase, letters and digits onlyMyComponent
snake_caseLowercase with underscoresmy_file
SCREAMING_SNAKE_CASEUppercase with underscoresMY_CONSTANT
kebab-caseLowercase with hyphensmy-file

Combining Rules

Use the pipe operator | to allow multiple conventions:

ls:
  .ts: camelCase | PascalCase   # Either is valid
  .js: kebab-case | snake_case

Extensions & Sub-extensions

Standard Extensions

Apply rules to specific file types:

ls:
  .js: kebab-case
  .ts: kebab-case
  .json: kebab-case
  .md: SCREAMING_SNAKE_CASE   # README.md, CHANGELOG.md

Sub-extensions

Handle compound extensions like .d.ts, .test.js, .module.css:

ls:
  .d.ts: kebab-case           # Type definition files
  .test.ts: kebab-case        # Test files
  .module.css: kebab-case     # CSS modules
  .config.js: kebab-case      # Config files

Wildcard Extension

Match all extensions with .*:

ls:
  .*: kebab-case              # All files must be kebab-case

Directory Naming

Use .dir to enforce directory name conventions:

ls:
  .dir: kebab-case            # All directories must be kebab-case

Path Patterns

Global Rules

Rules at the top level apply project-wide:

ls:
  .js: kebab-case             # Applies everywhere
  .ts: kebab-case

ignore:
  - node_modules

Directory-Specific Rules

Override global rules for specific directories:

ls:
  .js: kebab-case             # Global default

  components:                 # Override for components/
    .js: PascalCase

  src/models:                 # Override for src/models/
    .js: PascalCase

Directory rules apply to the specified directory and all its subdirectories.

Glob Patterns

Use wildcards for flexible path matching:

ls:
  # Single wildcard: matches one directory level
  packages/*/src:
    .ts: kebab-case

  # Double wildcard: matches any depth
  packages/**/components:
    .tsx: PascalCase

Alternative Patterns

Use curly braces for multiple alternatives:

ls:
  packages/*/{src,tests}:
    .ts: kebab-case

  src/{components,pages}:
    .tsx: PascalCase

Advanced Rules

Regex Patterns

For custom naming patterns, use regex with regex:^pattern$ format:

ls:
  # Files must start with uppercase letter
  .ts: regex:^[A-Z].*$

  # Allow files starting with underscore or letter
  .js: regex:^[_a-z][a-zA-Z0-9]*$

Combine regex with built-in rules:

ls:
  .ts: PascalCase | regex:^index$   # PascalCase OR "index"

Directory Substitution

Reference parent directory names in patterns:

ls:
  # File must match parent directory name
  components/*/:
    .tsx: regex:^${0}$   # ${0} = parent directory name

Exists Rule

Enforce file quantity constraints:

ls:
  # Exactly one index file required
  src/:
    index.ts: exists:1

  # Between 1-5 test files allowed
  tests/:
    .test.ts: exists:1-5

  # No image files allowed
  src/:
    .png: exists:0
    .jpg: exists:0

Combine with naming rules:

ls:
  .ts: kebab-case | exists:1   # Must be kebab-case AND exactly one

Common Configurations

JavaScript/TypeScript Project

ls:
  .dir: kebab-case
  .js: kebab-case
  .ts: kebab-case
  .tsx: PascalCase           # React components
  .d.ts: kebab-case
  .json: kebab-case
  .md: SCREAMING_SNAKE_CASE

  src/components:
    .tsx: PascalCase

ignore:
  - .git
  - node_modules
  - dist
  - coverage

Monorepo Pattern

ls:
  .dir: kebab-case
  .*: kebab-case

  packages/*/src:
    .ts: kebab-case
    .tsx: PascalCase

  packages/*/{src,tests}:
    .dir: kebab-case

ignore:
  - .git
  - node_modules
  - "**/dist"
  - "**/coverage"
  - "**/build"

GitHub Actions Integration

Basic workflow configuration:

# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]

jobs:
  ls-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ls-lint/action@v2

Action Configuration Options

- uses: ls-lint/action@v2
  with:
    config: .ls-lint.yml          # Config file path
    workdir: .                    # Working directory
    error-output-format: text     # text or json
    warn: false                   # Output to stdout, exit 0
    debug: false                  # Enable debug output

Troubleshooting

Common Issues

No files matched: Verify path patterns match actual directory structure.

Rule not applying: Check for more specific rules that might override.

Ignore not working: Ensure ignore patterns use correct glob syntax.

Debug Mode

Run with verbose output to diagnose issues:

ls-lint --debug

External Resources

For features not covered in this skill, consult:

The official documentation covers additional features like:

  • Multiple configuration files
  • Bazel integration
  • Docker usage
  • Complete regex syntax

Source

git clone https://github.com/PaulRBerg/agent-skills/blob/main/skills/ls-lint/SKILL.mdView on GitHub

Overview

ls-lint is an extremely fast directory and filename linter that enforces naming conventions across project filesystems. It uses a minimal .ls-lint.yml configuration and a set of built-in rules to keep file and directory names consistent across platforms.

How This Skill Works

ls-lint reads the .ls-lint.yml configuration, applies extension-specific rules (such as .js: kebab-case or .ts: kebab-case), and reports any violations. It supports sub-extensions, wildcard extensions, directory naming via .dir, and combining rules with the pipe operator, enabling scalable linting across large projects in milliseconds.

When to Use It

  • When you want to configure or set up filename linting with ls-lint
  • When enforcing consistent file naming across a codebase
  • When applying directory naming rules to ensure folder names conform
  • When working with multiple extensions and sub-extensions (e.g., .d.ts, .test.js)
  • When integrating naming conventions checks into CI or local development

Quick Start

  1. Step 1: Install ls-lint (npm install -D @ls-lint/ls-lint) or run via npx
  2. Step 2: Create .ls-lint.yml at project root with rules (e.g., ls: .js: kebab-case, .dir: kebab-case)
  3. Step 3: Run ls-lint (npx @ls-lint/ls-lint) or ls-lint --config path/to/.ls-lint.yml

Best Practices

  • Start with a focused set of extension rules before expanding to more types
  • Use the .dir rule to enforce directory naming across the project
  • Combine multiple valid conventions with the | operator (e.g., .js: kebab-case | snake_case)
  • Run ls-lint locally first, then add it to CI to catch regressions
  • Pin the ls-lint version and align your .ls-lint.yml with the installed tool

Example Use Cases

  • Web app: enforce kebab-case for .js and .ts files and kebab-case for directory names
  • Library: apply camelCase to internal files while keeping public APIs in PascalCase
  • Monorepo: use sub-extensions like .module.css and .test.ts with appropriate rules
  • Documentation-heavy project: use SCREAMING_SNAKE_CASE for constants and kebab-case for files
  • Data processing project: enforce lowercase filenames with underscores in data pipelines

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers