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

@datalackey/tooling-core

v1.3.0

Published

Shared logic and CLI framework for the JavaScript tooling ecosystem in this repository.

Downloads

602

Readme

@datalackey/tooling-core

Shared logic and CLI framework for the JavaScript tooling ecosystem in this repository.

This package is the foundation on which all CLI plugins in this workspace are built — update-markdown-toc, nx-graph-to-mermaid, and update-markdown-uml all depend on it. It can also be used independently to build your own Node.js CLI tools that follow the same conventions.


Overview

tooling-core provides:

  • CLI framework — argument parsing, help generation, plugin descriptor wiring, and exit code management via runCli and PluginDescriptor
  • File processing — recursive directory traversal, single-file and recursive modes, deterministic ordering via walkFiles and listFilesToProcess
  • Markdown utilities — marker-based content injection (injectBetweenMarkers), heading extraction, link extraction, fragment and relative link validation
  • Repository runner — orchestrates file processing with policy-driven error handling and output formatting via RepositoryRunner
  • Shared types — see below

Shared Types

  • RunConfig — base configuration passed to every file processor; carries mode, verbosity, debug, exclude list, and run mode (update vs check)
  • ProcessingStatus — return value from a FileProcessor; one of "updated", "unchanged", "needs update", or "skipped"
  • FileProcessor — interface a plugin implements; single process(filePath, config) method
  • PluginDescriptor — declarative plugin metadata; name, description, options, optional parseOptions, validate, and afterRun hooks
  • PluginOption — describes a single custom CLI flag declared by a plugin
  • ParsedCliResult — result returned by parseStandardCli; carries parsed config, positionals, passthrough flags (those custom to your tool), and help/version booleans
  • RunMode"update" or "check"
  • RunnerPolicy — interface controlling per-file processing decisions and error handling strategy in RepositoryRunner
  • RunnerDecision"abort" or "continue"; returned by RunnerPolicy.handleProcessorError
  • RepositoryStats — counts of updated, unchanged, needs update, and skipped files returned by RepositoryRunner.run

Installation

npm install @datalackey/tooling-core

Node.js ≥ 18 required. ESM only.


Usage

The primary entry point for plugin authors is runCli. A minimal plugin looks like this:

import { runCli } from "@datalackey/tooling-core";
import type {
  PluginDescriptor,
  FileProcessor,
  RunConfig,
  ProcessingStatus,
} from "@datalackey/tooling-core";

// 1. Extend RunConfig to carry your plugin-specific options.
interface MyPluginConfig extends RunConfig {
  skipJs: boolean;          // skip processing of Javascript files
}

// 2. Declare your plugin's metadata and custom CLI flags.
const descriptor: PluginDescriptor<MyPluginConfig> = {
  name: "my-plugin",
  description: "do something with all non-Javascript files ",
  options: [
    {
      flag: "--skip-js",
      description: "Skip processing and log Skipped: <file> instead",
    },
    {
      flag: "-s",
      description: "Short form of --skip-js",
    },
  ],
  parseOptions(standard, passthrough): MyPluginConfig {
    const skipJs =
      passthrough.get("--skip-js") === true ||
      passthrough.get("-s") === true;
    return {
      ...standard,
      skipJs: skipJs,
    };
  },
};

// 3. Implement your file processor.
const processor: FileProcessor<MyPluginConfig> = {
  process(filePath: string, config: MyPluginConfig): ProcessingStatus {
    if (config.skipJs) {
      return "skipped";
    }
    // ... transform filePath content here ...
    return "updated";
  },
};

// 4. Wire everything together.
await runCli({ descriptor: descriptor, processor: processor });

This gives your plugin standard --check, --recursive, --verbose, --quiet, --debug, and --help flags with no additional configuration, plus your own --skip-js / -s flag wired through automatically.

For a complete real-world example see update-markdown-toc.


Package Structure

flowchart TB
  subgraph cli["cli"]
  end
  subgraph markdown["markdown"]
  end
  subgraph policy["policy"]
  end
  subgraph repository["repository"]
  end
  subgraph util["util"]
  end

  cli --> markdown
  cli --> policy
  cli --> repository
  cli --> util
  markdown --> util
  policy --> cli
  policy --> markdown
  policy --> repository
  policy --> util
  repository --> cli
  repository --> markdown
  repository --> policy
  repository --> util

