node-modules-hunter 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/cli.js +275 -80
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,6 +47,7 @@ nmh stats -g # global installs across npm/pnpm/yarn/bun
|
|
|
47
47
|
nmh why <pkg> [dir…] # reverse depend: where is <pkg> and what requires it — read-only
|
|
48
48
|
nmh treemap [dir] # single-file interactive HTML treemap → nmh-treemap.html
|
|
49
49
|
nmh update --check # v1.2: compare installed vs registry — nothing installs
|
|
50
|
+
nmh update --check beta # v1.4: compare against a specific dist-tag (or: --tag beta)
|
|
50
51
|
nmh update --info # v1.2: full registry detail (npm view style)
|
|
51
52
|
nmh update -y # install the newer version without asking (-n declines, --force skips the ask)
|
|
52
53
|
|
|
@@ -92,6 +93,8 @@ Search patterns: plain text is a case-insensitive substring (`nmh search lodash`
|
|
|
92
93
|
| `--reinstall` | With `stats` (focused view): naive npm-ci-style estimate of how long re-installing everything takes (pkg × 60 ms + bytes / 50 MB/s + 3 s per native-family build); assumptions surfaced in the JSON, labeled naif |
|
|
93
94
|
| `--animate` / `--no-animate` | Spinning braille loader while measuring (time-driven — rotates on its own, v1.1.1): auto = real TTY only, `--animate` forces it even when piped; always suppressed under `--json`; `.nmhrc animate:false` mutes it |
|
|
94
95
|
| `--update-check` | Opt-in: peek npm for a newer release (non-blocking, 24 h cache, notice on stderr; also `updateCheck` in `.nmhrc`) |
|
|
96
|
+
| `--tag <name>` | **v1.4** — update only: read a specific npm dist-tag (`nmh update --tag beta`); `--check <tag>` names it inline; unknown tags refuse with the available list, downgrades confirm with NO as the default |
|
|
97
|
+
| `--update-tag <name>` | **v1.4** — config family: persist the default update dist-tag (`updateTag` in `.nmhrc`) — what `nmh update` / `--check` read when no `--tag` is given |
|
|
95
98
|
| `--config <file>` | Use this config file instead of the `.nmhrc` lookup (cwd → `$HOME`) |
|
|
96
99
|
| `--language <lang>` | **v1.3** — UI language: `en` \| `id` \| `zh` \| `ru` \| `es`; also via `.nmhrc` `language` and `NMH_LANG` (see [UI language](#ui-language-v130--i18n)) |
|
|
97
100
|
| `--json` | Machine-readable output (pipe into `jq`) |
|
|
@@ -234,7 +237,7 @@ Only bare package specifiers count (`node:fs`, `./util`, `#alias` skipped; subpa
|
|
|
234
237
|
|
|
235
238
|
```bash
|
|
236
239
|
$ nmh stats ./my-repo --update-check # opt-in npm peek, 24 h cache
|
|
237
|
-
ℹ update
|
|
240
|
+
ℹ update available: 0.4.0 → 0.5.0 — npm i -g node-modules-hunter (…)
|
|
238
241
|
```
|
|
239
242
|
|
|
240
243
|
### Vision & hygiene extras (v0.5)
|
|
@@ -359,6 +362,7 @@ The classic question — *which of these `node_modules` can I actually kill?*
|
|
|
359
362
|
- **`--fast-size`** swaps the byte-exact walker for one `du -sk` per entry (KiB granularity — sizes are always multiples of 1024); anything `du` can't measure falls back to the exact walker silently. Scan-only knob: delete runs always measure exactly so the freed-bytes number stays honest. Windows has no `du`, so it always walks.
|
|
360
363
|
- **Default skip-list flip**: discovery now hides name-based system noise (`.Trash`, `.Trashes`, `.Trash-<uid>`, `Library`, `*.app`) wherever it sits in the tree; pass **`--no-skip`** to restore the bare full-tree v1.0 audit. `.git` stays skipped always (even with `--no-skip`), and direct targets are never filtered — the skip only shapes what discovery finds.
|
|
361
364
|
- **`nmh update` is consented (v1.2)**: the plain run shows the facts and asks before installing (`@clack` confirm on a TTY; a piped/`--json` run needs `-y` to install or `-n` to decline — without an answer it refuses with exit `1`, the same protocol as deletes). `--check` is the compact compare for scripts/CI (exit 0 whether or not an update exists, never installs), `--info` is the full `npm view`-style read-out (description, tarball + size + file count, engines, license, publish time), and the two are mutually exclusive. `--force` skips the ask when an update exists — an already-latest install is checked and reported, never blindly reinstalled. Non-npm-global installs keep the honest how-to note. `--json` payload: `{ current, latest, updated, method }` frozen + additive `{ updateAvailable, detail? }`.
|
|
365
|
+
- **Dist-tag support (v1.4)**: `--tag <name>` (or `--check <tag>`, or the persisted `.nmhrc` `updateTag` key via `nmh config set --update-tag <name>`) reads any published dist-tag instead of `latest`. A tag pointing below the installed version is a **downgrade** — same consent gate as an upgrade, but the TTY confirm defaults to **NO** (overwriting a newer install is never the obvious move); non-TTY still needs `-y`. Unknown tags refuse loudly with the available list (`--tag nope` → exit 1), malformed names are validated against the npm dist-tag shape. `--info` lists every published tag (`dist-tags latest=1.4.0, beta=1.5.0-beta.1`). `--json` payload stays additive: `{ current, latest, updated, method, updateAvailable, detail? }` + new `{ tag, target, direction: 'upgrade'|'downgrade'|'current', distTags? }`. The wizard menu gains a **🔁 Update nmh** entry, and the wizard boot now peeks the registry by default (24 h cache, `.nmhrc` `updateCheck: false` opts out).
|
|
362
366
|
- **`--json` stays additive**: new optional keys `idleDays`, `activitySource`, `backend`, `trashBatch`, `trashFallback` appear only when a v1.1 feature is active; every v1.0 payload key is unchanged (the frozen v1.0 contract, extended minor-version-safely).
|
|
363
367
|
|
|
364
368
|
## Exit codes
|
|
@@ -417,6 +421,7 @@ For settings you always repeat, drop a `.nmhrc` (or `.nmhrc.json`) next to your
|
|
|
417
421
|
"animate": false,
|
|
418
422
|
"updateCheck": true,
|
|
419
423
|
"language": "en",
|
|
424
|
+
"updateTag": "latest",
|
|
420
425
|
"logDir": "~/.cache/nmh-logs"
|
|
421
426
|
}
|
|
422
427
|
```
|
|
@@ -438,7 +443,7 @@ Hand-editing JSON is optional now:
|
|
|
438
443
|
| `nmh config remove …` | Drop listed items; the **bare flag clears the whole list** |
|
|
439
444
|
| `nmh config unset …` | Delete keys from the file (back to defaults) |
|
|
440
445
|
|
|
441
|
-
List keys use self-describing flag names: `--default-exclude` (→ the `exclude` key) and `--default-keep` (→ `keep`). Scalars keep their `.nmhrc` names: `--depth`, `--default-mode`, `--log-dir`, `--animate`, `--color`, `--update-check` (negations like `--no-animate` work).
|
|
446
|
+
List keys use self-describing flag names: `--default-exclude` (→ the `exclude` key) and `--default-keep` (→ `keep`). Scalars keep their `.nmhrc` names: `--depth`, `--default-mode`, `--log-dir`, `--animate`, `--color`, `--update-check`, `--update-tag` (v1.4 — the `updateTag` dist-tag, validated against the npm tag-name shape) (negations like `--no-animate` work).
|
|
442
447
|
|
|
443
448
|
```bash
|
|
444
449
|
nmh config add --default-exclude=.npm,.nvm,self # the classic homedir silencer
|
|
@@ -474,7 +479,7 @@ NMH_LANG=ru nmh scan # 3. the environment (NMH_LANG, then LC_ALL/LAN
|
|
|
474
479
|
|
|
475
480
|
## Roadmap
|
|
476
481
|
|
|
477
|
-
v0.1 shipped the MVP (scan · size · delete · wizard · guards · PM detection). v0.2 added **search, map, `--depend`, `-r` recursive audit and the `--pm` / `--exclude` / `--keep` / `--depth` / `--expand` filters**. v0.3 added the **`stats` suite (dup factor, waste, top-N, per-package tree), `stats -g` global analysis across PMs, report export (`--save-report`/`--report`), `--animate` and the `.nmhrc` config file**. v0.4 added the **analytics deep-cut: baselines (`--save-baseline`/`--compare`/`--history`), dedup suggestions with per-copy declared ranges, `nmh why`, the real `--by type` breakdown, the `--phantom`/`--dead` best-effort import audit and the opt-in `--update-check`**. v0.5 added the **vision & hygiene extras: license scan (`--licenses`/`--by licenses` with the copyleft-in-prod ⚠), the experimental Bloat Score (`--score`) and CO2 estimate (`--co2`), the deprecated check (`--online`, offline manifests + lazy cached registry fallback), the `nmh treemap` single-file HTML export and `--save-report` for map/search/stats**. v0.6 added the **lockfile-grade graph: `--graph` parses npm/yarn/pnpm/bun lockfiles (zero new dependencies) into a real dependency graph with a BFS depth histogram, `nmh why` upgrades to lockfile-grade required-by (transitive requirers, no more false "orphans"), and `--reinstall` estimates the npm-ci-style reinstall time**. v0.7 added the **full PRD §7.5 wizard menu (delete all / pick / search / map / detailed report / settings, with loop-backs), a serious banner box (TTY) + compact one-liner (non-TTY, `--json`-clean), and a richer `nmh version` (node + abi + OS/arch/kernel + tty, `--json`)**. The v0.7.1 patch re-scheduled the folder walker to a slot-per-readdir work queue: the old recursive limiter could deadlock (circular wait) on wide bushy trees like a 12-package pnpm workspace — freezing the scan with **zero output and exit code 0 mid-walk**. Trees of that shape are covered by a regression test now. The same patch hardened measurement: children are classified with `fs.lstat` instead of dirent `d_type`, because some filesystems (Android FUSE/sdcardfs) misreport hardlinked pnpm-store files as symlinks — one `typescript/lib` dir had 112 of 125 dirents lying, which made a whole pnpm virtual store measure 650 KB while `du` saw 66 MB — and entry sizes now dedupe hardlinks per entry (`du -sb`-style), keeping walk numbers in line with `du` (91 → 63 MB on the same tree). v0.8 makes the no-arg wizard scope-aware: when the cwd has no node_modules within depth 3, it climbs once to the nearest manifest ancestor (package.json, any PM lockfile, or `pnpm-workspace.yaml`, ≤8 hops — empty manifest dirs are skipped so the monorepo root still wins) and the whole menu runs there; the scope is frozen for the session (rescans never re-climb), a TTY note reveals the lift, non-TTY gets a warn line, and `--json` stays a pure payload. The v0.9 minor introduces **`nmh config` (info · set · add · remove · unset)** — manage the `.nmhrc` from the CLI instead of hand-editing JSON (`--default-exclude`/`--default-keep` list discipline with dedupe and clear, loader-grade validation, unknown-key preservation on write, `$HOME/.nmhrc` default target) — and the **`self` token** for `exclude`/`keep`: a scan-level guard that drops every entry inside the folder nmh runs from, wholesale, whatever target you point at (your own project can never be hunted by accident). v0.9.1 is a **live-audit hardening patch**: a scripted fixture farm × ~140 invoked combination runs surfaced five defects that are now fixed — delete guards additionally refuse a `node_modules` sitting *directly inside* `/` or `$HOME` (previously a `--dir ~ --delete -y` could sweep it away), the wizard's non-TTY fallback scan now honors `exclude`/`keep` from config and flags, a bare `--depth` failure message no longer swallows the value into `true`, the `--depend` guard messages are reconciled as map-only with actionable hints, and a failed `treemap --out` write exits 1 with a friendly 🛑 instead of a raw errno string. Audited-and-confirmed-as-designed along the way: positional targets are never comma-split (only `--dir` is), `--save-report` write failures warn and keep the exit code, `nmh search` matches top-level package names per PRD §7.3, and `nmh why` takes pkg-first arguments. v0.9.2 is an **independent-review hardening patch**: it closes the biggest hole the v0.9.1 audit missed — a TTY `--json --delete` used to execute with **zero confirmation** (machine output has no interactive prompt slot, and the non-TTY guard didn't cover the TTY branch; a pseudo-TTY reproduction proved rc=0 with the victim gone) — now `--json --delete` requires `--yes`/`--force` on every shell, TTY included. The same pass fixed the config family under `--quiet --json` (its payload was the one survivor the sweep missed — printed empty with rc 0), turned a silent bare/multi `--size` into a loud usage error like its sibling guards, and cleaned the last 10 pre-existing `tsc` errors (a leftover `depth` sentinel union) so `npm run typecheck` is finally clean. v0.9.3 is a **no-behavior-change cleanliness patch** from the same review: six dead symbols removed (`measurePackageRefs`, `SizedPackageRef`, `readLicense`, `listHasSelf`, `isVerbose`, `formatCount`), the write-only `MeasureProgress.currentEntry` field dropped, the twin `DepsAudit` interfaces collapsed to one canonical definition (re-exported from `core/result.ts`), the `self` guard moved to its semantic home (`core/guards.ts`), `ConfigError` now carries a machine-readable `code` instead of message string-matching, scan's private report writer now shares `writeReportSnapshot` with map/search/stats, the `analyze`/`info` stats aliases are documented, and `npm run typecheck` stays at zero errors. v0.9.4 is a **hardening patch for the review findings that change data/behavior**: `stripJsonC` is now fully quote-aware (a trailing comma inside a string value is no longer eaten — silent corruption fixed), `makeGlobMatcher` caps pathological patterns (512 chars / 8 `**`) up front, a delete op aimed at `/` refuses before scanning, the deprecated `truncated` flag means "a 201st item was refused" instead of "exactly at the cap", recovery logs get a random suffix (no same-millisecond overwrites), deprecated notes are ANSI-stripped at the source, `nmh why` reads its manifests/locks with bounded concurrency of 4, the `$HOME` guard ignores letter-case on macOS, the `.nmhrc` ancestor trust is documented in the README, and the self-guard-vs-symlinked-cwd claim is verified as a non-issue (Node resolves `process.cwd()` physically). v1.0.0 is the **stable-API release**: every `--json` payload is a frozen contract guarded by the 245-test suite, the exit-code table (0/1/2/3/4) is locked, `npm run typecheck` and `npm audit` are both clean, and the package ships to npm with a `v1.0.0` git tag once the remote is configured. v1.1.0 is the **stale-hunting edition**: `--stale <days>` grades entries by newest-of git commit → manifest mtime → folder mtime and drops no-evidence stragglers, `--fast-size` measures with `du -sk` (exact-walker fallback), results gain an `Idle` column, a proportional Share bar and `--sort size|path|idle|mtime`, discovery hides system noise by default (`--no-skip` restores the bare audit), `nmh update` self-updates npm-global installs, and `--trash=system|nmh` picks the backend with a restorable `~/.nmh/trash` fallback — all with zero new dependencies and additive-only JSON keys, guarded by the 267-test suite. The v1.1.1 patch is a **polish-and-hardening pass driven by three user reports and a full live-exercise matrix** (26 sandbox fixtures × 223 real combinations): the measuring loader is a **time-driven spinner** (braille frames rotate on their own timer at 70 ms instead of per-update repaints, spinning on TTY, silent in pipes unless `--animate on`), `nmh help` renders a **complete manual** (own renderer — 14 commands + 5 stats subcommand views + grouped options + examples + the safety/exit footer, and the previously-missing `-h`/`--help`/`-v`/`--version` aliases finally work instead of slipping into the default scan), and ANSI colors are **TTY-only by design** (picocolors' `!!env.CI` guess had painted unknown escape bytes into piped GitHub Actions output and shredded substring assertions — CI is 9/9 green for the first time; local color comes from a real TTY or explicit `--color`/`FORCE_COLOR`). The same matrix surfaced two defects the suite had missed: an unknown first word (`nmh scanx`) used to fall through to a silent full-cwd scan with exit 0 — any non-path, non-command token is now a loud usage error (and a bare cwd-relative dir like `nmh node_modules` now correctly targets that folder); and `nmh config set` wrote `$HOME/.nmhrc` while scans walked cwd → `/` and never read it when the cwd lived outside the home tree — the home file is now the documented fallback (chain first). Meanwhile `os.homedir()` on Windows reads `USERPROFILE` (test helper pins both), `execFile('npm')` needs `shell: true` on win32 (`stats -g` exited 2 there), and system-trash-dependent flows run hermetically via `nmh trash` fallback. Suite: 44 files / 279 tests green. v1.2.0 is the **consent-and-targeting edition**: `nmh update` stops installing on faith — the plain run shows the facts and asks (`-y`/`-n` on pipes, `--force` to skip the ask, and an already-latest install is never reinstalled), while `--check` and `--info` are read-only registry views (compact compare vs full `npm view` detail, mutually exclusive); and the wizard becomes a first-class command — `nmh wizard --dir=./a,./b` scopes the menu to explicit targets (no auto-climb), `nmh --wizard` is the flag form, and the `--` router (`nmh wizard -- stats --dir=./a`) opens a read-only view through the full dispatcher before the menu; pipes refuse every explicit wizard form with exit 1 and directions while the bare `nmh` fallback scan stays untouched. The update messages were also unified to Indonesian (the smoke matrix caught `--check` speaking English next to an Indonesian default). Suite: 46 files / 295 tests green. The v1.2.1 hotfix repairs what the wild caught the same day: modern npm prints `npm view <pkg> --json` as an **abbreviated packument array** (no top-level `version` key), which made every `nmh update` flavor exit "cannot read the latest version" — version detection is back on the plain-text `npm view <pkg> version` spawn, the `--info` detail is a separate best-effort fetch with shape normalization (array / object / garbage all tolerated — facts minus detail, never a failed run), and the new `NMH_UPDATE_VIEW_JSON` seam keeps both shapes hermetically testable. Suite: 46 files / 296 tests green. v1.3.0 is the **full-i18n edition**: the CLI now speaks five languages — `en` (default & fallback), `id`, `zh`, `ru`, `es` — through a single catalog (`t(key, params)` in `src/i18n/`, `{placeholder}` interpolation, zero hard-coded user-facing strings left in `src/` outside the i18n module, help manual / wizard menus / table headers / guard & delete messages / treemap HTML included). The language resolves as `--language` > `.nmhrc` `language` key > `NMH_LANG` > `LC_ALL`/`LANG` > `en` (unknown flag values refused loudly with exit 1, unknown env values fall back to `en` silently), a CI completeness gate keeps every locale's key set and `{placeholder}` slots 1:1 with the English source, and both frozen contracts — `--json` payload keys and the exit-code table — are language-independent. Suite: 48 files / 315 tests green. The v1.3.1 patch **completes the five-language promise**: `zh` and `ru` are filled with their real Mandarin/Russian translations (all 480 keys, the same 1:1 key + `{placeholder}` gate applies), and `nmh help` documents the `--language <lang>` flag — codifying the rule that every new flag, command or feature ships with its help entry in the same release. Suite: 48 files / 319 tests green.
|
|
482
|
+
v0.1 shipped the MVP (scan · size · delete · wizard · guards · PM detection). v0.2 added **search, map, `--depend`, `-r` recursive audit and the `--pm` / `--exclude` / `--keep` / `--depth` / `--expand` filters**. v0.3 added the **`stats` suite (dup factor, waste, top-N, per-package tree), `stats -g` global analysis across PMs, report export (`--save-report`/`--report`), `--animate` and the `.nmhrc` config file**. v0.4 added the **analytics deep-cut: baselines (`--save-baseline`/`--compare`/`--history`), dedup suggestions with per-copy declared ranges, `nmh why`, the real `--by type` breakdown, the `--phantom`/`--dead` best-effort import audit and the opt-in `--update-check`**. v0.5 added the **vision & hygiene extras: license scan (`--licenses`/`--by licenses` with the copyleft-in-prod ⚠), the experimental Bloat Score (`--score`) and CO2 estimate (`--co2`), the deprecated check (`--online`, offline manifests + lazy cached registry fallback), the `nmh treemap` single-file HTML export and `--save-report` for map/search/stats**. v0.6 added the **lockfile-grade graph: `--graph` parses npm/yarn/pnpm/bun lockfiles (zero new dependencies) into a real dependency graph with a BFS depth histogram, `nmh why` upgrades to lockfile-grade required-by (transitive requirers, no more false "orphans"), and `--reinstall` estimates the npm-ci-style reinstall time**. v0.7 added the **full PRD §7.5 wizard menu (delete all / pick / search / map / detailed report / settings, with loop-backs), a serious banner box (TTY) + compact one-liner (non-TTY, `--json`-clean), and a richer `nmh version` (node + abi + OS/arch/kernel + tty, `--json`)**. The v0.7.1 patch re-scheduled the folder walker to a slot-per-readdir work queue: the old recursive limiter could deadlock (circular wait) on wide bushy trees like a 12-package pnpm workspace — freezing the scan with **zero output and exit code 0 mid-walk**. Trees of that shape are covered by a regression test now. The same patch hardened measurement: children are classified with `fs.lstat` instead of dirent `d_type`, because some filesystems (Android FUSE/sdcardfs) misreport hardlinked pnpm-store files as symlinks — one `typescript/lib` dir had 112 of 125 dirents lying, which made a whole pnpm virtual store measure 650 KB while `du` saw 66 MB — and entry sizes now dedupe hardlinks per entry (`du -sb`-style), keeping walk numbers in line with `du` (91 → 63 MB on the same tree). v0.8 makes the no-arg wizard scope-aware: when the cwd has no node_modules within depth 3, it climbs once to the nearest manifest ancestor (package.json, any PM lockfile, or `pnpm-workspace.yaml`, ≤8 hops — empty manifest dirs are skipped so the monorepo root still wins) and the whole menu runs there; the scope is frozen for the session (rescans never re-climb), a TTY note reveals the lift, non-TTY gets a warn line, and `--json` stays a pure payload. The v0.9 minor introduces **`nmh config` (info · set · add · remove · unset)** — manage the `.nmhrc` from the CLI instead of hand-editing JSON (`--default-exclude`/`--default-keep` list discipline with dedupe and clear, loader-grade validation, unknown-key preservation on write, `$HOME/.nmhrc` default target) — and the **`self` token** for `exclude`/`keep`: a scan-level guard that drops every entry inside the folder nmh runs from, wholesale, whatever target you point at (your own project can never be hunted by accident). v0.9.1 is a **live-audit hardening patch**: a scripted fixture farm × ~140 invoked combination runs surfaced five defects that are now fixed — delete guards additionally refuse a `node_modules` sitting *directly inside* `/` or `$HOME` (previously a `--dir ~ --delete -y` could sweep it away), the wizard's non-TTY fallback scan now honors `exclude`/`keep` from config and flags, a bare `--depth` failure message no longer swallows the value into `true`, the `--depend` guard messages are reconciled as map-only with actionable hints, and a failed `treemap --out` write exits 1 with a friendly 🛑 instead of a raw errno string. Audited-and-confirmed-as-designed along the way: positional targets are never comma-split (only `--dir` is), `--save-report` write failures warn and keep the exit code, `nmh search` matches top-level package names per PRD §7.3, and `nmh why` takes pkg-first arguments. v0.9.2 is an **independent-review hardening patch**: it closes the biggest hole the v0.9.1 audit missed — a TTY `--json --delete` used to execute with **zero confirmation** (machine output has no interactive prompt slot, and the non-TTY guard didn't cover the TTY branch; a pseudo-TTY reproduction proved rc=0 with the victim gone) — now `--json --delete` requires `--yes`/`--force` on every shell, TTY included. The same pass fixed the config family under `--quiet --json` (its payload was the one survivor the sweep missed — printed empty with rc 0), turned a silent bare/multi `--size` into a loud usage error like its sibling guards, and cleaned the last 10 pre-existing `tsc` errors (a leftover `depth` sentinel union) so `npm run typecheck` is finally clean. v0.9.3 is a **no-behavior-change cleanliness patch** from the same review: six dead symbols removed (`measurePackageRefs`, `SizedPackageRef`, `readLicense`, `listHasSelf`, `isVerbose`, `formatCount`), the write-only `MeasureProgress.currentEntry` field dropped, the twin `DepsAudit` interfaces collapsed to one canonical definition (re-exported from `core/result.ts`), the `self` guard moved to its semantic home (`core/guards.ts`), `ConfigError` now carries a machine-readable `code` instead of message string-matching, scan's private report writer now shares `writeReportSnapshot` with map/search/stats, the `analyze`/`info` stats aliases are documented, and `npm run typecheck` stays at zero errors. v0.9.4 is a **hardening patch for the review findings that change data/behavior**: `stripJsonC` is now fully quote-aware (a trailing comma inside a string value is no longer eaten — silent corruption fixed), `makeGlobMatcher` caps pathological patterns (512 chars / 8 `**`) up front, a delete op aimed at `/` refuses before scanning, the deprecated `truncated` flag means "a 201st item was refused" instead of "exactly at the cap", recovery logs get a random suffix (no same-millisecond overwrites), deprecated notes are ANSI-stripped at the source, `nmh why` reads its manifests/locks with bounded concurrency of 4, the `$HOME` guard ignores letter-case on macOS, the `.nmhrc` ancestor trust is documented in the README, and the self-guard-vs-symlinked-cwd claim is verified as a non-issue (Node resolves `process.cwd()` physically). v1.0.0 is the **stable-API release**: every `--json` payload is a frozen contract guarded by the 245-test suite, the exit-code table (0/1/2/3/4) is locked, `npm run typecheck` and `npm audit` are both clean, and the package ships to npm with a `v1.0.0` git tag once the remote is configured. v1.1.0 is the **stale-hunting edition**: `--stale <days>` grades entries by newest-of git commit → manifest mtime → folder mtime and drops no-evidence stragglers, `--fast-size` measures with `du -sk` (exact-walker fallback), results gain an `Idle` column, a proportional Share bar and `--sort size|path|idle|mtime`, discovery hides system noise by default (`--no-skip` restores the bare audit), `nmh update` self-updates npm-global installs, and `--trash=system|nmh` picks the backend with a restorable `~/.nmh/trash` fallback — all with zero new dependencies and additive-only JSON keys, guarded by the 267-test suite. The v1.1.1 patch is a **polish-and-hardening pass driven by three user reports and a full live-exercise matrix** (26 sandbox fixtures × 223 real combinations): the measuring loader is a **time-driven spinner** (braille frames rotate on their own timer at 70 ms instead of per-update repaints, spinning on TTY, silent in pipes unless `--animate on`), `nmh help` renders a **complete manual** (own renderer — 14 commands + 5 stats subcommand views + grouped options + examples + the safety/exit footer, and the previously-missing `-h`/`--help`/`-v`/`--version` aliases finally work instead of slipping into the default scan), and ANSI colors are **TTY-only by design** (picocolors' `!!env.CI` guess had painted unknown escape bytes into piped GitHub Actions output and shredded substring assertions — CI is 9/9 green for the first time; local color comes from a real TTY or explicit `--color`/`FORCE_COLOR`). The same matrix surfaced two defects the suite had missed: an unknown first word (`nmh scanx`) used to fall through to a silent full-cwd scan with exit 0 — any non-path, non-command token is now a loud usage error (and a bare cwd-relative dir like `nmh node_modules` now correctly targets that folder); and `nmh config set` wrote `$HOME/.nmhrc` while scans walked cwd → `/` and never read it when the cwd lived outside the home tree — the home file is now the documented fallback (chain first). Meanwhile `os.homedir()` on Windows reads `USERPROFILE` (test helper pins both), `execFile('npm')` needs `shell: true` on win32 (`stats -g` exited 2 there), and system-trash-dependent flows run hermetically via `nmh trash` fallback. Suite: 44 files / 279 tests green. v1.2.0 is the **consent-and-targeting edition**: `nmh update` stops installing on faith — the plain run shows the facts and asks (`-y`/`-n` on pipes, `--force` to skip the ask, and an already-latest install is never reinstalled), while `--check` and `--info` are read-only registry views (compact compare vs full `npm view` detail, mutually exclusive); and the wizard becomes a first-class command — `nmh wizard --dir=./a,./b` scopes the menu to explicit targets (no auto-climb), `nmh --wizard` is the flag form, and the `--` router (`nmh wizard -- stats --dir=./a`) opens a read-only view through the full dispatcher before the menu; pipes refuse every explicit wizard form with exit 1 and directions while the bare `nmh` fallback scan stays untouched. The update messages were also unified to Indonesian (the smoke matrix caught `--check` speaking English next to an Indonesian default). Suite: 46 files / 295 tests green. The v1.2.1 hotfix repairs what the wild caught the same day: modern npm prints `npm view <pkg> --json` as an **abbreviated packument array** (no top-level `version` key), which made every `nmh update` flavor exit "cannot read the latest version" — version detection is back on the plain-text `npm view <pkg> version` spawn, the `--info` detail is a separate best-effort fetch with shape normalization (array / object / garbage all tolerated — facts minus detail, never a failed run), and the new `NMH_UPDATE_VIEW_JSON` seam keeps both shapes hermetically testable. Suite: 46 files / 296 tests green. v1.3.0 is the **full-i18n edition**: the CLI now speaks five languages — `en` (default & fallback), `id`, `zh`, `ru`, `es` — through a single catalog (`t(key, params)` in `src/i18n/`, `{placeholder}` interpolation, zero hard-coded user-facing strings left in `src/` outside the i18n module, help manual / wizard menus / table headers / guard & delete messages / treemap HTML included). The language resolves as `--language` > `.nmhrc` `language` key > `NMH_LANG` > `LC_ALL`/`LANG` > `en` (unknown flag values refused loudly with exit 1, unknown env values fall back to `en` silently), a CI completeness gate keeps every locale's key set and `{placeholder}` slots 1:1 with the English source, and both frozen contracts — `--json` payload keys and the exit-code table — are language-independent. Suite: 48 files / 315 tests green. The v1.3.1 patch **completes the five-language promise**: `zh` and `ru` are filled with their real Mandarin/Russian translations (all 480 keys, the same 1:1 key + `{placeholder}` gate applies), and `nmh help` documents the `--language <lang>` flag — codifying the rule that every new flag, command or feature ships with its help entry in the same release. Suite: 48 files / 319 tests green. v1.4.0 is the **update-zoom edition**: `nmh update` reads any npm **dist-tag** — `--tag <name>` / `--check [tag]` / the persisted `.nmhrc` `updateTag` key (`nmh config set --update-tag beta`) — with version compares that finally understand **prereleases** (a triple tie is broken prerelease-wise, so `1.4.0` beats `1.4.0-beta.1` and `beta.2` beats `beta.1`); a tag pointing below the installed version is a **downgrade** with the same consent gate as an upgrade but a NO-default confirm (non-TTY still needs `-y`), unknown tags refuse loudly with the available list, `--info` lists every published tag, and the `--json` payload grows additively (`tag` / `target` / `direction` / `distTags?` — the frozen keys untouched). The wizard menu gains **🔁 Update nmh**, the wizard boot peeks the registry by default (24 h cache, `updateCheck: false` opts out), and the English catalog was swept to be 100% English (a handful of inherited keys still held Indonesian values; key names are frozen — only values changed). Suite: 48 files / 325 tests green.
|
|
478
483
|
|
|
479
484
|
## Development
|
|
480
485
|
|
package/dist/cli.js
CHANGED
|
@@ -176,35 +176,35 @@ var en = {
|
|
|
176
176
|
"render.stats.directDeps": "Direct deps : {count} declared across the scanned projects",
|
|
177
177
|
"render.stats.waste": "Waste (dedupable) : {size} ({percent}% of package sizes)",
|
|
178
178
|
"render.stats.noLicenses": "no package manifests found \u2014 nothing to license",
|
|
179
|
-
"render.stats.copyleftProd": " \u26A0 copyleft
|
|
180
|
-
"render.stats.copyleftOther": " (copyleft,
|
|
179
|
+
"render.stats.copyleftProd": " \u26A0 copyleft in production dependencies",
|
|
180
|
+
"render.stats.copyleftOther": " (copyleft, not a prod dependency)",
|
|
181
181
|
"render.stats.experimental": "(experimental)",
|
|
182
182
|
"render.stats.grade": "grade",
|
|
183
183
|
"render.stats.wasteLabel": "waste",
|
|
184
184
|
"render.stats.dupLabel": "dup factor",
|
|
185
185
|
"render.stats.deadLabel": "dead",
|
|
186
|
-
"render.stats.deadNotAudited": "(
|
|
186
|
+
"render.stats.deadNotAudited": "(not audited \u2014 add --dead for the list)",
|
|
187
187
|
"render.stats.sizeLabel": "size",
|
|
188
|
-
"render.stats.co2Storage": "
|
|
189
|
-
"render.stats.co2Transfer": "
|
|
190
|
-
"render.stats.deprecatedNone": "
|
|
188
|
+
"render.stats.co2Storage": "rough estimate, not a carbon audit \u2014 one year of storage",
|
|
189
|
+
"render.stats.co2Transfer": "plus re-downloading everything once",
|
|
190
|
+
"render.stats.deprecatedNone": "no deprecated packages \u2600\uFE0F",
|
|
191
191
|
"render.stats.deprecatedCount": "{count} instance deprecated:",
|
|
192
|
-
"render.stats.moreDeprecations": "\
|
|
192
|
+
"render.stats.moreDeprecations": "\u2026and {n} more",
|
|
193
193
|
"render.stats.lockfileGrade": "(lockfile-grade)",
|
|
194
|
-
"render.stats.graphSuffix": "lockfile-grade \u2014
|
|
194
|
+
"render.stats.graphSuffix": "lockfile-grade \u2014 the rest is manifest-grade",
|
|
195
195
|
"render.stats.graphRoot": "root direct : {declared} declared \u2192 {nodes} tree nodes via {edges} edges",
|
|
196
|
-
"render.stats.graphNoDepth": "
|
|
196
|
+
"render.stats.graphNoDepth": "nothing traceable in depth from the root \u2014 this lockfile may be v1/broken",
|
|
197
197
|
"render.stats.graphUnreachable": "+ {n} node(s) unreachable from the root (optional/peer pruning)",
|
|
198
198
|
"render.stats.noLockfile": "no usable lockfile \u2014 manifest-grade",
|
|
199
|
-
"render.stats.reinstallNaive": "(
|
|
200
|
-
"render.stats.reinstallLine": "
|
|
199
|
+
"render.stats.reinstallNaive": "(naive)",
|
|
200
|
+
"render.stats.reinstallLine": "reinstall everything once : ~{duration}",
|
|
201
201
|
"render.stats.copies": "\xD7{n} copies",
|
|
202
202
|
"render.stats.oneCopy": "\xD71 copy",
|
|
203
|
-
"render.stats.dedupSaving": " \u2190 dedup
|
|
203
|
+
"render.stats.dedupSaving": " \u2190 dedup could save {size}",
|
|
204
204
|
"render.stats.longTail": "\u2026 plus {names} more package name(s) \xB7 {instances} instances \xB7 {size}",
|
|
205
|
-
"render.stats.bisaHemat": "
|
|
205
|
+
"render.stats.bisaHemat": " could save",
|
|
206
206
|
"render.stats.declaredRange": "{project} declared {range} ({field})",
|
|
207
|
-
"render.stats.transitive": "transitive (
|
|
207
|
+
"render.stats.transitive": "transitive (not declared in a manifest)",
|
|
208
208
|
"render.global.title": "\u{1F310} nmh stats \u2014 global installation analysis",
|
|
209
209
|
"render.global.readonly": "(\u26A0\uFE0F global mode \u2014 read-only; needs access to the PM prefixes \u2014 sudo is never auto-applied)",
|
|
210
210
|
"render.global.pmDetected": "PM detected : {pms}{skipped}",
|
|
@@ -238,8 +238,8 @@ var en = {
|
|
|
238
238
|
"render.why.title": "\u{1F50D} why '{pkg}' \u2014 {count} instance(s)",
|
|
239
239
|
"render.why.linked": "linked",
|
|
240
240
|
"render.why.declares": " project : {project} declares {range} ({field})",
|
|
241
|
-
"render.why.noName": "(manifest
|
|
242
|
-
"render.why.transitive": " project : transitive \u2014
|
|
241
|
+
"render.why.noName": "(unnamed manifest)",
|
|
242
|
+
"render.why.transitive": " project : transitive \u2014 not declared in any manifest",
|
|
243
243
|
"render.why.requiredBy": " required by : {count} package(s)",
|
|
244
244
|
"render.why.moreRequirers": " \u2026 plus {n} more requirer(s)",
|
|
245
245
|
"render.why.rootOnly": " required by : no package in the lockfile graph depends on it (root-only copy?)",
|
|
@@ -251,7 +251,7 @@ var en = {
|
|
|
251
251
|
// ── utils: format / update-check / version ─────────────────────────────
|
|
252
252
|
"format.now": "now",
|
|
253
253
|
"format.ago": "{n} ago",
|
|
254
|
-
"update.note": "update
|
|
254
|
+
"update.note": "update available: {current} \u2192 {latest} \u2014 npm i -g node-modules-hunter (checked every 24 h, opt-in via --update-check)",
|
|
255
255
|
"version.tagline": "hunt node_modules \u2014 scan \xB7 measure \xB7 clean safely",
|
|
256
256
|
"version.yes": "yes",
|
|
257
257
|
"version.no": "no",
|
|
@@ -302,6 +302,7 @@ var en = {
|
|
|
302
302
|
"wizard.menu.map": "\u{1F5FA}\uFE0F Map dependencies \u2014 project \u2192 PM \u2192 declared deps",
|
|
303
303
|
"wizard.menu.stats": "\u{1F4CA} Detailed report \u2014 the full stats read-out",
|
|
304
304
|
"wizard.menu.settings": "\u2699\uFE0F Settings & integration (read-only view)",
|
|
305
|
+
"wizard.menu.update": "\u{1F501} Update nmh (checks the registry, asks first)",
|
|
305
306
|
"wizard.menu.quit": "\u23F9 Exit nmh",
|
|
306
307
|
"wizard.outro.bye": "bye \u{1F44B} \u2014 nothing deleted",
|
|
307
308
|
"wizard.search.message": "Search installed packages \u2014 which pattern?",
|
|
@@ -335,9 +336,9 @@ var en = {
|
|
|
335
336
|
"update.info.installed": "installed {value}",
|
|
336
337
|
"update.info.latest": "latest {value}",
|
|
337
338
|
"update.info.update": "update {value}",
|
|
338
|
-
"update.info.available": "
|
|
339
|
-
"update.info.availableNonGlobal": " (
|
|
340
|
-
"update.info.none": "
|
|
339
|
+
"update.info.available": "available \u2014 run `nmh update`",
|
|
340
|
+
"update.info.availableNonGlobal": " (or: npm i -g node-modules-hunter)",
|
|
341
|
+
"update.info.none": "none \u2014 this is the latest version",
|
|
341
342
|
"update.info.summary": "summary {value}",
|
|
342
343
|
"update.info.tarball": "tarball {value}",
|
|
343
344
|
"update.info.sizeSuffix": " ({size}{files} files)",
|
|
@@ -345,17 +346,22 @@ var en = {
|
|
|
345
346
|
"update.info.license": "license {value}",
|
|
346
347
|
"update.info.published": "published {value}",
|
|
347
348
|
"update.err.noRegistry": "cannot read the latest version \u2014 is the registry reachable? (npm view node-modules-hunter version)",
|
|
348
|
-
"update.check.available": "\u2191 update
|
|
349
|
-
"update.check.latest": "\u2713 nmh {current}
|
|
350
|
-
"update.latestNoInstall": "\u2713 nmh {current}
|
|
351
|
-
"update.manual.title": "nmh {current}
|
|
352
|
-
"update.manual.command": " npm i -g node-modules-hunter (
|
|
353
|
-
"update.err.needsAnswer": "update
|
|
349
|
+
"update.check.available": "\u2191 update available: {current} \u2192 {latest} \u2014 run `nmh update` to install",
|
|
350
|
+
"update.check.latest": "\u2713 nmh {current} is already the latest version (registry: {latest})",
|
|
351
|
+
"update.latestNoInstall": "\u2713 nmh {current} is already the latest version (registry: {latest}) \u2014 nothing installed",
|
|
352
|
+
"update.manual.title": "nmh {current} is installed outside npm global \u2014 update manually:",
|
|
353
|
+
"update.manual.command": " npm i -g node-modules-hunter (or: pnpm add -g / bunx / brew upgrade node-modules-hunter)",
|
|
354
|
+
"update.err.needsAnswer": "update needs an explicit answer \u2014 -y to install, -n to decline (--check/--info just look)",
|
|
354
355
|
"update.confirm": "Update nmh {current} \u2192 {latest} via npm install -g?",
|
|
355
|
-
"update.declined": "\u2715
|
|
356
|
-
"update.err.failed": "\u26A0 update
|
|
357
|
-
"update.err.manualHint": "
|
|
358
|
-
"update.done": "\u2713
|
|
356
|
+
"update.declined": "\u2715 staying on nmh {current} \u2014 the {latest} update was not installed",
|
|
357
|
+
"update.err.failed": "\u26A0 update failed: {detail}",
|
|
358
|
+
"update.err.manualHint": " try manually: npm install -g node-modules-hunter@{latest}",
|
|
359
|
+
"update.done": "\u2713 updated {current} \u2192 {latest} (npm install -g node-modules-hunter)",
|
|
360
|
+
"update.info.tags": "dist-tags {tags}",
|
|
361
|
+
"update.check.onTag": "(dist-tag: {tag})",
|
|
362
|
+
"update.confirm.downgrade": 'Downgrade nmh {current} \u2192 {target} from dist-tag "{tag}"?',
|
|
363
|
+
"update.err.tagUnknown": 'dist-tag "{tag}" not found \u2014 available: {tags}',
|
|
364
|
+
"update.err.invalidTag": 'invalid dist-tag "{value}" \u2014 use letters, digits, dot, hyphen, underscore',
|
|
359
365
|
// ── commands/global.ts ──────────────────────────────────────────────────
|
|
360
366
|
"global.spin.probe": "probing global prefixes\u2026",
|
|
361
367
|
"global.spin.progress": "global {pm} \u2014 {done}/{total} packages",
|
|
@@ -371,7 +377,7 @@ var en = {
|
|
|
371
377
|
"why.warn.none": "no instance of '{pkg}' in the scanned node_modules \u2014 nmh why <pkg> [dirs]",
|
|
372
378
|
"treemap.warn.none": "no node_modules found \u2014 nothing to draw here \u{1F643}",
|
|
373
379
|
"treemap.err.write": "\u{1F6D1} could not write the treemap file \u2192 {path} \u2014 {detail}",
|
|
374
|
-
"treemap.done": "\u{1F5FA}\uFE0F treemap \u2192 {path} \u2014
|
|
380
|
+
"treemap.done": "\u{1F5FA}\uFE0F treemap \u2192 {path} \u2014 open it in a browser, hover a cell for details",
|
|
375
381
|
// ── verbose diagnostics & utils ─────────────────────────────────────────
|
|
376
382
|
"verbose.deleteLogUnavailable": "delete log unavailable: {detail}",
|
|
377
383
|
"verbose.configUsing": "config: using {file}",
|
|
@@ -396,11 +402,11 @@ var en = {
|
|
|
396
402
|
"verbose.npmViewFailed": "npm view failed (rc {code}): {stderr}",
|
|
397
403
|
// ── commands/stats.ts ───────────────────────────────────────────────────
|
|
398
404
|
"stats.spin.progress": "analyzing {done}/{total} node_modules\u2026",
|
|
399
|
-
"stats.hint.noDeclared": "copies
|
|
405
|
+
"stats.hint.noDeclared": "copies resolve through their own parents \u2014 no direct knob at the project level",
|
|
400
406
|
"stats.hint.tail": " (declared {range})",
|
|
401
|
-
"stats.hint.pnpm": "
|
|
402
|
-
"stats.hint.sameRange": "
|
|
403
|
-
"stats.hint.diffRanges": "
|
|
407
|
+
"stats.hint.pnpm": "identical declared ranges \u2014 the pnpm virtual store folds hoisted copies; one version at the workspace root is enough{tail}",
|
|
408
|
+
"stats.hint.sameRange": "identical declared ranges \u2014 rerun install / npm dedupe \xB7 yarn dedupe folds hoisted copies{tail}",
|
|
409
|
+
"stats.hint.diffRanges": "declared ranges differ ({ranges}) \u2014 align them in package.json first, then reinstall",
|
|
404
410
|
"stats.err.noBaseline": "no baseline named '{name}' \u2014 {detail}",
|
|
405
411
|
"stats.err.baselinesSaved": "saved: {list}",
|
|
406
412
|
"stats.err.saveFirst": "save one first with nmh stats --save-baseline <name>",
|
|
@@ -411,7 +417,7 @@ var en = {
|
|
|
411
417
|
"stats.err.saveFailed": "could not save baseline '{name}': {detail}",
|
|
412
418
|
// ── core/treemap.ts (HTML artifact) ────────────────────────────────────
|
|
413
419
|
"treemap.link": " \u27F6link",
|
|
414
|
-
"treemap.html.header": "nmh treemap \u2014 {entries} \u2014 {count} node_modules \u2014 hover
|
|
420
|
+
"treemap.html.header": "nmh treemap \u2014 {entries} \u2014 {count} node_modules \u2014 hover a cell for disk details, generated {at}",
|
|
415
421
|
"treemap.html.aria": "treemap ukuran node_modules",
|
|
416
422
|
// ── help manual ─────────────────────────────────────────────────────────
|
|
417
423
|
"help.tagline": "hunt bloated node_modules folders: scan, measure, clean safely (npm/pnpm/yarn/bun)",
|
|
@@ -421,9 +427,9 @@ var en = {
|
|
|
421
427
|
"help.statsSub.title": "Stats subcommands",
|
|
422
428
|
"help.options.title": "Options \u2014 {group}",
|
|
423
429
|
"help.examples.title": "Examples",
|
|
424
|
-
"help.cmd.bare": "interactive wizard: arrow menu (delete all / pick / search / map / report / settings)",
|
|
430
|
+
"help.cmd.bare": "interactive wizard: arrow menu (delete all / pick / search / map / report / update / settings)",
|
|
425
431
|
"help.cmd.paths": "shortcut: scan given path(s); one-liner actions via flags (--delete, --search, \u2026)",
|
|
426
|
-
"help.cmd.wizard": "v1.2: the wizard on explicit targets (--dir=./a,./b skips the auto-climb); -- <view> opens a view first",
|
|
432
|
+
"help.cmd.wizard": "v1.2: the wizard on explicit targets (--dir=./a,./b skips the auto-climb); -- <view> opens a view first; the menu now includes \u{1F501} Update nmh (v1.4)",
|
|
427
433
|
"help.cmd.scan": "full scan across targets (default: cwd)",
|
|
428
434
|
"help.cmd.clean": "scan + delete everything safe (trash by default)",
|
|
429
435
|
"help.cmd.search": "find installed packages by name (+ versions & sizes) \u2014 read-only",
|
|
@@ -433,7 +439,7 @@ var en = {
|
|
|
433
439
|
"help.cmd.treemap": "single-file interactive HTML treemap \u2192 nmh-treemap.html",
|
|
434
440
|
"help.cmd.global": "global installs across npm/pnpm/yarn/bun \u2014 read-only",
|
|
435
441
|
"help.cmd.config": "manage .nmhrc from the CLI: info \xB7 set \xB7 add \xB7 remove \xB7 unset",
|
|
436
|
-
"help.cmd.update": "v1.
|
|
442
|
+
"help.cmd.update": "v1.4: shows the facts and asks before installing \u2014 --check [tag] / --info compare only; --tag reads a dist-tag (downgrades confirm with NO as default); -y installs, -n declines, --force skips the ask",
|
|
437
443
|
"help.cmd.version": "banner: tool version, node+abi, OS/arch/kernel, tty (alias: -v / --version)",
|
|
438
444
|
"help.cmd.help": "this help (alias: -h / --help)",
|
|
439
445
|
"help.statsSub.byType": "breakdown per dependency field (dep/dev/optional/peer/transitive)",
|
|
@@ -463,6 +469,8 @@ var en = {
|
|
|
463
469
|
"help.flag.saveReport": "also write the printed report to a file (.json/.md/.txt; --report <file> aliases it)",
|
|
464
470
|
"help.flag.wizard": "v1.2: open the wizard explicitly \u2014 same as bare `nmh`, but a pipe refuses with directions instead of a scan",
|
|
465
471
|
"help.flag.updateFamily": "v1.2: read-only views vs consented install \u2014 see `nmh update` row above",
|
|
472
|
+
"help.flag.tag": "read a specific npm dist-tag \u2014 nmh update --tag beta; --check <tag> compares against it (v1.4)",
|
|
473
|
+
"help.flag.updateTag": "persisted update dist-tag (updateTag in .nmhrc) \u2014 what `nmh update` / `--check` read by default (v1.4)",
|
|
466
474
|
"help.flag.updateCheck": "peek npm for a newer release (non-blocking, 24 h cache; also settable in .nmhrc)",
|
|
467
475
|
"help.flag.stale": "keep only projects idle >= <days>; ladder = git commit \u2192 manifest \u2192 folder mtime; no evidence = dropped",
|
|
468
476
|
"help.flag.fastSize": "measure with one `du -sk` per entry (KiB granularity) instead of walking every file",
|
|
@@ -550,6 +558,9 @@ var en = {
|
|
|
550
558
|
"cli.err.rootRefusal": "refusing a delete op over the filesystem root \u2014 point --dir at the project directory you want cleaned",
|
|
551
559
|
"cli.err.checkOnlyUpdate": "--check only works with the update command \u2014 nmh update --check",
|
|
552
560
|
"cli.err.infoOnlyUpdate": "--info only works with the update command \u2014 nmh update --info",
|
|
561
|
+
"cli.err.tagNeedsValue": "--tag needs a dist-tag name \u2014 nmh update --tag beta (bare --check reads --tag / .nmhrc / latest)",
|
|
562
|
+
"cli.err.invalidTag": 'invalid dist-tag "{value}" \u2014 use letters, digits, dot, hyphen, underscore',
|
|
563
|
+
"cli.err.tagOnlyUpdate": "--tag only works with the update command \u2014 nmh update --tag beta",
|
|
553
564
|
"cli.err.updateArgs": "update takes no arguments \u2014 plain `nmh update` (add --json for the payload)",
|
|
554
565
|
"cli.err.checkInfoExclusive": "--check and --info are two different read-only views \u2014 pick one (nmh update --check | --info)",
|
|
555
566
|
"cli.err.routerOrphan": "the `--` router belongs to the wizard \u2014 nmh wizard -- stats|map|search|why|treemap \u2026",
|
|
@@ -596,6 +607,7 @@ var en = {
|
|
|
596
607
|
"config.err.notBoolean": "invalid config: {file}: {key} must be true or false (got {value})",
|
|
597
608
|
"config.err.invalidLanguage": "invalid config: {file}: language must be one of en | id | zh | ru | es (got {value})",
|
|
598
609
|
"config.err.invalidLogDir": "invalid config: {file}: logDir must be a non-empty string",
|
|
610
|
+
"config.err.invalidUpdateTag": "invalid config: {file}: updateTag must be a dist-tag name \u2014 letters, digits, dot, hyphen, underscore (got {value})",
|
|
599
611
|
"config.err.unreadable": "config unreadable: {file} ({code})",
|
|
600
612
|
"config.err.notFound": "config file not found: {file}",
|
|
601
613
|
"config.warn.unknownKey": '{file}: unknown config key "{key}" \u2014 ignored',
|
|
@@ -603,6 +615,7 @@ var en = {
|
|
|
603
615
|
"config.err.invalidDepthValue": "invalid --depth value: {value} (expected a non-negative integer)",
|
|
604
616
|
"config.err.invalidModeValue": "invalid --default-mode: {value} (expected hard | soft | trash)",
|
|
605
617
|
"config.err.invalidLanguageValue": "invalid --language value: {value} (expected en | id | zh | ru | es)",
|
|
618
|
+
"config.err.invalidUpdateTagValue": "invalid --update-tag value: {value} (letters, digits, dot, hyphen, underscore)",
|
|
606
619
|
"config.err.boolNeedsValue": "{label} needs true or false \u2014 e.g. nmh config set --animate=false",
|
|
607
620
|
"config.err.setListNeedsValue": "config set --{flag} needs the list value \u2014 e.g. --{flag}=.npm,.nvm",
|
|
608
621
|
"config.err.addListNeedsValue": "config add --{flag} needs items to append \u2014 e.g. --{flag}=.cache,self",
|
|
@@ -803,6 +816,7 @@ var id = {
|
|
|
803
816
|
"wizard.menu.map": "\u{1F5FA}\uFE0F Petakan dependensi \u2014 proyek \u2192 PM \u2192 dep terdeklarasi",
|
|
804
817
|
"wizard.menu.stats": "\u{1F4CA} Laporan detail \u2014 read-out stats lengkap",
|
|
805
818
|
"wizard.menu.settings": "\u2699\uFE0F Setelan & integrasi (tampilan read-only)",
|
|
819
|
+
"wizard.menu.update": "\u{1F501} Update nmh (cek registry, tanya dulu)",
|
|
806
820
|
"wizard.menu.quit": "\u23F9 Keluar dari nmh",
|
|
807
821
|
"wizard.outro.bye": "sampai jumpa \u{1F44B} \u2014 tidak ada yang dihapus",
|
|
808
822
|
"wizard.search.message": "Cari paket terinstall \u2014 pattern apa?",
|
|
@@ -857,6 +871,11 @@ var id = {
|
|
|
857
871
|
"update.err.failed": "\u26A0 update gagal: {detail}",
|
|
858
872
|
"update.err.manualHint": " coba manual: npm install -g node-modules-hunter@{latest}",
|
|
859
873
|
"update.done": "\u2713 terupdate {current} \u2192 {latest} (npm install -g node-modules-hunter)",
|
|
874
|
+
"update.info.tags": "dist-tags {tags}",
|
|
875
|
+
"update.check.onTag": "(dist-tag: {tag})",
|
|
876
|
+
"update.confirm.downgrade": 'Turunkan nmh {current} \u2192 {target} dari dist-tag "{tag}"?',
|
|
877
|
+
"update.err.tagUnknown": 'dist-tag "{tag}" tidak ditemukan \u2014 yang tersedia: {tags}',
|
|
878
|
+
"update.err.invalidTag": 'dist-tag "{value}" tidak valid \u2014 pakai huruf, digit, titik, tanda hubung, garis bawah',
|
|
860
879
|
// ── commands/global.ts ──────────────────────────────────────────────────
|
|
861
880
|
"global.spin.probe": "memeriksa prefix global\u2026",
|
|
862
881
|
"global.spin.progress": "global {pm} \u2014 {done}/{total} paket",
|
|
@@ -922,9 +941,9 @@ var id = {
|
|
|
922
941
|
"help.statsSub.title": "Subperintah stats",
|
|
923
942
|
"help.options.title": "Opsi \u2014 {group}",
|
|
924
943
|
"help.examples.title": "Contoh",
|
|
925
|
-
"help.cmd.bare": "wizard interaktif: menu panah (hapus semua / pilih / search / map / report / setelan)",
|
|
944
|
+
"help.cmd.bare": "wizard interaktif: menu panah (hapus semua / pilih / search / map / report / update / setelan)",
|
|
926
945
|
"help.cmd.paths": "jalan pintas: scan path yang diberikan; aksi satu-baris via flag (--delete, --search, \u2026)",
|
|
927
|
-
"help.cmd.wizard": "v1.2: wizard pada target eksplisit (--dir=./a,./b melewati auto-climb); -- <view> membuka view dulu",
|
|
946
|
+
"help.cmd.wizard": "v1.2: wizard pada target eksplisit (--dir=./a,./b melewati auto-climb); -- <view> membuka view dulu; menu kini punya \u{1F501} Update nmh (v1.4)",
|
|
928
947
|
"help.cmd.scan": "scan penuh di seluruh target (bawaan: cwd)",
|
|
929
948
|
"help.cmd.clean": "scan + hapus semua yang aman (trash secara bawaan)",
|
|
930
949
|
"help.cmd.search": "cari paket terinstall berdasarkan nama (+ versi & ukuran) \u2014 read-only",
|
|
@@ -934,7 +953,7 @@ var id = {
|
|
|
934
953
|
"help.cmd.treemap": "treemap HTML interaktif satu-file \u2192 nmh-treemap.html",
|
|
935
954
|
"help.cmd.global": "instalasi global lintas npm/pnpm/yarn/bun \u2014 read-only",
|
|
936
955
|
"help.cmd.config": "kelola .nmhrc dari CLI: info \xB7 set \xB7 add \xB7 remove \xB7 unset",
|
|
937
|
-
"help.cmd.update": "v1.
|
|
956
|
+
"help.cmd.update": "v1.4: menampilkan fakta dan bertanya sebelum menginstall \u2014 --check [tag] / --info hanya membandingkan; --tag membaca dist-tag (downgrade konfirmasinya default TIDAK); -y menginstall, -n menolak, --force melewati tanya",
|
|
938
957
|
"help.cmd.version": "banner: versi tool, node+abi, OS/arch/kernel, tty (alias: -v / --version)",
|
|
939
958
|
"help.cmd.help": "bantuan ini (alias: -h / --help)",
|
|
940
959
|
"help.statsSub.byType": "rincian per field dependensi (dep/dev/optional/peer/transitive)",
|
|
@@ -964,6 +983,8 @@ var id = {
|
|
|
964
983
|
"help.flag.saveReport": "tuliskan juga laporan yang tercetak ke file (.json/.md/.txt; --report <file> aliasnya)",
|
|
965
984
|
"help.flag.wizard": "v1.2: buka wizard secara eksplisit \u2014 sama dengan `nmh` polos, tapi pipe menolak dengan arah alih-alih scan",
|
|
966
985
|
"help.flag.updateFamily": "v1.2: view read-only vs install yang disetujui \u2014 lihat baris `nmh update` di atas",
|
|
986
|
+
"help.flag.tag": "baca dist-tag npm tertentu \u2014 nmh update --tag beta; --check <tag> membandingkan dengannya (v1.4)",
|
|
987
|
+
"help.flag.updateTag": "dist-tag update yang tersimpan (updateTag di .nmhrc) \u2014 yang dibaca `nmh update` / `--check` secara default (v1.4)",
|
|
967
988
|
"help.flag.updateCheck": "intip npm untuk rilis lebih baru (non-blocking, cache 24 jam; juga bisa di .nmhrc)",
|
|
968
989
|
"help.flag.stale": "hanya proyek idle >= <hari>; tangga = git commit \u2192 manifest \u2192 mtime folder; tanpa bukti = dibuang",
|
|
969
990
|
"help.flag.fastSize": "ukur dengan satu `du -sk` per entry (granularitas KiB) alih-alih jalan di tiap file",
|
|
@@ -1051,6 +1072,9 @@ var id = {
|
|
|
1051
1072
|
"cli.err.rootRefusal": "menolak delete op di atas root filesystem \u2014 arahkan --dir ke direktori proyek yang ingin dibersihkan",
|
|
1052
1073
|
"cli.err.checkOnlyUpdate": "--check hanya untuk perintah update \u2014 nmh update --check",
|
|
1053
1074
|
"cli.err.infoOnlyUpdate": "--info hanya untuk perintah update \u2014 nmh update --info",
|
|
1075
|
+
"cli.err.tagNeedsValue": "--tag butuh nama dist-tag \u2014 nmh update --tag beta (--check tanpa nilai membaca --tag / .nmhrc / latest)",
|
|
1076
|
+
"cli.err.invalidTag": 'dist-tag "{value}" tidak valid \u2014 pakai huruf, digit, titik, tanda hubung, garis bawah',
|
|
1077
|
+
"cli.err.tagOnlyUpdate": "--tag hanya untuk perintah update \u2014 nmh update --tag beta",
|
|
1054
1078
|
"cli.err.updateArgs": "update tidak menerima argumen \u2014 `nmh update` polos (tambah --json untuk payload)",
|
|
1055
1079
|
"cli.err.checkInfoExclusive": "--check dan --info adalah dua view read-only berbeda \u2014 pilih satu (nmh update --check | --info)",
|
|
1056
1080
|
"cli.err.routerOrphan": "router `--` milik wizard \u2014 nmh wizard -- stats|map|search|why|treemap \u2026",
|
|
@@ -1097,6 +1121,7 @@ var id = {
|
|
|
1097
1121
|
"config.err.notBoolean": "config tidak valid: {file}: {key} harus true atau false (dapat {value})",
|
|
1098
1122
|
"config.err.invalidLanguage": "config tidak valid: {file}: language harus salah satu dari en | id | zh | ru | es (dapat {value})",
|
|
1099
1123
|
"config.err.invalidLogDir": "config tidak valid: {file}: logDir harus string tak-kosong",
|
|
1124
|
+
"config.err.invalidUpdateTag": "config tidak valid: {file}: updateTag harus nama dist-tag \u2014 huruf, digit, titik, tanda hubung, garis bawah (dapat {value})",
|
|
1100
1125
|
"config.err.unreadable": "config tidak bisa dibaca: {file} ({code})",
|
|
1101
1126
|
"config.err.notFound": "file config tidak ditemukan: {file}",
|
|
1102
1127
|
"config.warn.unknownKey": '{file}: kunci config tidak dikenal "{key}" \u2014 diabaikan',
|
|
@@ -1104,6 +1129,7 @@ var id = {
|
|
|
1104
1129
|
"config.err.invalidDepthValue": "nilai --depth tidak valid: {value} (harus bilangan bulat non-negatif)",
|
|
1105
1130
|
"config.err.invalidModeValue": "nilai --default-mode tidak valid: {value} (harus hard | soft | trash)",
|
|
1106
1131
|
"config.err.invalidLanguageValue": "nilai --language tidak valid: {value} (harus en | id | zh | ru | es)",
|
|
1132
|
+
"config.err.invalidUpdateTagValue": "nilai --update-tag tidak valid: {value} (huruf, digit, titik, tanda hubung, garis bawah)",
|
|
1107
1133
|
"config.err.boolNeedsValue": "{label} butuh true atau false \u2014 mis. nmh config set --animate=false",
|
|
1108
1134
|
"config.err.setListNeedsValue": "config set --{flag} butuh nilai daftarnya \u2014 mis. --{flag}=.npm,.nvm",
|
|
1109
1135
|
"config.err.addListNeedsValue": "config add --{flag} butuh item untuk ditambahkan \u2014 mis. --{flag}=.cache,self",
|
|
@@ -1304,6 +1330,7 @@ var zh = {
|
|
|
1304
1330
|
"wizard.menu.map": "\u{1F5FA}\uFE0F \u6620\u5C04\u4F9D\u8D56 \u2014 \u9879\u76EE \u2192 PM \u2192 \u58F0\u660E\u7684\u4F9D\u8D56",
|
|
1305
1331
|
"wizard.menu.stats": "\u{1F4CA} \u8BE6\u7EC6\u62A5\u544A \u2014 \u5B8C\u6574\u7684 stats \u8F93\u51FA",
|
|
1306
1332
|
"wizard.menu.settings": "\u2699\uFE0F \u8BBE\u7F6E\u4E0E\u96C6\u6210\uFF08\u53EA\u8BFB\u89C6\u56FE\uFF09",
|
|
1333
|
+
"wizard.menu.update": "\u{1F501} \u66F4\u65B0 nmh\uFF08\u67E5\u8BE2 registry\uFF0C\u5148\u8BE2\u95EE\uFF09",
|
|
1307
1334
|
"wizard.menu.quit": "\u23F9 \u9000\u51FA nmh",
|
|
1308
1335
|
"wizard.outro.bye": "\u518D\u89C1 \u{1F44B} \u2014 \u672A\u5220\u9664\u4EFB\u4F55\u5185\u5BB9",
|
|
1309
1336
|
"wizard.search.message": "\u641C\u7D22\u5DF2\u5B89\u88C5\u7684\u5305 \u2014 \u7528\u4EC0\u4E48\u6A21\u5F0F\uFF1F",
|
|
@@ -1358,6 +1385,11 @@ var zh = {
|
|
|
1358
1385
|
"update.err.failed": "\u26A0 \u66F4\u65B0\u5931\u8D25\uFF1A{detail}",
|
|
1359
1386
|
"update.err.manualHint": " \u624B\u52A8\u5C1D\u8BD5\uFF1Anpm install -g node-modules-hunter@{latest}",
|
|
1360
1387
|
"update.done": "\u2713 \u5DF2\u66F4\u65B0 {current} \u2192 {latest}\uFF08npm install -g node-modules-hunter\uFF09",
|
|
1388
|
+
"update.info.tags": "dist-tags {tags}",
|
|
1389
|
+
"update.check.onTag": "\uFF08dist-tag\uFF1A{tag}\uFF09",
|
|
1390
|
+
"update.confirm.downgrade": '\u5C06 nmh {current} \u964D\u7EA7\u5230 {target}\uFF08\u6765\u81EA dist-tag "{tag}"\uFF09\uFF1F',
|
|
1391
|
+
"update.err.tagUnknown": '\u672A\u627E\u5230 dist-tag "{tag}" \u2014 \u53EF\u7528\uFF1A{tags}',
|
|
1392
|
+
"update.err.invalidTag": 'dist-tag "{value}" \u65E0\u6548 \u2014 \u53EA\u80FD\u4F7F\u7528\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u8FDE\u5B57\u7B26\u3001\u4E0B\u5212\u7EBF',
|
|
1361
1393
|
// ── commands/global.ts ──────────────────────────────────────────────────
|
|
1362
1394
|
"global.spin.probe": "\u6B63\u5728\u63A2\u6D4B\u5168\u5C40\u524D\u7F00\u2026",
|
|
1363
1395
|
"global.spin.progress": "\u5168\u5C40 {pm} \u2014 {done}/{total} \u4E2A\u5305",
|
|
@@ -1423,9 +1455,9 @@ var zh = {
|
|
|
1423
1455
|
"help.statsSub.title": "stats \u5B50\u547D\u4EE4",
|
|
1424
1456
|
"help.options.title": "\u9009\u9879 \u2014 {group}",
|
|
1425
1457
|
"help.examples.title": "\u793A\u4F8B",
|
|
1426
|
-
"help.cmd.bare": "\u4EA4\u4E92\u5F0F\u5411\u5BFC\uFF1A\u65B9\u5411\u952E\u83DC\u5355\uFF08\u5168\u90E8\u5220\u9664 / \u6311\u9009 / \u641C\u7D22 / \u6620\u5C04 / \u62A5\u544A / \u8BBE\u7F6E\uFF09",
|
|
1458
|
+
"help.cmd.bare": "\u4EA4\u4E92\u5F0F\u5411\u5BFC\uFF1A\u65B9\u5411\u952E\u83DC\u5355\uFF08\u5168\u90E8\u5220\u9664 / \u6311\u9009 / \u641C\u7D22 / \u6620\u5C04 / \u62A5\u544A / \u66F4\u65B0 / \u8BBE\u7F6E\uFF09",
|
|
1427
1459
|
"help.cmd.paths": "\u6377\u5F84\uFF1A\u626B\u63CF\u7ED9\u5B9A\u8DEF\u5F84\uFF1B\u901A\u8FC7 flag \u6267\u884C\u5355\u884C\u52A8\u4F5C\uFF08--delete\u3001--search \u7B49\uFF09",
|
|
1428
|
-
"help.cmd.wizard": "v1.2\uFF1A\u5BF9\u663E\u5F0F\u76EE\u6807\u8FD0\u884C\u5411\u5BFC\uFF08--dir=./a,./b \u8DF3\u8FC7\u81EA\u52A8\u4E0A\u6EAF\uFF09\uFF1B-- <view> \u5148\u6253\u5F00\u4E00\u4E2A\u89C6\u56FE",
|
|
1460
|
+
"help.cmd.wizard": "v1.2\uFF1A\u5BF9\u663E\u5F0F\u76EE\u6807\u8FD0\u884C\u5411\u5BFC\uFF08--dir=./a,./b \u8DF3\u8FC7\u81EA\u52A8\u4E0A\u6EAF\uFF09\uFF1B-- <view> \u5148\u6253\u5F00\u4E00\u4E2A\u89C6\u56FE\uFF1B\u83DC\u5355\u73B0\u5DF2\u5305\u542B \u{1F501} \u66F4\u65B0 nmh\uFF08v1.4\uFF09",
|
|
1429
1461
|
"help.cmd.scan": "\u8DE8\u76EE\u6807\u5B8C\u6574\u626B\u63CF\uFF08\u9ED8\u8BA4\uFF1Acwd\uFF09",
|
|
1430
1462
|
"help.cmd.clean": "\u626B\u63CF + \u5220\u9664\u6240\u6709\u5B89\u5168\u9879\uFF08\u9ED8\u8BA4\u56DE\u6536\u7AD9\uFF09",
|
|
1431
1463
|
"help.cmd.search": "\u6309\u540D\u79F0\u67E5\u627E\u5DF2\u5B89\u88C5\u7684\u5305\uFF08\u542B\u7248\u672C\u4E0E\u5927\u5C0F\uFF09\u2014 \u53EA\u8BFB",
|
|
@@ -1435,7 +1467,7 @@ var zh = {
|
|
|
1435
1467
|
"help.cmd.treemap": "\u5355\u6587\u4EF6\u4EA4\u4E92\u5F0F HTML treemap \u2192 nmh-treemap.html",
|
|
1436
1468
|
"help.cmd.global": "npm/pnpm/yarn/bun \u7684\u5168\u5C40\u5B89\u88C5 \u2014 \u53EA\u8BFB",
|
|
1437
1469
|
"help.cmd.config": "\u5728 CLI \u4E2D\u7BA1\u7406 .nmhrc\uFF1Ainfo \xB7 set \xB7 add \xB7 remove \xB7 unset",
|
|
1438
|
-
"help.cmd.update": "v1.
|
|
1470
|
+
"help.cmd.update": "v1.4\uFF1A\u5148\u5C55\u793A\u4FE1\u606F\uFF0C\u5B89\u88C5\u524D\u8BE2\u95EE \u2014 --check [tag] / --info \u4EC5\u5BF9\u6BD4\uFF1B--tag \u8BFB\u53D6 dist-tag\uFF08\u964D\u7EA7\u786E\u8BA4\u9ED8\u8BA4\u4E3A\u5426\uFF09\uFF1B-y \u5B89\u88C5\uFF0C-n \u62D2\u7EDD\uFF0C--force \u8DF3\u8FC7\u8BE2\u95EE",
|
|
1439
1471
|
"help.cmd.version": "banner\uFF1A\u5DE5\u5177\u7248\u672C\u3001node+abi\u3001OS/arch/kernel\u3001tty\uFF08\u522B\u540D\uFF1A-v / --version\uFF09",
|
|
1440
1472
|
"help.cmd.help": "\u672C\u5E2E\u52A9\uFF08\u522B\u540D\uFF1A-h / --help\uFF09",
|
|
1441
1473
|
"help.statsSub.byType": "\u6309\u4F9D\u8D56\u5B57\u6BB5\u7EC6\u5206\uFF08dep/dev/optional/peer/transitive\uFF09",
|
|
@@ -1465,6 +1497,8 @@ var zh = {
|
|
|
1465
1497
|
"help.flag.saveReport": "\u540C\u65F6\u628A\u6253\u5370\u7684\u62A5\u544A\u5199\u5165\u6587\u4EF6\uFF08.json/.md/.txt\uFF1B--report <file> \u662F\u522B\u540D\uFF09",
|
|
1466
1498
|
"help.flag.wizard": "v1.2\uFF1A\u663E\u5F0F\u6253\u5F00\u5411\u5BFC \u2014 \u4E0E\u88F8 `nmh` \u76F8\u540C\uFF0C\u4F46\u7BA1\u9053\u4E2D\u4F1A\u62D2\u7EDD\u5E76\u7ED9\u51FA\u6307\u5F15\u800C\u975E\u626B\u63CF",
|
|
1467
1499
|
"help.flag.updateFamily": "v1.2\uFF1A\u53EA\u8BFB\u89C6\u56FE\u4E0E\u7ECF\u540C\u610F\u7684\u5B89\u88C5 \u2014 \u89C1\u4E0A\u65B9 `nmh update` \u4E00\u884C",
|
|
1500
|
+
"help.flag.tag": "\u8BFB\u53D6\u6307\u5B9A\u7684 npm dist-tag \u2014 nmh update --tag beta\uFF1B--check <tag> \u4E0E\u4E4B\u5BF9\u6BD4\uFF08v1.4\uFF09",
|
|
1501
|
+
"help.flag.updateTag": "\u6301\u4E45\u5316\u7684\u66F4\u65B0 dist-tag\uFF08.nmhrc \u4E2D\u7684 updateTag\uFF09\u2014 `nmh update` / `--check` \u9ED8\u8BA4\u8BFB\u53D6\u5B83\uFF08v1.4\uFF09",
|
|
1468
1502
|
"help.flag.updateCheck": "\u67E5\u770B npm \u662F\u5426\u6709\u65B0\u7248\u672C\uFF08\u975E\u963B\u585E\uFF0C24 \u5C0F\u65F6\u7F13\u5B58\uFF1B\u4E5F\u53EF\u5728 .nmhrc \u4E2D\u8BBE\u7F6E\uFF09",
|
|
1469
1503
|
"help.flag.stale": "\u53EA\u4FDD\u7559\u95F2\u7F6E >= <days> \u7684\u9879\u76EE\uFF1B\u4F9D\u636E = git commit \u2192 manifest \u2192 \u6587\u4EF6\u5939 mtime\uFF1B\u65E0\u8BC1\u636E = \u5254\u9664",
|
|
1470
1504
|
"help.flag.fastSize": "\u6BCF\u9879\u7528\u4E00\u6B21 `du -sk` \u5EA6\u91CF\uFF08KiB \u7C92\u5EA6\uFF09\uFF0C\u800C\u975E\u904D\u5386\u6BCF\u4E2A\u6587\u4EF6",
|
|
@@ -1552,6 +1586,9 @@ var zh = {
|
|
|
1552
1586
|
"cli.err.rootRefusal": "\u62D2\u7EDD\u5728\u6587\u4EF6\u7CFB\u7EDF\u6839\u76EE\u5F55\u4E0A\u6267\u884C\u5220\u9664 \u2014 \u628A --dir \u6307\u5411\u8981\u6E05\u7406\u7684\u9879\u76EE\u76EE\u5F55",
|
|
1553
1587
|
"cli.err.checkOnlyUpdate": "--check \u53EA\u9002\u7528\u4E8E update \u547D\u4EE4 \u2014 nmh update --check",
|
|
1554
1588
|
"cli.err.infoOnlyUpdate": "--info \u53EA\u9002\u7528\u4E8E update \u547D\u4EE4 \u2014 nmh update --info",
|
|
1589
|
+
"cli.err.tagNeedsValue": "--tag \u9700\u8981 dist-tag \u540D\u79F0 \u2014 nmh update --tag beta\uFF08\u4E0D\u5E26\u503C\u7684 --check \u8BFB\u53D6 --tag / .nmhrc / latest\uFF09",
|
|
1590
|
+
"cli.err.invalidTag": 'dist-tag "{value}" \u65E0\u6548 \u2014 \u53EA\u80FD\u4F7F\u7528\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u8FDE\u5B57\u7B26\u3001\u4E0B\u5212\u7EBF',
|
|
1591
|
+
"cli.err.tagOnlyUpdate": "--tag \u53EA\u9002\u7528\u4E8E update \u547D\u4EE4 \u2014 nmh update --tag beta",
|
|
1555
1592
|
"cli.err.updateArgs": "update \u4E0D\u63A5\u53D7\u53C2\u6570 \u2014 \u76F4\u63A5 `nmh update`\uFF08\u52A0 --json \u83B7\u53D6\u8F7D\u8377\uFF09",
|
|
1556
1593
|
"cli.err.checkInfoExclusive": "--check \u4E0E --info \u662F\u4E24\u4E2A\u4E0D\u540C\u7684\u53EA\u8BFB\u89C6\u56FE \u2014 \u4E8C\u9009\u4E00\uFF08nmh update --check | --info\uFF09",
|
|
1557
1594
|
"cli.err.routerOrphan": "`--` \u8DEF\u7531\u5C5E\u4E8E\u5411\u5BFC \u2014 nmh wizard -- stats|map|search|why|treemap \u2026",
|
|
@@ -1598,6 +1635,7 @@ var zh = {
|
|
|
1598
1635
|
"config.err.notBoolean": "\u65E0\u6548\u914D\u7F6E\uFF1A{file}\uFF1A{key} \u5FC5\u987B\u662F true \u6216 false\uFF08\u5F97\u5230 {value}\uFF09",
|
|
1599
1636
|
"config.err.invalidLanguage": "\u65E0\u6548\u914D\u7F6E\uFF1A{file}\uFF1Alanguage \u5FC5\u987B\u662F en | id | zh | ru | es \u4E4B\u4E00\uFF08\u5F97\u5230 {value}\uFF09",
|
|
1600
1637
|
"config.err.invalidLogDir": "\u65E0\u6548\u914D\u7F6E\uFF1A{file}\uFF1AlogDir \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32",
|
|
1638
|
+
"config.err.invalidUpdateTag": "\u65E0\u6548\u914D\u7F6E\uFF1A{file}\uFF1AupdateTag \u5FC5\u987B\u662F dist-tag \u540D\u79F0 \u2014 \u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u8FDE\u5B57\u7B26\u3001\u4E0B\u5212\u7EBF\uFF08\u5F97\u5230 {value}\uFF09",
|
|
1601
1639
|
"config.err.unreadable": "\u914D\u7F6E\u4E0D\u53EF\u8BFB\uFF1A{file}\uFF08{code}\uFF09",
|
|
1602
1640
|
"config.err.notFound": "\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A{file}",
|
|
1603
1641
|
"config.warn.unknownKey": '{file}\uFF1A\u672A\u77E5\u7684\u914D\u7F6E\u952E "{key}" \u2014 \u5DF2\u5FFD\u7565',
|
|
@@ -1605,6 +1643,7 @@ var zh = {
|
|
|
1605
1643
|
"config.err.invalidDepthValue": "\u65E0\u6548\u7684 --depth \u503C\uFF1A{value}\uFF08\u5E94\u4E3A\u975E\u8D1F\u6574\u6570\uFF09",
|
|
1606
1644
|
"config.err.invalidModeValue": "\u65E0\u6548\u7684 --default-mode\uFF1A{value}\uFF08\u5E94\u4E3A hard | soft | trash\uFF09",
|
|
1607
1645
|
"config.err.invalidLanguageValue": "\u65E0\u6548\u7684 --language \u503C\uFF1A{value}\uFF08\u5E94\u4E3A en | id | zh | ru | es\uFF09",
|
|
1646
|
+
"config.err.invalidUpdateTagValue": "\u65E0\u6548\u7684 --update-tag \u503C\uFF1A{value}\uFF08\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u8FDE\u5B57\u7B26\u3001\u4E0B\u5212\u7EBF\uFF09",
|
|
1608
1647
|
"config.err.boolNeedsValue": "{label} \u9700\u8981 true \u6216 false \u2014 \u5982 nmh config set --animate=false",
|
|
1609
1648
|
"config.err.setListNeedsValue": "config set --{flag} \u9700\u8981\u5217\u8868\u503C \u2014 \u5982 --{flag}=.npm,.nvm",
|
|
1610
1649
|
"config.err.addListNeedsValue": "config add --{flag} \u9700\u8981\u8981\u8FFD\u52A0\u7684\u9879 \u2014 \u5982 --{flag}=.cache,self",
|
|
@@ -1805,6 +1844,7 @@ var ru = {
|
|
|
1805
1844
|
"wizard.menu.map": "\u{1F5FA}\uFE0F \u041A\u0430\u0440\u0442\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0435\u0439 \u2014 \u043F\u0440\u043E\u0435\u043A\u0442 \u2192 PM \u2192 \u0437\u0430\u044F\u0432\u043B\u0435\u043D\u043D\u044B\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0438",
|
|
1806
1845
|
"wizard.menu.stats": "\u{1F4CA} \u041F\u043E\u0434\u0440\u043E\u0431\u043D\u044B\u0439 \u043E\u0442\u0447\u0451\u0442 \u2014 \u043F\u043E\u043B\u043D\u044B\u0439 \u0432\u044B\u0432\u043E\u0434 stats",
|
|
1807
1846
|
"wizard.menu.settings": "\u2699\uFE0F \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0438 \u0438\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044F (\u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440 \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u0447\u0442\u0435\u043D\u0438\u044F)",
|
|
1847
|
+
"wizard.menu.update": "\u{1F501} \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C nmh (\u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 \u0440\u0435\u0435\u0441\u0442\u0440, \u0441\u043F\u0435\u0440\u0432\u0430 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442)",
|
|
1808
1848
|
"wizard.menu.quit": "\u23F9 \u0412\u044B\u0439\u0442\u0438 \u0438\u0437 nmh",
|
|
1809
1849
|
"wizard.outro.bye": "\u043F\u043E\u043A\u0430 \u{1F44B} \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u043E",
|
|
1810
1850
|
"wizard.search.message": "\u041F\u043E\u0438\u0441\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044B\u0445 \u043F\u0430\u043A\u0435\u0442\u043E\u0432 \u2014 \u043A\u0430\u043A\u043E\u0439 \u0448\u0430\u0431\u043B\u043E\u043D?",
|
|
@@ -1859,6 +1899,11 @@ var ru = {
|
|
|
1859
1899
|
"update.err.failed": "\u26A0 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C: {detail}",
|
|
1860
1900
|
"update.err.manualHint": " \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0432\u0440\u0443\u0447\u043D\u0443\u044E: npm install -g node-modules-hunter@{latest}",
|
|
1861
1901
|
"update.done": "\u2713 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u043E {current} \u2192 {latest} (npm install -g node-modules-hunter)",
|
|
1902
|
+
"update.info.tags": "dist-tags {tags}",
|
|
1903
|
+
"update.check.onTag": "(dist-tag: {tag})",
|
|
1904
|
+
"update.confirm.downgrade": '\u041E\u0442\u043A\u0430\u0442\u0438\u0442\u044C nmh {current} \u2192 {target} \u0438\u0437 dist-tag "{tag}"?',
|
|
1905
|
+
"update.err.tagUnknown": 'dist-tag "{tag}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u2014 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435: {tags}',
|
|
1906
|
+
"update.err.invalidTag": '\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 dist-tag "{value}" \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0431\u0443\u043A\u0432\u044B, \u0446\u0438\u0444\u0440\u044B, \u0442\u043E\u0447\u043A\u0430, \u0434\u0435\u0444\u0438\u0441, \u043F\u043E\u0434\u0447\u0451\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u0435',
|
|
1862
1907
|
// ── commands/global.ts ──────────────────────────────────────────────────
|
|
1863
1908
|
"global.spin.probe": "\u043E\u043F\u0440\u043E\u0441 \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u0445 \u043F\u0440\u0435\u0444\u0438\u043A\u0441\u043E\u0432\u2026",
|
|
1864
1909
|
"global.spin.progress": "\u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u0439 {pm} \u2014 {done}/{total} \u043F\u0430\u043A\u0435\u0442\u043E\u0432",
|
|
@@ -1924,9 +1969,9 @@ var ru = {
|
|
|
1924
1969
|
"help.statsSub.title": "\u041F\u043E\u0434\u043A\u043E\u043C\u0430\u043D\u0434\u044B stats",
|
|
1925
1970
|
"help.options.title": "\u041E\u043F\u0446\u0438\u0438 \u2014 {group}",
|
|
1926
1971
|
"help.examples.title": "\u041F\u0440\u0438\u043C\u0435\u0440\u044B",
|
|
1927
|
-
"help.cmd.bare": "\u0438\u043D\u0442\u0435\u0440\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u043C\u0430\u0441\u0442\u0435\u0440: \u043C\u0435\u043D\u044E \u043D\u0430 \u0441\u0442\u0440\u0435\u043B\u043A\u0430\u0445 (\u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u0441\u0451 / \u0432\u044B\u0431\u0440\u0430\u0442\u044C / \u043F\u043E\u0438\u0441\u043A / \u043A\u0430\u0440\u0442\u0430 / \u043E\u0442\u0447\u0451\u0442 / \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438)",
|
|
1972
|
+
"help.cmd.bare": "\u0438\u043D\u0442\u0435\u0440\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u043C\u0430\u0441\u0442\u0435\u0440: \u043C\u0435\u043D\u044E \u043D\u0430 \u0441\u0442\u0440\u0435\u043B\u043A\u0430\u0445 (\u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u0441\u0451 / \u0432\u044B\u0431\u0440\u0430\u0442\u044C / \u043F\u043E\u0438\u0441\u043A / \u043A\u0430\u0440\u0442\u0430 / \u043E\u0442\u0447\u0451\u0442 / \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 / \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438)",
|
|
1928
1973
|
"help.cmd.paths": "\u0441\u043E\u043A\u0440\u0430\u0449\u0435\u043D\u0438\u0435: \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u044B\u0435 \u043F\u0443\u0442\u0438; \u043E\u0434\u043D\u043E\u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u0444\u043B\u0430\u0433\u0430\u043C\u0438 (--delete, --search, \u2026)",
|
|
1929
|
-
"help.cmd.wizard": "v1.2: \u043C\u0430\u0441\u0442\u0435\u0440 \u043F\u043E \u044F\u0432\u043D\u044B\u043C \u0446\u0435\u043B\u044F\u043C (--dir=./a,./b \u043E\u0442\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u0430\u0432\u0442\u043E-\u043F\u043E\u0434\u044A\u0451\u043C); -- <view> \u0441\u043F\u0435\u0440\u0432\u0430 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u0432\u0438\u0434",
|
|
1974
|
+
"help.cmd.wizard": "v1.2: \u043C\u0430\u0441\u0442\u0435\u0440 \u043F\u043E \u044F\u0432\u043D\u044B\u043C \u0446\u0435\u043B\u044F\u043C (--dir=./a,./b \u043E\u0442\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u0430\u0432\u0442\u043E-\u043F\u043E\u0434\u044A\u0451\u043C); -- <view> \u0441\u043F\u0435\u0440\u0432\u0430 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u0432\u0438\u0434; \u0432 \u043C\u0435\u043D\u044E \u0442\u0435\u043F\u0435\u0440\u044C \u0435\u0441\u0442\u044C \u{1F501} \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C nmh (v1.4)",
|
|
1930
1975
|
"help.cmd.scan": "\u043F\u043E\u043B\u043D\u044B\u0439 \u0441\u043A\u0430\u043D \u043F\u043E \u0446\u0435\u043B\u044F\u043C (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: cwd)",
|
|
1931
1976
|
"help.cmd.clean": "\u0441\u043A\u0430\u043D + \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u0441\u0451 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0435 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443)",
|
|
1932
1977
|
"help.cmd.search": "\u043D\u0430\u0439\u0442\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044B\u0435 \u043F\u0430\u043A\u0435\u0442\u044B \u043F\u043E \u0438\u043C\u0435\u043D\u0438 (+ \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u0440\u0430\u0437\u043C\u0435\u0440\u044B) \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u0435\u043D\u0438\u0435",
|
|
@@ -1936,7 +1981,7 @@ var ru = {
|
|
|
1936
1981
|
"help.cmd.treemap": "\u043E\u0434\u043D\u043E\u0444\u0430\u0439\u043B\u043E\u0432\u044B\u0439 \u0438\u043D\u0442\u0435\u0440\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 HTML-treemap \u2192 nmh-treemap.html",
|
|
1937
1982
|
"help.cmd.global": "\u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 npm/pnpm/yarn/bun \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u0435\u043D\u0438\u0435",
|
|
1938
1983
|
"help.cmd.config": "\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 .nmhrc \u0438\u0437 CLI: info \xB7 set \xB7 add \xB7 remove \xB7 unset",
|
|
1939
|
-
"help.cmd.update": "v1.
|
|
1984
|
+
"help.cmd.update": "v1.4: \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0444\u0430\u043A\u0442\u044B \u0438 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0434 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u043E\u0439 \u2014 --check [tag] / --info \u0442\u043E\u043B\u044C\u043A\u043E \u0441\u0440\u0430\u0432\u043D\u0435\u043D\u0438\u0435; --tag \u0447\u0438\u0442\u0430\u0435\u0442 dist-tag (\u0434\u043B\u044F \u0434\u0430\u0443\u043D\u0433\u0440\u0435\u0439\u0434\u0430 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u041D\u0415\u0422); -y \u0443\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0435\u0442, -n \u043E\u0442\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F, --force \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u0435\u0442 \u0432\u043E\u043F\u0440\u043E\u0441",
|
|
1940
1985
|
"help.cmd.version": "\u0431\u0430\u043D\u043D\u0435\u0440: \u0432\u0435\u0440\u0441\u0438\u044F \u0443\u0442\u0438\u043B\u0438\u0442\u044B, node+abi, \u041E\u0421/\u0430\u0440\u0445/\u044F\u0434\u0440\u043E, tty (\u0430\u043B\u0438\u0430\u0441: -v / --version)",
|
|
1941
1986
|
"help.cmd.help": "\u044D\u0442\u0430 \u0441\u043F\u0440\u0430\u0432\u043A\u0430 (\u0430\u043B\u0438\u0430\u0441: -h / --help)",
|
|
1942
1987
|
"help.statsSub.byType": "\u0440\u0430\u0437\u0431\u0438\u0432\u043A\u0430 \u043F\u043E \u043F\u043E\u043B\u044E \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0438 (dep/dev/optional/peer/transitive)",
|
|
@@ -1966,6 +2011,8 @@ var ru = {
|
|
|
1966
2011
|
"help.flag.saveReport": "\u0442\u0430\u043A\u0436\u0435 \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u043F\u0435\u0447\u0430\u0442\u043D\u044B\u0439 \u043E\u0442\u0447\u0451\u0442 \u0432 \u0444\u0430\u0439\u043B (.json/.md/.txt; --report <file> \u2014 \u0430\u043B\u0438\u0430\u0441)",
|
|
1967
2012
|
"help.flag.wizard": "v1.2: \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u043C\u0430\u0441\u0442\u0435\u0440 \u044F\u0432\u043D\u043E \u2014 \u043A\u0430\u043A \u0433\u043E\u043B\u044B\u0439 `nmh`, \u043D\u043E \u0432 \u043F\u0430\u0439\u043F\u0435 \u043E\u0442\u043A\u0430\u0437 \u0441 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430\u043C\u0438 \u0432\u043C\u0435\u0441\u0442\u043E \u0441\u043A\u0430\u043D\u0430",
|
|
1968
2013
|
"help.flag.updateFamily": "v1.2: \u0432\u0438\u0434\u044B \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u0447\u0442\u0435\u043D\u0438\u044F \u043F\u0440\u043E\u0442\u0438\u0432 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 \u0441 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u044F \u2014 \u0441\u043C. \u0441\u0442\u0440\u043E\u043A\u0443 `nmh update` \u0432\u044B\u0448\u0435",
|
|
2014
|
+
"help.flag.tag": "\u0447\u0438\u0442\u0430\u0442\u044C \u043A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u044B\u0439 dist-tag npm \u2014 nmh update --tag beta; --check <tag> \u0441\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u0435\u0442 \u0441 \u043D\u0438\u043C (v1.4)",
|
|
2015
|
+
"help.flag.updateTag": "\u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0439 dist-tag \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F (updateTag \u0432 .nmhrc) \u2014 \u0447\u0442\u043E `nmh update` / `--check` \u0447\u0438\u0442\u0430\u044E\u0442 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E (v1.4)",
|
|
1969
2016
|
"help.flag.updateCheck": "\u043F\u043E\u0434\u0433\u043B\u044F\u0434\u0435\u0442\u044C \u0432 npm \u043D\u043E\u0432\u044B\u0439 \u0440\u0435\u043B\u0438\u0437 (\u043D\u0435\u0431\u043B\u043E\u043A\u0438\u0440\u0443\u044E\u0449\u0435, \u043A\u044D\u0448 24 \u0447; \u043C\u043E\u0436\u043D\u043E \u0438 \u0432 .nmhrc)",
|
|
1970
2017
|
"help.flag.stale": "\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043B\u0438\u0448\u044C \u043F\u0440\u043E\u0435\u043A\u0442\u044B \u0441 \u043F\u0440\u043E\u0441\u0442\u043E\u0435\u043C >= <\u0434\u043D\u0435\u0439>; \u043B\u0435\u0441\u0442\u043D\u0438\u0446\u0430 = git commit \u2192 \u043C\u0430\u043D\u0438\u0444\u0435\u0441\u0442 \u2192 mtime \u043F\u0430\u043F\u043A\u0438; \u0431\u0435\u0437 \u0443\u043B\u0438\u043A = \u043E\u0442\u0431\u0440\u043E\u0448\u0435\u043D",
|
|
1971
2018
|
"help.flag.fastSize": "\u0438\u0437\u043C\u0435\u0440\u044F\u0442\u044C \u043E\u0434\u043D\u0438\u043C `du -sk` \u043D\u0430 \u0437\u0430\u043F\u0438\u0441\u044C (\u0433\u0440\u0430\u043D\u0443\u043B\u044F\u0446\u0438\u044F KiB) \u0432\u043C\u0435\u0441\u0442\u043E \u043E\u0431\u0445\u043E\u0434\u0430 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0444\u0430\u0439\u043B\u0430",
|
|
@@ -2053,6 +2100,9 @@ var ru = {
|
|
|
2053
2100
|
"cli.err.rootRefusal": "\u043E\u0442\u043A\u0430\u0437 \u043E\u0442 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u043F\u043E\u0432\u0435\u0440\u0445 \u043A\u043E\u0440\u043D\u044F \u0444\u0430\u0439\u043B\u043E\u0432\u043E\u0439 \u0441\u0438\u0441\u0442\u0435\u043C\u044B \u2014 \u043D\u0430\u043F\u0440\u0430\u0432\u044C\u0442\u0435 --dir \u043D\u0430 \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u043F\u0440\u043E\u0435\u043A\u0442\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0445\u043E\u0442\u0438\u0442\u0435 \u043F\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",
|
|
2054
2101
|
"cli.err.checkOnlyUpdate": "--check \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043B\u0438\u0448\u044C \u0441 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u0439 update \u2014 nmh update --check",
|
|
2055
2102
|
"cli.err.infoOnlyUpdate": "--info \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043B\u0438\u0448\u044C \u0441 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u0439 update \u2014 nmh update --info",
|
|
2103
|
+
"cli.err.tagNeedsValue": "--tag \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u043C\u044F dist-tag \u2014 nmh update --tag beta (--check \u0431\u0435\u0437 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0447\u0438\u0442\u0430\u0435\u0442 --tag / .nmhrc / latest)",
|
|
2104
|
+
"cli.err.invalidTag": '\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 dist-tag "{value}" \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0431\u0443\u043A\u0432\u044B, \u0446\u0438\u0444\u0440\u044B, \u0442\u043E\u0447\u043A\u0430, \u0434\u0435\u0444\u0438\u0441, \u043F\u043E\u0434\u0447\u0451\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u0435',
|
|
2105
|
+
"cli.err.tagOnlyUpdate": "--tag \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043B\u0438\u0448\u044C \u0441 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u0439 update \u2014 nmh update --tag beta",
|
|
2056
2106
|
"cli.err.updateArgs": "update \u043D\u0435 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u2014 \u043F\u0440\u043E\u0441\u0442\u043E `nmh update` (\u0434\u043E\u0431\u0430\u0432\u044C\u0442\u0435 --json \u0434\u043B\u044F \u043C\u0430\u0448\u0438\u043D\u043E\u0447\u0438\u0442\u0430\u0435\u043C\u043E\u0433\u043E \u0432\u044B\u0432\u043E\u0434\u0430)",
|
|
2057
2107
|
"cli.err.checkInfoExclusive": "--check \u0438 --info \u2014 \u0434\u0432\u0430 \u0440\u0430\u0437\u043D\u044B\u0445 \u0432\u0438\u0434\u0430 \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u0447\u0442\u0435\u043D\u0438\u044F \u2014 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0434\u0438\u043D (nmh update --check | --info)",
|
|
2058
2108
|
"cli.err.routerOrphan": "\u0440\u043E\u0443\u0442\u0435\u0440 `--` \u043F\u0440\u0438\u043D\u0430\u0434\u043B\u0435\u0436\u0438\u0442 \u043C\u0430\u0441\u0442\u0435\u0440\u0443 \u2014 nmh wizard -- stats|map|search|why|treemap \u2026",
|
|
@@ -2099,6 +2149,7 @@ var ru = {
|
|
|
2099
2149
|
"config.err.notBoolean": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043E\u043D\u0444\u0438\u0433: {file}: {key} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C true \u0438\u043B\u0438 false (\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043E {value})",
|
|
2100
2150
|
"config.err.invalidLanguage": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043E\u043D\u0444\u0438\u0433: {file}: language \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0434\u043D\u0438\u043C \u0438\u0437 en | id | zh | ru | es (\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043E {value})",
|
|
2101
2151
|
"config.err.invalidLogDir": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043E\u043D\u0444\u0438\u0433: {file}: logDir \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435\u043F\u0443\u0441\u0442\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u043E\u0439",
|
|
2152
|
+
"config.err.invalidUpdateTag": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043E\u043D\u0444\u0438\u0433: {file}: updateTag \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0438\u043C\u0435\u043D\u0435\u043C dist-tag \u2014 \u0431\u0443\u043A\u0432\u044B, \u0446\u0438\u0444\u0440\u044B, \u0442\u043E\u0447\u043A\u0430, \u0434\u0435\u0444\u0438\u0441, \u043F\u043E\u0434\u0447\u0451\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u0435 (\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043E {value})",
|
|
2102
2153
|
"config.err.unreadable": "\u043A\u043E\u043D\u0444\u0438\u0433 \u043D\u0435\u0447\u0438\u0442\u0430\u0435\u043C: {file} ({code})",
|
|
2103
2154
|
"config.err.notFound": "\u0444\u0430\u0439\u043B \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D: {file}",
|
|
2104
2155
|
"config.warn.unknownKey": '{file}: \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u043A\u043B\u044E\u0447 \u043A\u043E\u043D\u0444\u0438\u0433\u0430 "{key}" \u2014 \u0438\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044F',
|
|
@@ -2106,6 +2157,7 @@ var ru = {
|
|
|
2106
2157
|
"config.err.invalidDepthValue": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 --depth: {value} (\u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C \u043D\u0435\u043E\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0446\u0435\u043B\u043E\u0435)",
|
|
2107
2158
|
"config.err.invalidModeValue": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 --default-mode: {value} (\u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C hard | soft | trash)",
|
|
2108
2159
|
"config.err.invalidLanguageValue": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 --language: {value} (\u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C en | id | zh | ru | es)",
|
|
2160
|
+
"config.err.invalidUpdateTagValue": "\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 --update-tag: {value} (\u0431\u0443\u043A\u0432\u044B, \u0446\u0438\u0444\u0440\u044B, \u0442\u043E\u0447\u043A\u0430, \u0434\u0435\u0444\u0438\u0441, \u043F\u043E\u0434\u0447\u0451\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u0435)",
|
|
2109
2161
|
"config.err.boolNeedsValue": "{label} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 true \u0438\u043B\u0438 false \u2014 \u043D\u0430\u043F\u0440. nmh config set --animate=false",
|
|
2110
2162
|
"config.err.setListNeedsValue": "config set --{flag} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0441\u043F\u0438\u0441\u043A\u0430 \u2014 \u043D\u0430\u043F\u0440. --{flag}=.npm,.nvm",
|
|
2111
2163
|
"config.err.addListNeedsValue": "config add --{flag} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u2014 \u043D\u0430\u043F\u0440. --{flag}=.cache,self",
|
|
@@ -2306,6 +2358,7 @@ var es = {
|
|
|
2306
2358
|
"wizard.menu.map": "\u{1F5FA}\uFE0F Mapear dependencias \u2014 proyecto \u2192 PM \u2192 deps declaradas",
|
|
2307
2359
|
"wizard.menu.stats": "\u{1F4CA} Informe detallado \u2014 la lectura completa de stats",
|
|
2308
2360
|
"wizard.menu.settings": "\u2699\uFE0F Ajustes e integraci\xF3n (vista de solo lectura)",
|
|
2361
|
+
"wizard.menu.update": "\u{1F501} Actualizar nmh (consulta el registro, pregunta primero)",
|
|
2309
2362
|
"wizard.menu.quit": "\u23F9 Salir de nmh",
|
|
2310
2363
|
"wizard.outro.bye": "adi\xF3s \u{1F44B} \u2014 no se elimin\xF3 nada",
|
|
2311
2364
|
"wizard.search.message": "Buscar paquetes instalados \u2014 \xBFqu\xE9 patr\xF3n?",
|
|
@@ -2360,6 +2413,11 @@ var es = {
|
|
|
2360
2413
|
"update.err.failed": "\u26A0 fall\xF3 la actualizaci\xF3n: {detail}",
|
|
2361
2414
|
"update.err.manualHint": " prueba manual: npm install -g node-modules-hunter@{latest}",
|
|
2362
2415
|
"update.done": "\u2713 actualizado {current} \u2192 {latest} (npm install -g node-modules-hunter)",
|
|
2416
|
+
"update.info.tags": "dist-tags {tags}",
|
|
2417
|
+
"update.check.onTag": "(dist-tag: {tag})",
|
|
2418
|
+
"update.confirm.downgrade": '\xBFBajar nmh {current} \u2192 {target} desde el dist-tag "{tag}"?',
|
|
2419
|
+
"update.err.tagUnknown": 'dist-tag "{tag}" no encontrado \u2014 disponibles: {tags}',
|
|
2420
|
+
"update.err.invalidTag": 'dist-tag "{value}" inv\xE1lido \u2014 usa letras, d\xEDgitos, punto, guion, guion bajo',
|
|
2363
2421
|
// ── commands/global.ts ──────────────────────────────────────────────────
|
|
2364
2422
|
"global.spin.probe": "sondeando prefijos globales\u2026",
|
|
2365
2423
|
"global.spin.progress": "global {pm} \u2014 {done}/{total} paquetes",
|
|
@@ -2425,9 +2483,9 @@ var es = {
|
|
|
2425
2483
|
"help.statsSub.title": "Subcomandos de stats",
|
|
2426
2484
|
"help.options.title": "Opciones \u2014 {group}",
|
|
2427
2485
|
"help.examples.title": "Ejemplos",
|
|
2428
|
-
"help.cmd.bare": "asistente interactivo: men\xFA con flechas (eliminar todo / elegir / search / map / informe / ajustes)",
|
|
2486
|
+
"help.cmd.bare": "asistente interactivo: men\xFA con flechas (eliminar todo / elegir / search / map / informe / actualizar / ajustes)",
|
|
2429
2487
|
"help.cmd.paths": "atajo: escanea las rutas dadas; acciones de una l\xEDnea v\xEDa flags (--delete, --search, \u2026)",
|
|
2430
|
-
"help.cmd.wizard": "v1.2: asistente sobre objetivos expl\xEDcitos (--dir=./a,./b salta el auto-climb); -- <vista> abre primero la vista",
|
|
2488
|
+
"help.cmd.wizard": "v1.2: asistente sobre objetivos expl\xEDcitos (--dir=./a,./b salta el auto-climb); -- <vista> abre primero la vista; el men\xFA ahora incluye \u{1F501} Actualizar nmh (v1.4)",
|
|
2431
2489
|
"help.cmd.scan": "escaneo completo de todos los objetivos (por defecto: cwd)",
|
|
2432
2490
|
"help.cmd.clean": "escanea + elimina todo lo seguro (trash por defecto)",
|
|
2433
2491
|
"help.cmd.search": "busca paquetes instalados por nombre (+ versi\xF3n y tama\xF1o) \u2014 solo lectura",
|
|
@@ -2437,7 +2495,7 @@ var es = {
|
|
|
2437
2495
|
"help.cmd.treemap": "treemap HTML interactivo de un solo archivo \u2192 nmh-treemap.html",
|
|
2438
2496
|
"help.cmd.global": "instalaciones globales de npm/pnpm/yarn/bun \u2014 solo lectura",
|
|
2439
2497
|
"help.cmd.config": "gestiona .nmhrc desde el CLI: info \xB7 set \xB7 add \xB7 remove \xB7 unset",
|
|
2440
|
-
"help.cmd.update": "v1.
|
|
2498
|
+
"help.cmd.update": "v1.4: muestra datos y pregunta antes de instalar \u2014 --check [tag] / --info solo comparan; --tag lee un dist-tag (el downgrade confirma con NO por defecto); -y instala, -n rechaza, --force salta la pregunta",
|
|
2441
2499
|
"help.cmd.version": "banner: versi\xF3n de la herramienta, node+abi, SO/arquitectura/kernel, tty (alias: -v / --version)",
|
|
2442
2500
|
"help.cmd.help": "esta ayuda (alias: -h / --help)",
|
|
2443
2501
|
"help.statsSub.byType": "desglose por campo de dependencia (dep/dev/optional/peer/transitive)",
|
|
@@ -2467,6 +2525,8 @@ var es = {
|
|
|
2467
2525
|
"help.flag.saveReport": "escribe tambi\xE9n el informe impreso a un archivo (.json/.md/.txt; --report <archivo> es alias)",
|
|
2468
2526
|
"help.flag.wizard": "v1.2: abre el asistente expl\xEDcitamente \u2014 igual que `nmh` simple, pero una pipe rechaza con direcci\xF3n en vez de escanear",
|
|
2469
2527
|
"help.flag.updateFamily": "v1.2: vistas de solo lectura vs instalaci\xF3n aprobada \u2014 ver la l\xEDnea de `nmh update` arriba",
|
|
2528
|
+
"help.flag.tag": "lee un dist-tag npm espec\xEDfico \u2014 nmh update --tag beta; --check <tag> compara contra \xE9l (v1.4)",
|
|
2529
|
+
"help.flag.updateTag": "dist-tag de actualizaci\xF3n persistido (updateTag en .nmhrc) \u2014 lo que `nmh update` / `--check` leen por defecto (v1.4)",
|
|
2470
2530
|
"help.flag.updateCheck": "consulta npm por versiones m\xE1s nuevas (sin bloqueo, cach\xE9 de 24 h; tambi\xE9n en .nmhrc)",
|
|
2471
2531
|
"help.flag.stale": "solo proyectos inactivos >= <d\xEDas>; escalera = git commit \u2192 manifiesto \u2192 mtime de carpeta; sin prueba = descartado",
|
|
2472
2532
|
"help.flag.fastSize": "mide con un `du -sk` por entrada (granularidad KiB) en vez de recorrer cada archivo",
|
|
@@ -2554,6 +2614,9 @@ var es = {
|
|
|
2554
2614
|
"cli.err.rootRefusal": "se rechaza la operaci\xF3n de delete sobre la ra\xEDz del sistema de archivos \u2014 apunta --dir al directorio del proyecto que quieres limpiar",
|
|
2555
2615
|
"cli.err.checkOnlyUpdate": "--check es solo para el comando update \u2014 nmh update --check",
|
|
2556
2616
|
"cli.err.infoOnlyUpdate": "--info es solo para el comando update \u2014 nmh update --info",
|
|
2617
|
+
"cli.err.tagNeedsValue": "--tag necesita un nombre de dist-tag \u2014 nmh update --tag beta (--check sin valor lee --tag / .nmhrc / latest)",
|
|
2618
|
+
"cli.err.invalidTag": 'dist-tag "{value}" inv\xE1lido \u2014 usa letras, d\xEDgitos, punto, guion, guion bajo',
|
|
2619
|
+
"cli.err.tagOnlyUpdate": "--tag es solo para el comando update \u2014 nmh update --tag beta",
|
|
2557
2620
|
"cli.err.updateArgs": "update no acepta argumentos \u2014 `nmh update` simple (a\xF1ade --json para el payload)",
|
|
2558
2621
|
"cli.err.checkInfoExclusive": "--check y --info son dos vistas de solo lectura distintas \u2014 elige una (nmh update --check | --info)",
|
|
2559
2622
|
"cli.err.routerOrphan": "el `--` del router es del asistente \u2014 nmh wizard -- stats|map|search|why|treemap \u2026",
|
|
@@ -2600,6 +2663,7 @@ var es = {
|
|
|
2600
2663
|
"config.err.notBoolean": "config inv\xE1lido: {file}: {key} debe ser true o false (recibido {value})",
|
|
2601
2664
|
"config.err.invalidLanguage": "config inv\xE1lido: {file}: language debe ser uno de en | id | zh | ru | es (recibido {value})",
|
|
2602
2665
|
"config.err.invalidLogDir": "config inv\xE1lido: {file}: logDir debe ser una cadena no vac\xEDa",
|
|
2666
|
+
"config.err.invalidUpdateTag": "config inv\xE1lido: {file}: updateTag debe ser un nombre de dist-tag \u2014 letras, d\xEDgitos, punto, guion, guion bajo (recibido {value})",
|
|
2603
2667
|
"config.err.unreadable": "config ilegible: {file} ({code})",
|
|
2604
2668
|
"config.err.notFound": "archivo de config no encontrado: {file}",
|
|
2605
2669
|
"config.warn.unknownKey": "{file}: clave de config desconocida \xAB{key}\xBB \u2014 ignorada",
|
|
@@ -2607,6 +2671,7 @@ var es = {
|
|
|
2607
2671
|
"config.err.invalidDepthValue": "valor de --depth inv\xE1lido: {value} (debe ser un entero no negativo)",
|
|
2608
2672
|
"config.err.invalidModeValue": "valor de --default-mode inv\xE1lido: {value} (debe ser hard | soft | trash)",
|
|
2609
2673
|
"config.err.invalidLanguageValue": "valor de --language inv\xE1lido: {value} (debe ser en | id | zh | ru | es)",
|
|
2674
|
+
"config.err.invalidUpdateTagValue": "valor de --update-tag inv\xE1lido: {value} (letras, d\xEDgitos, punto, guion, guion bajo)",
|
|
2610
2675
|
"config.err.boolNeedsValue": "{label} necesita true o false \u2014 p. ej. nmh config set --animate=false",
|
|
2611
2676
|
"config.err.setListNeedsValue": "config set --{flag} necesita el valor de la lista \u2014 p. ej. --{flag}=.npm,.nvm",
|
|
2612
2677
|
"config.err.addListNeedsValue": "config add --{flag} necesita un elemento que a\xF1adir \u2014 p. ej. --{flag}=.cache,self",
|
|
@@ -2825,8 +2890,9 @@ var GROUPS = () => [
|
|
|
2825
2890
|
{ usage: "--size <mode>", desc: t("help.flag.size") },
|
|
2826
2891
|
{ usage: "--save-report <file>", desc: t("help.flag.saveReport") },
|
|
2827
2892
|
{ usage: "--wizard", desc: t("help.flag.wizard") },
|
|
2828
|
-
{ usage: "update: --check \xB7 --info \xB7 -y \xB7 -n \xB7 -f", desc: t("help.flag.updateFamily") },
|
|
2829
|
-
{ usage: "--update-check", desc: t("help.flag.updateCheck") }
|
|
2893
|
+
{ usage: "update: --check [tag] \xB7 --tag <name> \xB7 --info \xB7 -y \xB7 -n \xB7 -f", desc: t("help.flag.updateFamily") },
|
|
2894
|
+
{ usage: "--update-check", desc: t("help.flag.updateCheck") },
|
|
2895
|
+
{ usage: "--tag <name>", desc: t("help.flag.tag") }
|
|
2830
2896
|
]
|
|
2831
2897
|
},
|
|
2832
2898
|
{
|
|
@@ -2842,7 +2908,8 @@ var GROUPS = () => [
|
|
|
2842
2908
|
{ usage: "--verbose", desc: t("help.flag.verbose") },
|
|
2843
2909
|
{ usage: "--no-color", desc: t("help.flag.noColor") },
|
|
2844
2910
|
{ usage: "--color", desc: t("help.flag.color") },
|
|
2845
|
-
{ usage: "--language <lang>", desc: t("help.flag.language") }
|
|
2911
|
+
{ usage: "--language <lang>", desc: t("help.flag.language") },
|
|
2912
|
+
{ usage: "--update-tag <name>", desc: t("help.flag.updateTag") }
|
|
2846
2913
|
]
|
|
2847
2914
|
},
|
|
2848
2915
|
{
|
|
@@ -2972,6 +3039,9 @@ var ConfigError = class extends Error {
|
|
|
2972
3039
|
};
|
|
2973
3040
|
var FILE_NAMES = [".nmhrc", ".nmhrc.json"];
|
|
2974
3041
|
var VALID_MODES = /* @__PURE__ */ new Set(["hard", "soft", "trash"]);
|
|
3042
|
+
function isValidDistTag(tag) {
|
|
3043
|
+
return tag.length > 0 && tag.length <= 64 && /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/i.test(tag);
|
|
3044
|
+
}
|
|
2975
3045
|
function parseConfigBody(body, file) {
|
|
2976
3046
|
let raw2;
|
|
2977
3047
|
try {
|
|
@@ -3024,6 +3094,12 @@ function parseConfigBody(body, file) {
|
|
|
3024
3094
|
}
|
|
3025
3095
|
values.logDir = expandTilde(value);
|
|
3026
3096
|
break;
|
|
3097
|
+
case "updateTag":
|
|
3098
|
+
if (typeof value !== "string" || !isValidDistTag(value)) {
|
|
3099
|
+
throw new ConfigError(t("config.err.invalidUpdateTag", { file, value: JSON.stringify(value) }));
|
|
3100
|
+
}
|
|
3101
|
+
values.updateTag = value;
|
|
3102
|
+
break;
|
|
3027
3103
|
default:
|
|
3028
3104
|
warn(t("config.warn.unknownKey", { file, key }));
|
|
3029
3105
|
}
|
|
@@ -5113,7 +5189,7 @@ function registryUrl() {
|
|
|
5113
5189
|
}
|
|
5114
5190
|
function isNewer(current2, latest) {
|
|
5115
5191
|
const triple = (v) => {
|
|
5116
|
-
const match = /^(\d+)\.(\d+)\.(\d+)(
|
|
5192
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:-?([^+]*))?(?:\+.*)?$/.exec(v.trim());
|
|
5117
5193
|
return match === null ? null : [Number(match[1]), Number(match[2]), Number(match[3]), match[4] ?? ""];
|
|
5118
5194
|
};
|
|
5119
5195
|
const now = triple(current2);
|
|
@@ -5123,7 +5199,26 @@ function isNewer(current2, latest) {
|
|
|
5123
5199
|
if (next[i] > now[i]) return true;
|
|
5124
5200
|
if (next[i] < now[i]) return false;
|
|
5125
5201
|
}
|
|
5126
|
-
|
|
5202
|
+
const curPre = now[3] === "" ? [] : now[3].split(".");
|
|
5203
|
+
const nextPre = next[3] === "" ? [] : next[3].split(".");
|
|
5204
|
+
if (curPre.length === 0 && nextPre.length === 0) return false;
|
|
5205
|
+
if (curPre.length === 0) return false;
|
|
5206
|
+
if (nextPre.length === 0) return true;
|
|
5207
|
+
for (let i = 0; i < Math.min(curPre.length, nextPre.length); i += 1) {
|
|
5208
|
+
const a = curPre[i];
|
|
5209
|
+
const b = nextPre[i];
|
|
5210
|
+
const numA = /^\d+$/.test(a);
|
|
5211
|
+
const numB = /^\d+$/.test(b);
|
|
5212
|
+
if (numA && numB) {
|
|
5213
|
+
const diff = Number(b) - Number(a);
|
|
5214
|
+
if (diff !== 0) return diff > 0;
|
|
5215
|
+
} else if (numA !== numB) {
|
|
5216
|
+
return !numB;
|
|
5217
|
+
} else if (a !== b) {
|
|
5218
|
+
return b > a;
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
return nextPre.length > curPre.length;
|
|
5127
5222
|
}
|
|
5128
5223
|
function updateNote(latest, current2) {
|
|
5129
5224
|
return t("update.note", { current: current2, latest });
|
|
@@ -5298,6 +5393,32 @@ async function isNpmGlobal() {
|
|
|
5298
5393
|
const ls = await runNpm(["ls", "-g", "node-modules-hunter", "--depth=0"], 6e4);
|
|
5299
5394
|
return ls.code === 0 && ls.stdout.includes("node-modules-hunter");
|
|
5300
5395
|
}
|
|
5396
|
+
async function distTagsMap(allowSpawn) {
|
|
5397
|
+
const collect = (raw2) => {
|
|
5398
|
+
if (raw2 === null || typeof raw2 !== "object" || Array.isArray(raw2)) return null;
|
|
5399
|
+
const out = {};
|
|
5400
|
+
for (const [name, version] of Object.entries(raw2)) {
|
|
5401
|
+
if (typeof version === "string" && VERSION_SHAPE.test(version)) out[name] = version;
|
|
5402
|
+
}
|
|
5403
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
5404
|
+
};
|
|
5405
|
+
const seam = process.env.NMH_UPDATE_DIST_TAGS_JSON;
|
|
5406
|
+
if (typeof seam === "string" && seam.length > 0) {
|
|
5407
|
+
try {
|
|
5408
|
+
return collect(JSON.parse(await fs13.readFile(seam, "utf8")));
|
|
5409
|
+
} catch {
|
|
5410
|
+
return null;
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
if (!allowSpawn) return null;
|
|
5414
|
+
const view = await runNpm(["view", "node-modules-hunter", "dist-tags", "--json"], 6e4);
|
|
5415
|
+
if (view.code !== 0) return null;
|
|
5416
|
+
try {
|
|
5417
|
+
return collect(JSON.parse(view.stdout));
|
|
5418
|
+
} catch {
|
|
5419
|
+
return null;
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5301
5422
|
async function installLatest(version) {
|
|
5302
5423
|
const installCommand = `npm install -g node-modules-hunter@${version}`;
|
|
5303
5424
|
const fake = process.env.NMH_UPDATE_FAKE_INSTALL;
|
|
@@ -5318,7 +5439,7 @@ async function installLatest(version) {
|
|
|
5318
5439
|
}
|
|
5319
5440
|
return { ok: true, detail: installCommand };
|
|
5320
5441
|
}
|
|
5321
|
-
function renderInfo(current2, manifest, updateAvailable, global) {
|
|
5442
|
+
function renderInfo(current2, manifest, updateAvailable, global, distTags) {
|
|
5322
5443
|
const d = manifest.detail;
|
|
5323
5444
|
const rows = [
|
|
5324
5445
|
t("update.info.installed", { value: current2 }),
|
|
@@ -5327,6 +5448,10 @@ function renderInfo(current2, manifest, updateAvailable, global) {
|
|
|
5327
5448
|
value: updateAvailable ? t("update.info.available") + (global ? "" : t("update.info.availableNonGlobal")) : t("update.info.none")
|
|
5328
5449
|
})
|
|
5329
5450
|
];
|
|
5451
|
+
if (distTags !== null) {
|
|
5452
|
+
const tags = Object.entries(distTags).map(([name, version]) => `${name}=${version}`).join(", ");
|
|
5453
|
+
rows.push(t("update.info.tags", { tags }));
|
|
5454
|
+
}
|
|
5330
5455
|
if (d.description !== void 0) rows.push(t("update.info.summary", { value: d.description }));
|
|
5331
5456
|
if (d.tarball !== void 0) {
|
|
5332
5457
|
const size = d.unpackedSize === void 0 ? "" : t("update.info.sizeSuffix", { size: d.unpackedSize, files: d.fileCount === void 0 ? "" : `, ${d.fileCount}` });
|
|
@@ -5339,6 +5464,12 @@ function renderInfo(current2, manifest, updateAvailable, global) {
|
|
|
5339
5464
|
}
|
|
5340
5465
|
async function runUpdate(request) {
|
|
5341
5466
|
const current2 = toolVersion();
|
|
5467
|
+
const tag = request.tag ?? "latest";
|
|
5468
|
+
if (!isValidDistTag(tag)) {
|
|
5469
|
+
const message = t("update.err.invalidTag", { value: tag });
|
|
5470
|
+
errorLog(request.json ? message : `\u26A0 ${message}`);
|
|
5471
|
+
return 1;
|
|
5472
|
+
}
|
|
5342
5473
|
const manifest = await latestManifest();
|
|
5343
5474
|
if (manifest === null) {
|
|
5344
5475
|
const message = t("update.err.noRegistry");
|
|
@@ -5346,25 +5477,46 @@ async function runUpdate(request) {
|
|
|
5346
5477
|
else errorLog(`\u26A0 ${message}`);
|
|
5347
5478
|
return 1;
|
|
5348
5479
|
}
|
|
5480
|
+
const hermetic = typeof process.env.NMH_UPDATE_LATEST_JSON === "string" && process.env.NMH_UPDATE_LATEST_JSON.length > 0;
|
|
5481
|
+
const distTags = await distTagsMap(!hermetic);
|
|
5482
|
+
let target;
|
|
5483
|
+
if (tag === "latest") {
|
|
5484
|
+
target = distTags?.latest ?? manifest.version;
|
|
5485
|
+
} else if (distTags !== null && typeof distTags[tag] === "string") {
|
|
5486
|
+
target = distTags[tag];
|
|
5487
|
+
} else if (distTags === null) {
|
|
5488
|
+
const message = t("update.err.noRegistry");
|
|
5489
|
+
if (request.json) errorLog(message);
|
|
5490
|
+
else errorLog(`\u26A0 ${message}`);
|
|
5491
|
+
return 1;
|
|
5492
|
+
} else {
|
|
5493
|
+
const tags = Object.keys(distTags).join(", ");
|
|
5494
|
+
const message = t("update.err.tagUnknown", { tag, tags });
|
|
5495
|
+
if (request.json) errorLog(message);
|
|
5496
|
+
else errorLog(`\u26A0 ${message}`);
|
|
5497
|
+
return 1;
|
|
5498
|
+
}
|
|
5349
5499
|
const latest = manifest.version;
|
|
5350
5500
|
const global = await isNpmGlobal();
|
|
5351
5501
|
const method = global ? "npm-global" : "manual";
|
|
5352
|
-
const
|
|
5353
|
-
const
|
|
5502
|
+
const direction = isNewer(current2, target) ? "upgrade" : isNewer(target, current2) ? "downgrade" : "current";
|
|
5503
|
+
const updateAvailable = direction === "upgrade";
|
|
5504
|
+
const result = (updated) => ({ current: current2, latest, updated, method, updateAvailable, tag, target, direction });
|
|
5354
5505
|
if (request.mode === "info") {
|
|
5355
|
-
if (request.json) payload(JSON.stringify({ ...result(false), detail: manifest.detail }, null, 2));
|
|
5356
|
-
else log([t("update.info.title"), ...renderInfo(current2, manifest, updateAvailable, global)].join("\n"));
|
|
5506
|
+
if (request.json) payload(JSON.stringify({ ...result(false), distTags: distTags ?? void 0, detail: manifest.detail }, null, 2));
|
|
5507
|
+
else log([t("update.info.title"), ...renderInfo(current2, manifest, updateAvailable, global, distTags)].join("\n"));
|
|
5357
5508
|
return 0;
|
|
5358
5509
|
}
|
|
5359
5510
|
if (request.mode === "check") {
|
|
5511
|
+
const onTag = tag === "latest" ? "" : ` ${t("update.check.onTag", { tag })}`;
|
|
5360
5512
|
if (request.json) payload(JSON.stringify(result(false), null, 2));
|
|
5361
|
-
else if (updateAvailable) log(t("update.check.available", { current: current2, latest }));
|
|
5362
|
-
else log(t("update.check.latest", { current: current2, latest }));
|
|
5513
|
+
else if (updateAvailable) log(t("update.check.available", { current: current2, latest: target }) + onTag);
|
|
5514
|
+
else log(t("update.check.latest", { current: current2, latest: target }) + onTag);
|
|
5363
5515
|
return 0;
|
|
5364
5516
|
}
|
|
5365
|
-
if (
|
|
5517
|
+
if (direction === "current") {
|
|
5366
5518
|
if (request.json) payload(JSON.stringify(result(false), null, 2));
|
|
5367
|
-
else log(t("update.latestNoInstall", { current: current2, latest }));
|
|
5519
|
+
else log(t("update.latestNoInstall", { current: current2, latest: target }));
|
|
5368
5520
|
return 0;
|
|
5369
5521
|
}
|
|
5370
5522
|
if (!global) {
|
|
@@ -5383,24 +5535,24 @@ async function runUpdate(request) {
|
|
|
5383
5535
|
return 1;
|
|
5384
5536
|
}
|
|
5385
5537
|
const admitted = await confirm({
|
|
5386
|
-
message: t("update.confirm", { current: current2, latest }),
|
|
5387
|
-
initialValue:
|
|
5538
|
+
message: direction === "downgrade" ? t("update.confirm.downgrade", { current: current2, target, tag }) : t("update.confirm", { current: current2, latest: target }),
|
|
5539
|
+
initialValue: direction !== "downgrade"
|
|
5388
5540
|
});
|
|
5389
5541
|
install = admitted === true;
|
|
5390
5542
|
}
|
|
5391
5543
|
if (!install) {
|
|
5392
5544
|
if (request.json) payload(JSON.stringify(result(false), null, 2));
|
|
5393
|
-
else log(t("update.declined", { current: current2, latest }));
|
|
5545
|
+
else log(t("update.declined", { current: current2, latest: target }));
|
|
5394
5546
|
return 0;
|
|
5395
5547
|
}
|
|
5396
|
-
const installation = await installLatest(
|
|
5548
|
+
const installation = await installLatest(target);
|
|
5397
5549
|
if (!installation.ok) {
|
|
5398
5550
|
errorLog(t("update.err.failed", { detail: installation.detail }));
|
|
5399
|
-
errorLog(t("update.err.manualHint", { latest }));
|
|
5551
|
+
errorLog(t("update.err.manualHint", { latest: target }));
|
|
5400
5552
|
return 1;
|
|
5401
5553
|
}
|
|
5402
5554
|
if (request.json) payload(JSON.stringify(result(true), null, 2));
|
|
5403
|
-
else log(t("update.done", { current: current2, latest }));
|
|
5555
|
+
else log(t("update.done", { current: current2, latest: target }));
|
|
5404
5556
|
return 0;
|
|
5405
5557
|
}
|
|
5406
5558
|
|
|
@@ -5409,7 +5561,7 @@ import fs14 from "fs/promises";
|
|
|
5409
5561
|
import path14 from "path";
|
|
5410
5562
|
import { homedir as homedir7 } from "os";
|
|
5411
5563
|
var VALID_MODES2 = /* @__PURE__ */ new Set(["hard", "soft", "trash"]);
|
|
5412
|
-
var KNOWN_KEYS = ["defaultMode", "depth", "exclude", "keep", "color", "animate", "updateCheck", "logDir", "language"];
|
|
5564
|
+
var KNOWN_KEYS = ["defaultMode", "depth", "exclude", "keep", "color", "animate", "updateCheck", "logDir", "language", "updateTag"];
|
|
5413
5565
|
var KEY_TO_FLAG = {
|
|
5414
5566
|
defaultMode: "default-mode",
|
|
5415
5567
|
depth: "depth",
|
|
@@ -5419,7 +5571,8 @@ var KEY_TO_FLAG = {
|
|
|
5419
5571
|
animate: "animate",
|
|
5420
5572
|
updateCheck: "update-check",
|
|
5421
5573
|
logDir: "log-dir",
|
|
5422
|
-
language: "language"
|
|
5574
|
+
language: "language",
|
|
5575
|
+
updateTag: "update-tag"
|
|
5423
5576
|
};
|
|
5424
5577
|
var LIST_KEYS = {
|
|
5425
5578
|
"default-exclude": "exclude",
|
|
@@ -5483,6 +5636,13 @@ function parseLanguage(raw2) {
|
|
|
5483
5636
|
}
|
|
5484
5637
|
return value.trim().toLowerCase();
|
|
5485
5638
|
}
|
|
5639
|
+
function parseUpdateTag(raw2) {
|
|
5640
|
+
const value = scalar(raw2).value;
|
|
5641
|
+
if (typeof value !== "string" || !isValidDistTag(value.trim())) {
|
|
5642
|
+
throw new ConfigError(t("config.err.invalidUpdateTagValue", { value: JSON.stringify(value ?? null) }));
|
|
5643
|
+
}
|
|
5644
|
+
return value.trim();
|
|
5645
|
+
}
|
|
5486
5646
|
function parseBool(raw2, label) {
|
|
5487
5647
|
const given = flagBool(raw2);
|
|
5488
5648
|
if (given.value === null) {
|
|
@@ -5522,6 +5682,7 @@ function assemble(request) {
|
|
|
5522
5682
|
if (scalar(request.depth).given) mutation.scalars.depth = parseDepth(request.depth);
|
|
5523
5683
|
if (scalar(request.defaultMode).given) mutation.scalars.defaultMode = parseMode(request.defaultMode);
|
|
5524
5684
|
if (scalar(request.language).given) mutation.scalars.language = parseLanguage(request.language);
|
|
5685
|
+
if (scalar(request.updateTag).given) mutation.scalars.updateTag = parseUpdateTag(request.updateTag);
|
|
5525
5686
|
if (scalar(request.logDir).given) {
|
|
5526
5687
|
const value = scalar(request.logDir).value;
|
|
5527
5688
|
if (typeof value !== "string" || value.length === 0) throw new ConfigError(t("config.err.logDirNeedsValue"));
|
|
@@ -5552,7 +5713,7 @@ function assemble(request) {
|
|
|
5552
5713
|
}
|
|
5553
5714
|
if (defaultExclude.given) mutation.unsetKeys.push("exclude");
|
|
5554
5715
|
if (defaultKeep.given) mutation.unsetKeys.push("keep");
|
|
5555
|
-
for (const key of ["defaultMode", "logDir", "depth", "animate", "color", "updateCheck", "language"]) {
|
|
5716
|
+
for (const key of ["defaultMode", "logDir", "depth", "animate", "color", "updateCheck", "language", "updateTag"]) {
|
|
5556
5717
|
if (request[key] !== void 0) mutation.unsetKeys.push(key);
|
|
5557
5718
|
}
|
|
5558
5719
|
if (mutation.unsetKeys.length === 0) {
|
|
@@ -5623,7 +5784,8 @@ var INFO_DEFAULTS = {
|
|
|
5623
5784
|
animate: "(auto: TTY only)",
|
|
5624
5785
|
updateCheck: "off",
|
|
5625
5786
|
logDir: "~/.nmh",
|
|
5626
|
-
language: "en"
|
|
5787
|
+
language: "en",
|
|
5788
|
+
updateTag: "latest"
|
|
5627
5789
|
};
|
|
5628
5790
|
function renderInfo2(source, values) {
|
|
5629
5791
|
const row = (key, value) => ` ${colors.dim(key.padEnd(12, " "))}${value}`;
|
|
@@ -7779,6 +7941,12 @@ async function runFallbackScan(cwd, options) {
|
|
|
7779
7941
|
async function runInteractiveWizard(cwd, options) {
|
|
7780
7942
|
const explicit = options.targets !== void 0 && options.targets.length > 0;
|
|
7781
7943
|
if (options.banner !== false) log(renderFullBanner());
|
|
7944
|
+
if (options.settings === void 0 || options.settings.values.updateCheck === void 0) {
|
|
7945
|
+
void checkForUpdate().then((notice) => {
|
|
7946
|
+
if (notice !== null) note(notice);
|
|
7947
|
+
}).catch(() => {
|
|
7948
|
+
});
|
|
7949
|
+
}
|
|
7782
7950
|
const scope = explicit ? { root: cwd, from: cwd, climbed: false, scouted: false } : await resolveWizardScope(cwd);
|
|
7783
7951
|
if (scope.climbed) {
|
|
7784
7952
|
log(colors.dim(t("wizard.info.scopedUp", { root: scope.root })));
|
|
@@ -7805,6 +7973,7 @@ async function runInteractiveWizard(cwd, options) {
|
|
|
7805
7973
|
{ value: "search", label: t("wizard.menu.search") },
|
|
7806
7974
|
{ value: "map", label: t("wizard.menu.map") },
|
|
7807
7975
|
{ value: "stats", label: t("wizard.menu.stats") },
|
|
7976
|
+
{ value: "update", label: t("wizard.menu.update") },
|
|
7808
7977
|
{ value: "settings", label: t("wizard.menu.settings") },
|
|
7809
7978
|
{ value: "quit", label: t("wizard.menu.quit") }
|
|
7810
7979
|
]
|
|
@@ -7837,6 +8006,10 @@ async function runInteractiveWizard(cwd, options) {
|
|
|
7837
8006
|
case "stats":
|
|
7838
8007
|
await runStats({ targets: wizardTargets(options), cwd: scope.root, maxDepth: WIZARD_DEPTH });
|
|
7839
8008
|
break;
|
|
8009
|
+
case "update": {
|
|
8010
|
+
await runUpdate({ json: false, mode: "default", answer: "none", force: false });
|
|
8011
|
+
break;
|
|
8012
|
+
}
|
|
7840
8013
|
case "settings":
|
|
7841
8014
|
log(renderSettings(options.settings, scope));
|
|
7842
8015
|
break;
|
|
@@ -8180,13 +8353,15 @@ cli.option("--reinstall", "stats only: naive npm-ci-style estimate of the time t
|
|
|
8180
8353
|
cli.option("--treemap [file]", "treemap export: single-file HTML (vanilla JS, no deps); default nmh-treemap.html in cwd");
|
|
8181
8354
|
cli.option("--out <file>", "treemap only: where to write the HTML file (same as --treemap <file>)");
|
|
8182
8355
|
cli.option("--update-check", "opt-in: peek npm for a newer release (non-blocking, 24 h cache; also settable in .nmhrc)");
|
|
8183
|
-
cli.option("--check", "update only: compare installed vs registry and exit \u2014 never installs");
|
|
8356
|
+
cli.option("--check [tag]", "update only: compare installed vs registry dist-tag and exit \u2014 never installs (bare = latest/rc)");
|
|
8357
|
+
cli.option("--tag <name>", "update only: read this npm dist-tag instead of latest (also --check <tag>)");
|
|
8184
8358
|
cli.option("--info", "update only: full registry detail (npm view style) \u2014 never installs");
|
|
8185
8359
|
cli.option("-n, --no", "update only: decline the update on the command line (nothing installs)");
|
|
8186
8360
|
cli.option("--wizard", "open the interactive wizard explicitly (same as the bare `nmh`); needs a TTY");
|
|
8187
8361
|
cli.option("--default-exclude <globs>", 'config family: manage the persisted exclude list (comma list; special value "self")');
|
|
8188
8362
|
cli.option("--default-keep <pkgs>", 'config family: manage the persisted keep list (comma list; special value "self")');
|
|
8189
8363
|
cli.option("--default-mode <mode>", "config family: set the persisted defaultMode (hard | soft | trash)");
|
|
8364
|
+
cli.option("--update-tag <name>", "config family: set the persisted update dist-tag (updateTag)");
|
|
8190
8365
|
cli.option("--log-dir <dir>", "config family: set the persisted recovery-log directory (logDir)");
|
|
8191
8366
|
cli.option("--language <lang>", "UI language: en | id | zh | ru | es (also in .nmhrc / NMH_LANG; v1.3)");
|
|
8192
8367
|
var PM_FAMILIES = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun", "vp"]);
|
|
@@ -8516,20 +8691,39 @@ async function runCli(userArgs) {
|
|
|
8516
8691
|
errorLog(t("cli.err.infoOnlyUpdate"));
|
|
8517
8692
|
return 1;
|
|
8518
8693
|
}
|
|
8694
|
+
if (flags.tag !== void 0 && subcommand !== "update") {
|
|
8695
|
+
errorLog(t("cli.err.tagOnlyUpdate"));
|
|
8696
|
+
return 1;
|
|
8697
|
+
}
|
|
8519
8698
|
if (subcommand === "update") {
|
|
8520
8699
|
if (deleted.given || rest.length > 0) {
|
|
8521
8700
|
errorLog(t("cli.err.updateArgs"));
|
|
8522
8701
|
return 1;
|
|
8523
8702
|
}
|
|
8524
|
-
if (flags.check
|
|
8703
|
+
if (flags.check !== void 0 && flags.check !== false && flags.info === true) {
|
|
8525
8704
|
errorLog(t("cli.err.checkInfoExclusive"));
|
|
8526
8705
|
return 1;
|
|
8527
8706
|
}
|
|
8707
|
+
if (flags.tag === true) {
|
|
8708
|
+
errorLog(t("cli.err.tagNeedsValue"));
|
|
8709
|
+
return 1;
|
|
8710
|
+
}
|
|
8711
|
+
const flagTag = typeof flags.tag === "string" ? flags.tag.trim() : void 0;
|
|
8712
|
+
const checkTag = typeof flags.check === "string" ? flags.check.trim() : void 0;
|
|
8713
|
+
for (const candidate of [flagTag, checkTag]) {
|
|
8714
|
+
if (candidate !== void 0 && !isValidDistTag(candidate)) {
|
|
8715
|
+
errorLog(t("cli.err.invalidTag", { value: candidate }));
|
|
8716
|
+
return 1;
|
|
8717
|
+
}
|
|
8718
|
+
}
|
|
8719
|
+
const checkGiven = flags.check !== void 0 && flags.check !== false;
|
|
8720
|
+
const tag = flagTag ?? checkTag ?? config.updateTag ?? "latest";
|
|
8528
8721
|
return runUpdate({
|
|
8529
8722
|
json,
|
|
8530
|
-
mode:
|
|
8723
|
+
mode: checkGiven ? "check" : flags.info === true ? "info" : "default",
|
|
8531
8724
|
answer: flags.yes === true ? "yes" : flags.no === true ? "no" : "none",
|
|
8532
|
-
force: flags.force === true
|
|
8725
|
+
force: flags.force === true,
|
|
8726
|
+
tag
|
|
8533
8727
|
});
|
|
8534
8728
|
}
|
|
8535
8729
|
const wizardIntent = subcommand === "wizard" || flags.wizard === true;
|
|
@@ -8604,7 +8798,8 @@ async function runCli(userArgs) {
|
|
|
8604
8798
|
animate: animateGiven ? flags.animate : void 0,
|
|
8605
8799
|
color: colorGiven ? flags.color : void 0,
|
|
8606
8800
|
updateCheck: flags.updateCheck,
|
|
8607
|
-
language: flags.language
|
|
8801
|
+
language: flags.language,
|
|
8802
|
+
updateTag: flags.updateTag
|
|
8608
8803
|
});
|
|
8609
8804
|
}
|
|
8610
8805
|
const searchPattern = typeof flags.search === "string" && flags.search.length > 0 ? flags.search : subcommand === "search" ? rest[0] ?? null : null;
|
package/package.json
CHANGED