effort-mediumenhancementgood first issue
Description
Summary
fnm is a popular Node version manager (Rust, ~14k stars) with no RTK handler in 0.37.2. Common dev shells initialize Node via eval "$(fnm env)" and switch versions via fnm use. rtk hook check returns "No rewrite" for both. From 30 days of rtk discover:
fnm use 126 fnm use 20 2>&1
eval "$(fnm 123 eval "$(fnm env)"
249 invocations / 30 days, almost entirely from session-init / Node-version-switch context. Output is normally short (1-3 lines), but the volume + the fact that they appear in nearly every session that touches Node makes them a base-rate pain point — ~5-8% of all Claude Code Bash calls.
Why a handler matters even though output is small
- Session init noise: every shell init runs
eval "$(fnm env)". Even 3 lines × thousands of sessions = measurable. - Error path is verbose:
fnm use <missing-version>prints multi-line install hints. RTK could compress to one-line "missing version 22, runfnm install 22". - Pairs naturally with existing
npm/npx/pnpm/vitest/jesthandlers — RTK already supports the JS/TS toolchain extensively;fnmis the standard env-bootstrap tool for that ecosystem on macOS/Linux.
Proposed approach (not prescribing)
Two-tier handling, similar to how pnpm/npx are wrapped:
rtk fnm use <version>— strip the post-switch table that lists installed versions (typically 5-10 lines), keep justUsing Node v<X>.rtk fnm env— passthrough as-is (the eval'd output IS the environment; can't compress without breaking).- Hook routing whitelist additions:
fnm,eval "$(fnm env)"(the latter needs lexer awareness — see PR #156's lexer for prior art oncommand/exec/noglobprefix stripping).
Related
- #599 "Add support for Bun" — open, includes
nvm use 30/30din theirrtk discoveroutput (nvmis conceptually similar tofnm; could be addressed together as a "Node version manager family") - #361 / PR #156 (hook engine v2 —
hook_lookup()whitelist will need fnm entry)
Environment
- rtk: 0.37.2
- fnm version observed: latest (Linux WSL2)
- Multi-language project (Java/Spring Boot backend + Next.js frontend), so the Node toolchain is touched ~daily