| Package | Description | |---------|-------------| | cli | TBD | | markdown | TBD | | policy | TBD | | repository | TBD | | util | TBD |

cli

classDiagram
  direction TB
  class ResolvedTargets {
    <<type>>
  }
  class RunCliOptions {
    <<interface>>
    +descriptor PluginDescriptor<TConfig>
    +processor FileProcessor<TConfig>
    +argv? string[]
  }
  class PluginOption {
    <<interface>>
    +flag string
    +description string
    +requiresValue? boolean
    +valueName? string
  }
  class PluginDescriptor {
    <<interface>>
    +name string
    +description string
    +options PluginOption[]
    +parseOptions(this, standard, passthrough) TConfig
    +validate(this, config) void
    +afterRun(this, files, config) Promise<void>
  }
  class ParsedCliResult {
    <<interface>>
    +config TConfig
    +positionals string[]
    +passthrough string[]
    +help boolean
    +version boolean
  }
  class RunMode {
    <<type>>
  }

markdown

classDiagram
  direction TB
  class MarkerLocation {
    <<interface>>
    +startMarker string
    +endMarker string
    +startLine number
    +endLine number
    +startIndex number
    +endIndex number
  }
  class LinkRecord {
    <<interface>>
    +href string
    +line number
    +kind LinkKind
  }
  class HeadingRecord {
    <<interface>>
    +line number
    +rawText string
    +slug string
  }
  class FileLineRef {
    <<interface>>
    +file string
    +line number
  }
  class LinkValidationError {
    <<interface>>
    +link string
    +reason string
  }
  class LinkValidationWarning {
    <<interface>>
    +link string
    +reason string
  }
  class LinkValidationResult {
    <<interface>>
    +errors LinkValidationError[]
    +warnings LinkValidationWarning[]
    +validatedCount number
    +skippedCount number
  }
  class LinkValidationOptions {
    <<interface>>
    +validateExternal? boolean
    +timeoutMs? number
    +concurrency? number
    +managedBlockStartMarker? string
    +managedBlockEndMarker? string
    +verbose? boolean
    +onVerbose? (message: string) => void
    +onDebug? (message: string) => void
  }
  class LinkKind {
    <<type>>
  }
  class ExternalLinkStatus {
    <<type>>
  }

  LinkValidationError ..|> FileLineRef
  LinkValidationWarning ..|> FileLineRef

policy

classDiagram
  direction TB
  class RunnerPolicy {
    <<interface>>
    +shouldPrint(status) boolean
    +shouldPrintSummary() boolean
    +handleProcessorError(file, error) RunnerDecision
  }
  class RunnerDecision {
    <<type>>
  }

repository

classDiagram
  direction TB
  class RepositoryRunner {
    -processor FileProcessor<TConfig>
    -config TConfig
    -policy RunnerPolicy
    +run(files) RepositoryStats
    -updateCounters(result, stats) void
    -printFileStatus(result, file) void
    -getInitCounterState() RepositoryStats
    -printSummary(stats) void
  }
  class RepositoryRunnerOptions {
    <<interface>>
    +processor FileProcessor<TConfig>
    +config TConfig
    +policy RunnerPolicy
  }
  class RepositoryStats {
    <<interface>>
    +updated number
    +unchanged number
    +needsUpdate number
    +skipped number
  }
  class FileProcessor {
    <<interface>>
    +process(filePath, config) ProcessingStatus
  }
  class RunConfig {
    <<interface>>
    +runMode RunMode
    +mode "single" | "recursive"
    +recursivePath? string
    +exclude string[]
    +verbose boolean
    +quiet boolean
    +debug boolean
    +validateExternalLinks boolean
    +linkTimeoutMs number
  }
  class ProcessingStatus {
    <<type>>
  }

util

classDiagram
  direction TB
  class WalkOptions {
    <<interface>>
    +rootDir string
    +extensions? string[]
    +excludeDirs? string[]
  }

Tech Stack

For the full workspace tech stack see: TECH-STACK.md


Contributing

See javascript/docs/CONTRIBUTING.md for workspace-level setup, build pipeline, and release workflow.


Packaging, Publishing, and Inter-relationship with Other Plugins

This package is one component of a small ecosystem of JavaScript tooling plugins maintained as individual npm packages in this repository. The versioning and release of these packages is governed by a coordinated release policy, and the packages adhere to common design and architectural principles described here.