npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@emeryld/manager

v1.4.15

Published

Interactive manager for pnpm monorepos (update/test/build/publish).

Downloads

7,411

Readme

@emeryld/manager

Dev dependency built for Codex agents: scan a pnpm workspace, scaffold RRRoutes packages, and ship releases without rebuilding boilerplate. Install it in a workspace and call pnpm manager-cli from the root to drive everything interactively or via arguments for headless automation.

Quick start

  • Install: pnpm add -D @emeryld/manager
  • Add a script: "manager-cli": "manager-cli" in the workspace package.json
  • Launch interactive manager: pnpm manager-cli (package picker → action picker)
  • List templates fast: pnpm manager-cli templates (alias pnpm manager-cli create --list)
  • Headless scaffold (Codex/CI-ready): pnpm manager-cli create --variant rrr-server --dir packages/api --name @scope/api --contract @scope/contract --skip-install
  • Headless publish: pnpm manager-cli all --non-interactive --bump patch --tag next

Running manager-cli interactively

  • Package selection: scans for every package.json (ignores node_modules/dist). Menu entries include each package (color-coded), "All packages", and "Create package". Navigate with ↑/↓/j/k or digits to run instantly.
  • Action menu for the selection:
    • update dependencies → runs pnpm -r update (or filtered update), stages only dependency files, prompts for a commit message, commits, and pushes.
    • testpnpm test (filtered to the package when possible).
    • format checker → prompts for limits, then scans each source file for long functions and class methods, deep indentation, too many components/functions, and repeated/similar snippets before reporting offenders.
    • buildpnpm build (filtered when a single package is selected).
    • publish → ensures the working tree is committed, checks registry auth, prompts a version strategy, commits the bump, tags, publishes with pnpm, and pushes tags.
    • full → update → test → build → publish in order.
  • back → return to package selection. When a single package is chosen, its package.json scripts also appear as runnable entries.

Format checker configuration

manager-cli ships with a format checker action that respects defaults in .vscode/settings.json under the manager.formatChecker key. Define:

| setting | description | | --- | --- | | maxFunctionLength | allowed lines per function (default 150) | | maxMethodLength | allowed lines per class method (default 150) | | maxIndentationDepth | indentation spaces before warning | | maxFunctionsPerFile | functions allowed in a file | | maxComponentsPerFile | component abstractions allowed | | maxFileLength | total lines per file | | maxDuplicateLineOccurrences | times a similar line can repeat | | minDuplicateLines | minimum consecutive lines required for repetition warnings | | exportOnly | limit function/component checks to exported symbols | | indentationWidth | spaces to count per tab when evaluating indentation depth |

Each run also prompts for overrides, so you can tweak targets without editing the file. Long methods inside classes now obey the maxMethodLength limit, so class members are scanned even when they aren't individually exported. The override prompt now lists every limit at once; you can move with ↑/↓, type to replace the highlighted value, Backspace to erase characters, and press Enter when the values validate before confirming. You can also decide where the report lands: the manager will ask whether to stream the violations to the console or dump them into a temporary file that is opened in your editor (no repo files are modified).

{
  "manager.formatChecker": {
    "maxFunctionLength": 150,
    "maxMethodLength": 200
  }
}

Format checker scan CLI

  • Usage: pnpm manager-cli scan [flags] scans the workspace without interactive prompts while honoring defaults in .vscode/settings.json under manager.formatChecker.
  • Flags: override any limit via the table below or run pnpm manager-cli scan --help/-h to print the same guidance.

| Flag | Description | | --- | --- | | --max-function-length <number> | Maximum lines per function before a violation is reported. | | --max-method-length <number> | Maximum lines per class/instance method before a violation is reported. | | --max-indentation-depth <number> | Maximum indentation depth (spaces) that the scanner tolerates. | | --max-functions-per-file <number> | Maximum number of functions allowed in a source file. | | --max-components-per-file <number> | Maximum component abstractions permitted per file. | | --max-file-length <number> | Maximum total lines in a file before the file-length rule triggers. | | --max-duplicate-line-occurrences <number> | Maximum times a similar line may repeat before it counts as duplication. | | --min-duplicate-lines <number> | Minimum consecutive duplicate lines needed to trigger the duplicate check (set to 0 to skip the requirement). | | --indentation-width <number> | Number of spaces counted per tab when measuring indentation depth. | | --export-only <true|false> | When true, component/function counts only consider exported symbols. | | --reporting-mode <group|file> | Choose group (summary by violation type) or file (per-file entries). | | --export-mode <console|editor> | Choose console to print violations in the terminal or editor to write them to a temporary file and open it in your default editor. Defaults to console. |

  • Purpose: give Codex agents, CI pipelines, and automation deterministic scans that print the same violation summaries as the interactive action.
  • Output: prints Format checker violations: followed by grouped or per-file buckets (with severity, snippets, and location references); when no violations occur you get Format checker found no violations. and Workspace meets the configured format limits. Colors mirror the interactive report to keep results easy to scan.

