Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ While the major version is 0, minor version bumps may contain breaking changes.

## [Unreleased]

### Added

- `lash explain` now knows every code `lash lint` emits. The per-rule syntax,
semantic and cross-file codes (`E_SYNTAX_*`, `E_SEM_*`, `E_NOTE_*`,
`E_LINK_*`, `W_INDEX_ORPHAN`, and the `W_`/`I_` variants) previously answered
"Unknown error code", so following the advice in lint's own output was a dead
end. Warnings and info-level codes are also labelled as such rather than
introduced as errors.
- Lint's summary names one of the codes it just reported alongside the
`lash explain` invocation for it.

### Fixed

- `.lashignore` is reachable from where users hit it. The `W_INDEX_ORPHAN`
warning names it in the message text, `lash lint --help` and `lash --help`
describe file discovery, and the README, user guide and error-code reference
document it. The mechanism already worked; nothing pointed at it (#58).
- `lash explain --list` no longer drops codes whose prefix matched no category.
Every `W_` and `I_` code was silently missing from the listing.

## [0.4.0] - 2026-08-11

A task's ID is derived from its title rather than stored, so a change to the
Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ This project follows strict quality standards:
- **Pre-commit hooks**: Auto-enforces formatting, linting, and tests
- **Zero warnings**: All clippy lints must pass with `clippy::pedantic`
- **Comprehensive tests**: 3,000+ tests across all crates (>80% coverage target)
- **Error taxonomy**: 50+ documented error codes in `docs/error-codes.md`
- **Error taxonomy**: 75+ documented error codes in `docs/error-codes.md`, all queryable with `lash explain`
- **Doctests**: All public APIs include executable examples
- **CI/CD**: Automated testing on Linux, macOS, and Windows

Expand Down Expand Up @@ -264,8 +264,28 @@ lash lint [PATH...] [--fix] [--interactive]

# Format task files (alias: fmt)
lash format [PATH...] [--check] [--diff]

# Explain any code the linter reports
lash explain W_INDEX_ORPHAN
lash explain --list
```

### Excluding Files

Commands that walk the project (`lint`, `format`, `index`, `check-index`,
`check-links`) read every `.md` file under the project root, skipping anything
excluded by `.gitignore` or by a `.lashignore` at the project root.
`.lashignore` uses `.gitignore` syntax, so a directory of Markdown that is not
task files is one line:

```bash
printf 'content/\n' >> .lashignore
```

Without it, each such file is reported once per run as `W_INDEX_ORPHAN` ("not
referenced in the root index"). Common documentation filenames and the `docs/`
directory are exempt already.

### Indexing & Database

```bash
Expand Down
2 changes: 1 addition & 1 deletion crates/lash-agent/src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ lash skill install --target T # Install Lash skill into a coding agent (claude
lash config <SUBCOMMAND> # Manage configuration (get, set, list, path)

# Error Help
lash explain <CODE> # Explain error code (e.g., E001)
lash explain <CODE> # Explain any code lint reports (e.g., W_INDEX_ORPHAN)
lash explain --list # List all error codes
```

Expand Down
17 changes: 16 additions & 1 deletion crates/lash-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const LOGO_FOR_HELP: &str = "\
about = "Minimalist Markdown-native task tracker",
long_about = "Lash is an ultra-fast, Markdown-native task tracker designed for developers and AI agents.\n\
It uses Markdown as the single source of truth and SQLite as an acceleration layer.\n\n\
FILE DISCOVERY:\n \
Commands that walk the project (lint, format, index, check-index) visit every .md\n \
file under the project root, skipping anything excluded by .gitignore or by a\n \
.lashignore file. .lashignore uses .gitignore syntax — one pattern per line, e.g.\n \
'content/' — and is the way to keep non-task Markdown out of Lash entirely.\n\n\
EXIT CODES:\n \
0 - Success\n \
1 - General error\n \
Expand Down Expand Up @@ -128,7 +133,17 @@ pub struct LashCli {
#[allow(clippy::large_enum_variant)]
pub enum Commands {
/// Validate Lash task files for errors
#[command(alias = "check")]
#[command(
alias = "check",
long_about = "Validate Lash task files for errors.\n\n\
With no PATH, lints every .md file under the project root, skipping anything\n\
excluded by .gitignore or .lashignore. Add a .lashignore at the project root\n\
(.gitignore syntax, one pattern per line, e.g. 'content/') to keep Markdown\n\
that is not a task file out of linting — that is the fix for a directory of\n\
prose reporting W_INDEX_ORPHAN once per file.\n\n\
Run 'lash explain <CODE>' for a detailed explanation of any code reported\n\
here, or 'lash explain --list' to see them all."
)]
Lint {
/// Files or directories to lint (defaults to current project)
#[arg(value_name = "PATH")]
Expand Down
Loading
Loading