readme/dev/any_cleanup_progress.md
any Cleanup ProgressTracks the effort to remove // eslint-disable-next-line @typescript-eslint/no-explicit-any comments from the codebase and replace any with proper types.
Reduce the number of eslint-disable-next-line @typescript-eslint/no-explicit-any comments by replacing any with actual types wherever this can be done without changing code logic and without significant refactoring. Most of these comments are tagged Old code before rule was applied and are the primary targets.
For each disable comment encountered:
any with a real type only if:
any describes a value that comes from a third-party package (e.g. @rmp135/sql-ts Table/Column, yargs Arguments, markdown-it Token / StateCore), check the package's .d.ts files (node_modules/<pkg>/**/*.d.ts) before defining a new local interface. Importing the existing type is preferable because it stays accurate as the library evolves and matches what the runtime actually produces. Only fall back to a local type when the library doesn't export one, the exported type is significantly broader/narrower than needed, or importing it would pull in a heavy dependency the file otherwise doesn't need.
'@rmp135/sql-ts', 'markdown-it'), import it from there rather than reaching into dist/, lib/, or src/ ('@rmp135/sql-ts/dist/Typings', 'markdown-it/lib/token'). Internal paths can be renamed or removed in any minor release without notice. The exception is when the type is not re-exported from the top level (markdown-it's StateCore/Token/Renderer are this case — 'markdown-it/lib/...' is the only way to reach them); in that case the internal path is unavoidable and is fine to use.Old code before rule was applied (e.g. No better type available, CodeMirror 5 API requires any, would be too big of a refactoring).unknown and would force narrowing changes (that's a logic change).any is removed, delete the disable comment as well.CLAUDE.md).-- reason is enough; don't pair it with an extra block comment.yarn tsc --noEmit and yarn lint for that package to verify nothing broke.yarn spellcheck --all (or yarn spellcheck <path> for the files you touched, including the progress docs) and ensure it passes. The pre-commit hook runs spellcheck on the staged files, so an unknown word will block the commit. When cSpell flags a real technical word that should be allowed everywhere, add it to the last dictionary in packages/tools/cspell/dictionary?.txt per the spec in readme/dev/spellcheck.md (each dictionary has a ~400-word cap; create a new one if the last is full). Don't use inline // cSpell:disable for individual words — only for blocks of unparseable content.packages/generator-joplin/generators/app/templates/api/types.ts — Yeoman template, not real code.packages/app-cli/tests/support/plugins/*/api/types.ts — copies of the plugin API; source of truth is packages/lib/services/plugins/api/types.ts. They get regenerated.lib, app-desktop, app-cli), also update the table row at intermediate checkpoints (e.g. every ~20 files) so a hard cutoff loses at most one checkpoint's worth of detail.gh pr edit <PR-number> --body-file readme/dev/any_cleanup_progress.md.
Find the PR number with gh pr list --head <branch> --json number. The current branch for this cleanup is any_refactor_7 (no PR opened yet — previous PRs on any_refactor_* were merged).Large packages can consume enough context in a single session that Claude either hits a hard limit, gets auto-compacted, or starts to degrade in attention. Plan for this rather than hope to avoid it:
lib (1140 comments, 213 files) will not fit in a single conversation with full attention; even app-desktop (477) and app-cli (742) are risky. Do not try to batch multiple packages.any in package X") but may lose which specific files were already processed. The on-disk progress file is the only reliable record — that's why per-file entries must be written immediately, not batched.grep -rn "eslint-disable-next-line @typescript-eslint/no-explicit-any" packages/<name>/) to confirm where to pick up. Trust the file, not memory.Counts captured 2026-05-11 before any work. Note: the original app-cli row counted 742 comments across 90 files, but that included build/ (compiled JS), app/*.js (compiled JS), and tests/support/plugins/*/api/ (regenerated plugin API copies — listed under "Files to never touch"). The in-scope .ts/.tsx source contains 90 comments across 38 files; the table was corrected on 2026-05-13.
| # | Package | Files w/ comments | Comments (start) | Removed | Remaining | Status |
|---|---|---|---|---|---|---|
| 1 | pdf-viewer | 3 | 5 | 5 | 0 | done (2026-05-11) |
| 2 | editor | 5 | 21 | 6 | 15 | done (2026-05-11) |
| 3 | utils | 9 | 28 | 23 | 5 | done (2026-05-11) |
| 4 | react-native-saf-x | 1 | 1 | 1 | 0 | done (2026-05-11) |
| 5 | default-plugins | 1 | 4 | 4 | 0 | done (2026-05-11) |
| 6 | renderer | 25 | 99 | 87 | 12 | done (2026-05-11) |
| 7 | tools | 23 | 49 | 45 | 4 | done (2026-05-11) |
| 8 | plugin-repo-cli | 11 | 33 | 33 | 0 | done (2026-05-11) |
| 9 | app-mobile | 37 | 131 | 98 | 33 | done (2026-05-12) |
| 10 | server | 67 | 227 | 205 | 22 | done (2026-05-12) |
| 11 | app-cli | 38 | 90 | 74 | 16 | done (2026-05-13) |
| 12 | app-desktop | 149 | 477 | 300 | 177 | done (2026-05-13) |
| 13 | lib | 212 | 1138 | 866 | 272 | done (2026-05-14) |
| — | generator-joplin | 2 | 27 | — | — | excluded (template) |
Total in-scope comments at start: 2,952 across 633 files.
A later follow-up pass (June 2026, branch chore/claude/better-types) revisited any that the per-package effort deliberately deferred — cases where the type had to be tightened at its source so caller skips cascade away, or that spanned multiple packages. See the "Multiple packages - June 2026" section in any_cleanup_progress_details.md for the per-change detail.
Smallest packages first to validate the workflow and surface common patterns before tackling the large ones:
tests/support/plugins/*/api/types.ts copiesEach package gets a subsection added to ./any_cleanup_progress_details.md when work begins. Format:
## packages/<name>
Session date: YYYY-MM-DD
Files processed:
- path/to/file.ts — N removed, M left (reasons)
Files skipped entirely:
- path/to/file.ts — reason