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
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,41 @@
All notable changes to DebtLens are documented here. This project adheres to
[Semantic Versioning](https://semver.org/).

## [0.3.0] - 2026-06-09

### Added

- **`debtlens adopt`** first-run adoption workflow with dry-run recommendations and optional
config/baseline writes.
- **`debtlens doctor`** command to inspect resolved config and matched files without scanning.
- **Rule packs** (`core`, `react`, `react-native`, `next`) as config presets via `--pack` and
`debtlens init --pack`.
- **Configurable `todo-comment` markers** with custom patterns, disabled defaults, and
`replaceDefaults`.
- **Inline suppressions** via `debtlens-disable-next-line` and `debtlens-disable-file`
comments with required reasons after `--`.
- **`--fail-on-confidence`** CLI flag, config field, and GitHub Action input for
confidence-aware CI exit codes.
- **`--diff-base`** mode to report findings introduced since a git ref.
- **`--package`** monorepo scanning MVP for `packages/*` workspace layouts.
- **`--profile`** per-rule timing output without changing findings.
- **Filter stats** in scan summaries (`suppressedByBaseline`, `filteredByMinSeverity`,
`suppressedByInline`) across terminal, JSON, Markdown, and PR-comment reporters.
- **GitHub Action** step summary output, PR comment upsert mode, and `fail-on-confidence` input.
- **Calibrated quality fixtures** for representative app shapes.
- **Performance benchmark suite** for scan fixtures.
- **Rule fix guidance** and refactor prompts in Markdown reports.
- **Plugin API RFC** in `docs/plugin-api-rfc.md`.

### Changed

- **`large-component`** now recognizes `memo`, `forwardRef`, and class components.
- **`naming-drift`** is quieter on domain-rich apps via `disableBuiltInVocabulary` and
calibrated defaults.
- **`todo-comment`** skips `debtlens-disable-*` directive lines so suppression comments do
not self-trigger findings.
- Contributor docs refreshed for completed roadmap; good-first issue queue is now historical.

## [0.2.0] - 2026-06-06

### Added
Expand Down
54 changes: 44 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,33 @@ When a scan reads zero files, DebtLens prints a stderr warning with likely cause

When `duplicate-logic` reaches `duplicate-logic.maxSnippets`, DebtLens warns that duplicate comparisons were capped. JSON output includes the same advisory under `summary.warnings`.

## Inline suppressions

Suppress intentional findings in source with an explicit, auditable reason. Suppressions apply during the scan; baseline and `--diff-base` filtering run afterward on the remaining issues.

**Next-line** — hides a finding on the line immediately below the comment:

```ts
// debtlens-disable-next-line todo-comment -- tracked in PROJ-123
// TODO: remove after migration ships
```

**File-level** — hides all findings for that rule in the file:

```ts
// debtlens-disable-file naming-drift -- domain vocabulary is intentional here
```

Rules:

- A non-empty reason is required after `--`. Suppressions without a reason are ignored and emit a warning.
- Unknown rule ids emit a warning and do not suppress.
- Only the matching rule (and line, for next-line) is suppressed; other rules on the same line still report.

Terminal output includes inline suppression counts in the filter stats line (for example, `1 inline suppressed`). JSON reports expose the same count under `summary.filterStats.suppressedByInline`.

Prefer baselines for legacy debt, config tuning for false positives, and inline suppressions for rare, documented exceptions. See [`docs/rules.md`](./docs/rules.md#suppressing-findings) for guidance.

## Configuration

Create `debtlens.config.json`:
Expand Down Expand Up @@ -386,14 +413,16 @@ steps:

Want to help make DebtLens better? Start with the
[first-PR guide](./docs/contributing-first-pr.md), the
[rule pack taxonomy](./docs/rule-packs.md), the
[good first issues list](./docs/good-first-issues.md), and the
[contributor roadmap](https://github.com/ColumbusLabs/DebtLens/projects). Use
[Discussions](https://github.com/ColumbusLabs/DebtLens/discussions) for open-ended
ideas, rule proposals, and usage questions.
[rule pack taxonomy](./docs/rule-packs.md), and
[CONTRIBUTING.md](./CONTRIBUTING.md). The v0.3 contributor roadmap batch is complete;
see [`docs/good-first-issues.md`](./docs/good-first-issues.md) for a historical index of
shipped tasks. Propose new work in
[Discussions](https://github.com/ColumbusLabs/DebtLens/discussions), via the rule request
template, or the [plugin API RFC](./docs/plugin-api-rfc.md).

Contribution paths: **core TS/JS rules**, **React pack rules**, **framework packs**
(Next.js, RN, Node), **scanner/CI** (baselines, monorepos), and **reporters**.
(Next.js, RN, Node), **scanner/CI** (baselines, monorepos, inline suppressions), and
**reporters**.

## Development

Expand All @@ -409,10 +438,15 @@ node dist/cli/index.js scan examples/react --min-severity info

## Project status

DebtLens is currently in the v0.2 release line. The architecture is intentionally simple:
a language-agnostic scan and reporting layer, with pluggable rule packs on top. React is
the first serious pack; React Native, Next.js, and broader TS/JS rules expand from there.
See [`ROADMAP.md`](./ROADMAP.md) and [`docs/rule-packs.md`](./docs/rule-packs.md).
DebtLens is in the **v0.3** release line. Recent capabilities include `debtlens adopt`
and `debtlens doctor`, rule packs, inline suppressions with required reasons,
confidence-aware `--fail-on`, monorepo `--package` scanning, GitHub Action step summaries
and PR comment upsert, and `--diff-base` branch comparisons.

The architecture stays intentionally simple: a language-agnostic scan and reporting
layer with pluggable rule packs on top. React is the first serious pack; React Native,
Next.js, and broader TS/JS rules expand from there. See [`ROADMAP.md`](./ROADMAP.md) and
[`docs/rule-packs.md`](./docs/rule-packs.md).

## License

Expand Down
17 changes: 11 additions & 6 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@ the core vs pack taxonomy, future languages, and contribution paths.
- Add `--changed` mode for pull request scanning.
- Add `--sarif` output for GitHub code scanning.

## v0.3 — Maintainer workflow integrations
## v0.3 — Maintainer workflow integrations (shipped)

- GitHub Action.
- GitHub Action with SARIF, step summary, PR comment upsert, and `fail-on-confidence`.
- PR comment mode with Markdown annotations grouped by file.
- Suggested refactor prompts for each issue.
- Rule config schema and generated docs.
- Monorepo/package-aware scanning.
- Suggested refactor prompts and rule fix guidance in reports.
- Rule config schema, rule packs, and `debtlens doctor`.
- Monorepo/package-aware scanning (`--package` MVP).
- First-run adoption workflow (`debtlens adopt`).
- Inline suppressions with required reasons.
- Filter stats in scan summaries (baseline, min-severity, inline suppressions).
- `--diff-base` for branch-introduced findings.
- Scan profiling (`--profile`) and calibrated quality fixtures.

## v0.4 — Ecosystem expansion

- Optional rule packs in config (`core`, `react`, `react-native`, `next`, `node`).
- Optional rule packs in config (`core`, `react`, `react-native`, `next`, `node`) — **partially shipped in v0.3**.
- Vue/Svelte detectors where applicable.
- **First non-JS language pack: Python** — duplicate/dead-abstraction/TODO/naming rules; same `ScanResult` and SARIF contract as TS/JS.
- Configurable domain vocabulary for naming drift.
Expand Down
16 changes: 11 additions & 5 deletions docs/contributing-first-pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ Use a focused test while iterating, then run the full commands before opening a
- `tests/` mirrors the production areas with focused `node:test` coverage.
- `examples/` contains small projects used for smoke tests and report fixtures.

## Pick an issue
## Pick a contribution

Start with [`docs/good-first-issues.md`](./good-first-issues.md), then comment on the
GitHub issue before taking medium or large work. Small docs and test-only fixes usually
do not need a long design thread.
The original good-first issue queue is complete as of v0.3.0. Use
[`docs/good-first-issues.md`](./good-first-issues.md) as a historical index of shipped
work, then propose new changes through
[Discussions](https://github.com/ColumbusLabs/DebtLens/discussions), the
[rule request template](../.github/ISSUE_TEMPLATE/rule_request.md), or the plugin API RFC
([`docs/plugin-api-rfc.md`](./plugin-api-rfc.md)).

Good starter areas by layer:
Comment before starting medium or large work so maintainers can help shape the approach.
Small docs and test-only fixes usually do not need a long design thread.

Good contribution areas by layer:

- **Core rules** — duplication, abstractions, naming, TODO markers
- **React pack** — component size, hooks, prop drilling, effects
Expand Down
66 changes: 37 additions & 29 deletions docs/good-first-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,52 @@ contribution layers.

**Labels:** `good first issue` (general) · `good-first-rule` (detector/rule work)

Statuses reflect the current repository surface. **Done** means the GitHub issue is closed.
## Roadmap status (v0.3.0)

The original contributor roadmap batch is **complete**. There are no open good-first
implementation issues. New work should start in
[Discussions](https://github.com/ColumbusLabs/DebtLens/discussions), the
[rule request template](../.github/ISSUE_TEMPLATE/rule_request.md), or the plugin API RFC
([`docs/plugin-api-rfc.md`](./plugin-api-rfc.md)).

Statuses below are historical. **Done** means the GitHub issue is closed.

## Core rules (any TS/JS project)

| # | Task | Issue | Status |
| --- | --- | --- | --- |
| 3 | Reduce `naming-drift` false positives on domain-rich apps | [#3](https://github.com/ColumbusLabs/DebtLens/issues/3) | Open |
| 4 | Configurable markers for `todo-comment` | [#4](https://github.com/ColumbusLabs/DebtLens/issues/4) | Open |
| 3 | Reduce `naming-drift` false positives on domain-rich apps | [#3](https://github.com/ColumbusLabs/DebtLens/issues/3) | **Done** |
| 4 | Configurable markers for `todo-comment` | [#4](https://github.com/ColumbusLabs/DebtLens/issues/4) | **Done** |
| 27 | Warn when `duplicate-logic` hits `maxSnippets` cap | [#27](https://github.com/ColumbusLabs/DebtLens/issues/27) | **Done** |

## React pack rules

| # | Task | Issue | Status |
| --- | --- | --- | --- |
| 1 | Make the `prop-drilling` host-component list configurable | [#1](https://github.com/ColumbusLabs/DebtLens/issues/1) | **Done** |
| 2 | Teach `large-component` to recognize `memo`, `forwardRef`, and class components | [#2](https://github.com/ColumbusLabs/DebtLens/issues/2) | Open |
| 2 | Teach `large-component` to recognize `memo`, `forwardRef`, and class components | [#2](https://github.com/ColumbusLabs/DebtLens/issues/2) | **Done** |
| 15 | Extend `effect-complexity` to `useLayoutEffect` / `useInsertionEffect` | [#15](https://github.com/ColumbusLabs/DebtLens/issues/15) | **Done** |

### 1. Make the `prop-drilling` host-component list configurable — [#1](https://github.com/ColumbusLabs/DebtLens/issues/1) (closed)

Implemented via `propDrilling.ignoreComponents`, config/schema support, and detector
tests covering custom ignored components.

### 2. Teach `large-component` to recognize more component forms — [#2](https://github.com/ColumbusLabs/DebtLens/issues/2)

Today it only classifies PascalCase function/arrow components
([`src/utils/ast.ts`](../src/utils/ast.ts) `collectFunctionLikes`). It misses
`memo(function X(){})`, `forwardRef(...)`, and class components.

- Verify: fixtures for each form in `tests/detectors/largeComponent.test.ts`.

### 3. Reduce `naming-drift` false positives on domain-rich apps — [#3](https://github.com/ColumbusLabs/DebtLens/issues/3)
### 2. Teach `large-component` to recognize more component forms — [#2](https://github.com/ColumbusLabs/DebtLens/issues/2) (closed)

The built-in media vocabulary treats distinct domain entities (e.g. `movie` vs `show`)
as "competing names." Options: raise the default `minVariants`, add a config switch to
disable the built-in pack, or require co-occurrence in the same identifier.
`memo`, `forwardRef`, and class components are classified in
[`src/utils/ast.ts`](../src/utils/ast.ts) with fixtures in
`tests/detectors/largeComponent.test.ts`.

- Touch: [`src/detectors/namingDrift.ts`](../src/detectors/namingDrift.ts).
- Verify: a media-style fixture that should NOT fire by default.
### 3. Reduce `naming-drift` false positives on domain-rich apps — [#3](https://github.com/ColumbusLabs/DebtLens/issues/3) (closed)

### 4. Configurable markers for `todo-comment` — [#4](https://github.com/ColumbusLabs/DebtLens/issues/4)
`namingDrift.disableBuiltInVocabulary` and calibrated media fixtures reduce noise on
domain-rich apps. See [`src/detectors/namingDrift.ts`](../src/detectors/namingDrift.ts).

Allow projects to add/replace the marker patterns
([`src/detectors/todoComment.ts`](../src/detectors/todoComment.ts)) via config.
### 4. Configurable markers for `todo-comment` — [#4](https://github.com/ColumbusLabs/DebtLens/issues/4) (closed)

- Verify: a custom marker fires; a removed default does not.
Custom markers, disabled defaults, and `replaceDefaults` are supported via config and
documented in the schema. See [`src/detectors/todoComment.ts`](../src/detectors/todoComment.ts).

### 15. Extend `effect-complexity` to layout/insertion effects — [#15](https://github.com/ColumbusLabs/DebtLens/issues/15) (closed)

Expand Down Expand Up @@ -176,12 +176,20 @@ Expose `write-baseline`, `thresholds`, and `max-files` in `action.yml`.

Scan `examples/react-native` and `examples/next` in `.github/workflows/ci.yml`.

## Roadmap / larger work
## Adoption and CI (v0.3)

Framework packs, monorepo support, and plugin loading are multi-PR efforts. Read the
issue body before starting and comment if you plan to own one.

| # | Task | Layer | Issue |
| # | Task | Issue | Status |
| --- | --- | --- | --- |
| 23 | Monorepo and package-aware scanning | scanner / CI | [#23](https://github.com/ColumbusLabs/DebtLens/issues/23) |
| 26 | Plugin API for third-party rules | scanner / extensibility | [#26](https://github.com/ColumbusLabs/DebtLens/issues/26) |
| 23 | Monorepo and package-aware scanning | [#23](https://github.com/ColumbusLabs/DebtLens/issues/23) | **Done** |
| 33 | Inline suppressions with required reasons | [#33](https://github.com/ColumbusLabs/DebtLens/issues/33) | **Done** |
| 37 | `debtlens doctor` for config debugging | [#37](https://github.com/ColumbusLabs/DebtLens/issues/37) | **Done** |
| 38 | First-run adoption wizard | [#38](https://github.com/ColumbusLabs/DebtLens/issues/38) | **Done** |
| 39 | Confidence-aware exit-code policy | [#39](https://github.com/ColumbusLabs/DebtLens/issues/39) | **Done** |

## Forward-looking work

Multi-PR or RFC efforts for future releases:

| # | Task | Layer | Issue | Status |
| --- | --- | --- | --- | --- |
| 26 | Plugin API for third-party rules | scanner / extensibility | [#26](https://github.com/ColumbusLabs/DebtLens/issues/26) | RFC closed — see [`docs/plugin-api-rfc.md`](./plugin-api-rfc.md) |
19 changes: 19 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ Every finding includes a **confidence** score from 0 to 1. Confidence reflects h

Use confidence for triage and CI policy (for example, `--fail-on high --fail-on-confidence 0.8`) when you want to gate on high-severity findings that are also well-supported.

## Suppressing findings

DebtLens supports three layers for managing noise. Pick the narrowest tool that fits:

| Approach | Best for |
| --- | --- |
| **Config / thresholds** | Project-wide false positives (ignore components, custom TODO markers, naming vocabulary) |
| **Baseline** | Legacy debt you accept today but want to block newly introduced issues in CI |
| **Inline suppression** | Rare, file-local exceptions with an auditable reason |

Inline suppressions use comment directives:

```ts
// debtlens-disable-next-line <rule-id> -- <reason>
// debtlens-disable-file <rule-id> -- <reason>
```

The reason after `--` is required. Unknown rule ids and missing reasons produce warnings and do not suppress. Suppressions run inside `scan()` before baseline or `--diff-base` filtering, so baselines still track only the issues that remain after inline suppressions.

## `large-component`

Flags React-style PascalCase functions, `memo`/`forwardRef` wrappers, and class components
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "debtlens",
"version": "0.2.0",
"version": "0.3.0",
"description": "Maintainability scanner for TypeScript and JavaScript codebases; React rule pack is the first supported target.",
"type": "module",
"homepage": "https://github.com/ColumbusLabs/DebtLens#readme",
Expand Down
1 change: 1 addition & 0 deletions src/detectors/todoComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const todoCommentDetector: Detector = {
for (let index = 0; index < lines.length; index += 1) {
const line = lines[index] ?? "";
if (!line.includes("//") && !line.includes("/*") && !line.includes("*")) continue;
if (/debtlens-disable-(?:next-line|file)/i.test(line)) continue;
const match = patterns.find((pattern) => pattern.regex.test(line));
if (!match) continue;

Expand Down
Loading