ESLint (in-editor)

If you want these checks surfaced as squiggles in your editor, you can run them as an ESLint rule.

  1. Install ESLint in your workspace: pnpm add -D eslint
  2. Add eslint.config.js:
import managerFormatChecker from '@emeryld/manager/dist/eslint-plugin-format-checker/index.js'

export default [
  {
    files: ['**/*.{ts,tsx,js,jsx,mjs,cjs}'],
    plugins: { manager: managerFormatChecker },
    rules: {
      'manager/format-checker': 'warn',
    },
  },
]

The rule defaults to the same limits as manager-cli and will also pick up manager.formatChecker from .vscode/settings.json (override any setting via rule options if you prefer).

Robot metadata

The robot metadata action now starts with the same interactive settings screen as the format checker: pick which kinds of symbols to include, decide whether to limit the scan to exported declarations, and adjust the column width. Use ↑/↓ to move between rows, type new values (comma-separated lists for the kinds), and press Enter once the validation message disappears.

The column width now controls how much context is emitted for each declaration. Symbols that start past the configured column keep their name/export status but drop heavyweight fields (IO signatures, docstrings, JSX locations, etc.), so you still see everything in the workspace but only the left-most definitions contribute rich metadata to your LLM prompt.

Before the extraction runs you can also choose how to consume the results. The default console stream prints the JSON into your terminal, while editor writes the report to a temporary file (non-saved) and tries to open it in your editor via your configured $EDITOR, code, or the OS open/xdg-open helpers.

To keep the payload more token-friendly, the interactive settings screen now exposes Condense output for compact JSON and Docstring length limit. Enabling the condensed output replaces the verbose object format with a small fields + rows array layout, and the docstring limit trims comments to the first N characters (set the value to 0 for unlimited). Set your preferred defaults in .vscode/settings.json under manager.robot.condenseOutput and manager.robot.maxDocStringLength.

Running with arguments

Run pnpm manager-cli, pick the workspace (or “All packages”), then select the robot metadata action. The helper walks you through:

  1. Set the symbol kinds to capture (comma-separated list or all).
  2. Toggle Only exported symbols, adjust Maximum columns, Condense output for compact JSON, and Docstring length limit.
  3. Confirm the summary to trigger the run and choose whether to stream results to the console or editor.

The same knobs live in .vscode/settings.json under manager.robot, for example:

{
  "manager.robot": {
    "includeKinds": ["function", "type", "const"],
    "exportedOnly": true,
    "maxColumns": 120,
    "condenseOutput": true,
    "maxDocStringLength": 80
  }
}

Robot pack settings reference

The same manager.robot block that backs the metadata helper is merged with the defaults listed in src/robot/pack/types.ts before every robot pack build. The helper always uses the directory you select at runtime as the rootDir, so you only need to override the other keys. Here is what each option controls:

| Setting | Description | Default | | --- | --- | --- | | tsconfigPath | Optional path (relative to the selected root) pointing to a tsconfig.json. When omitted the builder climbs parent directories until it finds one. | Auto-detect the nearest tsconfig.json. | | includeGlobs | Glob patterns that determine which .ts/.tsx files are scanned. | ["src/**/*.{ts,tsx}"] | | excludeGlobs | Globs that are skipped (tests, build output, declaration files, etc.) so they never contribute symbols. | ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/dist/**", "**/build/**", "**/*.d.ts"] | | entrypoints | Modules that seed the exported-symbol walk when exportMode is entrypoints. If none of the globs match, the first included file is used as a fallback so the pack is never empty. | ["src/index.ts", "src/**/index.ts"] | | exportMode | Choose between entrypoints (only mirror the modules matched above) and all-files (treat every included file as an entrypoint). Use entrypoints to scope the pack to a few roots; all-files is the default so nothing is accidentally omitted. | all-files | | visibility | exported-only (default) keeps only exported symbols, exported+reexported also follows re-exports from other modules, and all additionally captures the local declarations that live in the same file. | exported-only | | includeKinds | Which symbol kinds to keep—choose any combination of function, class, interface, type-alias, enum, and const to filter the pack down to your preferred abstractions. | ["function", "class", "interface", "type-alias", "enum", "const"] | | closure | surface-only keeps just the exported declarations, while surface+deps (default) also includes their dependency closure. The latter also enables trimming dependency types when a tokenBudget is in play. | surface+deps | | maxExemplars | Maximum number of exemplar functions/classes that are appended to the pack. The builder also caps each module to about half this number so the samples cover more files. | 8 | | tokenBudget | Optional cap on estimated tokens (pack text length ÷ 4). When the estimate exceeds the budget the helper drops exemplars first, then—if closure is surface+deps—it drops dependency type declarations until the estimate fits. Leave blank for unlimited. | Unlimited | | preferTypeSurface | Accepted for compatibility and shown in the interactive prompt, but the current builder ignores this flag. | true | | exemplarHeuristics | Weights that tune the new utility-per-token scoring (usage, boundary, flow, clarity, redundancy) plus the token penalty scale. | {"usage":6,"boundary":1.2,"flow":1.3,"clarity":0.8,"redundancy":0.6,"tau":280} | | keepJSDocTags | List of JSDoc tags that survive the minification step when exemplar bodies are emitted. Tags lacking an @ automatically get one added. | ["@deprecated", "@throws", "@pure", "@sideEffects", "@internal", "@public", "@experimental", "@llm"] |

exemplarHeuristics now drives a utility-per-token score that favors usage-focused, boundary-aware, and flow-respecting chunks while penalizing redundancy and excessive size.

  • usage (default 6) strongly weights snippets that show real call-site arguments, defaults, or error handling.
  • boundary (default 1.2) favors chunks that touch configuration, CLI wiring, filesystem/serialization, or output paths.
  • flow (default 1.3) boosts exemplars on entrypoint-to-output paths, including the traced flow exemplar when available.
  • clarity (default 0.8) rewards clear naming, preserved doc tags, and explicit error strings.
  • redundancy (default 0.6) subtracts from candidates that closely overlap already-selected snippets.
  • tau (default 280) sets the denominator for the size penalty, anchoring chunk length around ~200–300 tokens.

Every exemplar is paired with metadata (purpose, when_relevant, symbols_shown) plus a declared purpose bucket (orchestration/pipeline, configuration/normalization, parsing/validation, selection/filtering, core domain algorithm, or I/O boundary) so downstream LLM consumers can immediately understand why the snippet matters, when to consult it, and which angle it covers.

Example output

robot metadata prints a summary followed by the parsed payload. With the default formatting you get readable JSON:

Robot extraction complete (functions=4 components=1 types=2 consts=0 classes=1)
Estimated tokens: 72
Detailed results:
{
  "functions": [
    {
      "kind": "function",
      "name": "buildManagerConfig",
      "location": { "file": "src/menu.ts", "line": 45, "column": 3 },
      "docString": "Builds the menu configuration for the helper CLI.",
      "exported": true,
      "inputs": ["packages: LoadedPackage[]"],
      "output": "HelperScriptEntry[]"
    }
  ],
  ...
}

Enabling Condense output for compact JSON yields a compact payload that reduces tokens even when the detailed rows are long:

Robot extraction complete (functions=4 components=1 types=2 consts=0 classes=1)
Estimated tokens: 48
Detailed results (condensed):
{
  "version": 1,
  "summary": { "functions": 4, "components": 1, "types": 2, "consts": 0, "classes": 1 },
  "fields": ["kind","file","line","column","name","signature","docString","exported"],
  "rows": [
    ["function","src/menu.ts",45,3,"buildManagerConfig","(packages: LoadedPackage[]) => HelperScriptEntry[]","Builds the menu configuration...",true],
    ["component","src/ui/banner.ts",12,7,"Banner","(props: BannerProps) => JSX.Element","Lightweight banner used in the hero layout.",true]
  ]
}

Non-interactive release (Codex/CI)

  • Syntax: pnpm manager-cli <pkg|all> --non-interactive [publish flags]
  • Requirements: provide the selection (<pkg> or all) and one of --bump <type>, --sync <version>, or --noop (skip the version change but still tag/publish). Use --non-interactive, --ci, --yes, or -y interchangeably to answer every prompt in the affirmative.
  • Behavior: commits any existing changes (prompting for a message), checks registry auth (pnpm whoami), runs pnpm publish (filtered when possible), tags, and pushes after a successful release.
  • Flags:

| Flag | Description | | --- | --- | | --non-interactive, --ci, --yes, -y | Auto-respond “yes” to every prompt. | | --bump <patch|minor|major|prepatch|preminor|premajor|prerelease> | Bump versions (pre* keeps or previews prerelease tags). | | --sync <version> | Set all selected packages to the exact semver you pass. | | --noop | Skip the version bump but still tag/publish the current versions. | | --tag <dist-tag> | Publish with a custom npm dist-tag (defaults to prerelease suffix inference). | | --dry-run | Forward --dry-run to pnpm publish. | | --provenance | Enable npm provenance metadata when publishing. |

--bump, --sync, or --noop are mandatory in non-interactive mode. Optional flags like --tag, --dry-run, and --provenance layer additional behavior on top of the release pipeline.

Create package CLI

  • Interactive: pnpm manager-cli create prompts for template, path, package name, contract (for server/client), and client kind (when applicable). The menu accepts ↑/↓/j/k navigation, digits, and arrow keys when raw mode is available.
  • Headless usage: pnpm manager-cli templates is a shorthand for create --list. Any other flag combination described below will skip prompts and scaffold directly.

| Flag | Description | | --- | --- | | --list, -l | List every available template (rrr-contract, rrr-server, etc.) with their default directories and summaries. | | --describe <variant>, -d | Print the scripts, key files, and notes for a specific template before scaffolding. | | --variant <id>, -v | Choose a template by ID, partial label, or friendly name without hitting the prompts. | | --dir, --path, -p <path> | Target directory for the new package (defaults to the variant’s default). | | --name, -n <pkg> | Package name inside package.json; defaults to the basename of --dir. | | --contract <pkg> | Contract import to wire into server/client templates. | | --client-kind <vite-react|expo-react-native> | Pick the client stack for client-friendly templates. | | --reset | Delete the existing target directory before scaffolding (refuses to reset the workspace root). | | --skip-install | Do not run pnpm install after scaffolding. | | --skip-build | Skip the post-scaffold build step (only meaningful when not skipping install). | | --help, -h | Show the help text above. |

After scaffolding, helper tooling (tsconfig, workspace helpers, etc.) is ensured, the template is written, and a build/install attempt runs unless skipped. Each generated package ships with its own README explaining variant-specific scripts.

Templates at a glance

| id | default dir | summary | key files | | --- | --- | --- | --- | | rrr-contract | packages/rrr-contract | Shared RRRoutes contract + sockets for clients/servers | src/index.ts, README.md | | rrr-server | packages/rrr-server | Express + RRRoutes API wired to a contract import | src/index.ts, .env.example, README.md | | rrr-client | packages/rrr-client | React Query-ready RRRoutes client bound to a contract import | src/index.ts, README.md | | rrr-empty | packages/rrr-empty | Minimal TypeScript package with lint/format/test wiring | src/index.ts, README.md | | rrr-docker | packages/rrr-docker | Express service with Dockerfile + helper CLI | src/index.ts, scripts/docker.ts, Dockerfile, README.md | | rrr-fullstack | rrrfull-stack | pnpm workspace with contract, server, client, and docker helper | root package.json, pnpm-workspace.yaml, packages/* |

Use pnpm manager-cli create --describe <variant> to print the scripts, key files, and notes for any template before scaffolding.

Agent-ready command crib

  • Scaffold server without prompts:
    pnpm manager-cli create --variant rrr-server --dir packages/api --name @scope/api --contract @scope/contract --skip-install
  • Scaffold Expo client:
    pnpm manager-cli create --variant rrr-client --dir packages/mobile --name @scope/mobile --contract @scope/contract --client-kind expo-react-native
  • Publish a single package headlessly:
    pnpm manager-cli @scope/api --non-interactive --bump minor --tag next
  • Publish everything with a synced version:
    pnpm manager-cli all --non-interactive --sync 1.2.3 --provenance
  • Run the format checker scan headlessly:
    pnpm manager-cli scan --max-function-length 90 --reporting-mode file

Notes

  • Helper scripts register the bundled ts-node/esm loader so the CLI works even when dependencies are hoisted.
  • Install/build after scaffolding can be skipped when you need full control (--skip-install / --skip-build).

Tests

  • pnpm test verifies the helper CLI loader registration.