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

infracensus-collector

v1.6.41

Published

InfraCensus on-premises collector: discovers your network (ICMP/ARP/SNMP/SSH, VMware, Hyper-V, SQL Server, load balancers, voice, Microsoft Entra ID, Azure) and pushes normalized inventory snapshots outbound to your InfraCensus control plane. Device crede

Readme

InfraCensus Collector

This is the operator's page. It is written for the person who runs the collector on their own hardware, inside their own network, holding their own device credentials — not for us.

The collector is outbound-only on your network. It polls the control plane; the control plane never connects in, and nothing here listens on a network interface. There is exactly one listener anywhere in the product and it is pinned to 127.0.0.1 — the local status UI, described below, unreachable from any other machine by construction and asserted at startup, not assumed.


How it is organized — three planes

1. The data plane

your network                     this host                                InfraCensus cloud
────────────                     ─────────                                ─────────────────

                    config: /etc/netdoc-collector/collector.env  (0600)
                    identity + the collector key + device credentials
                                     │
                                     ▼
switches, hosts,   ◄── scan ──  scan modules                 poll (outbound) ──►  control plane
hypervisors,                    network · vmware · hyperv    ◄── scan jobs,       (never connects
vCenter, SQL,                   sql · lb · voice · identity      cancellations,    into your
Entra ID, Azure                 azure · config-import            restart signal)   network)
                                     │
                                     │  raw facts — device credentials are used
                                     │  HERE and go no further
                                     ▼
                                canonical snapshot / inventory
                                (normalized, redacted, stamped
                                 with tenant + site)
                                     │
                                     ▼
                                authenticated push ── Bearer collector key ──►  ingest
                                     │
                                     ▼
                                use log (JSONL ledger on this host —
                                your evidence of what was touched)

browser ON THIS HOST ──► http://127.0.0.1:9477   the local UI (status, log tail,
                                                 run-a-scan) — loopback only

Configuration is resolved once, locally. Scan modules read it, talk to your equipment, and hand back raw facts. Those facts are normalized into the canonical model, redacted, and pushed outbound with the collector's key. In daemon mode the same loop runs in reverse order: the collector polls for a job, the job carries the targets and credentials, and the snapshot is stamped from the job. Nothing is ever pushed that was not first normalized and redacted.

2. The security boundaries

The collector key authenticates this host to the control plane.

  • At rest it lives in exactly one file (collector.env / collector.config.json), created empty and locked to mode 0600 (Linux) or an explicit three-SID ACL (Windows) before the key is written into it.
  • It is never a process argument — there is no --api-key flag, and a test asserts there never will be. Enrolment takes it at a muted prompt or from a file whose path (not contents) was the argument.
  • It is never logged. Every log line and every ledger record passes through a redactor that knows the key's value before the first line is written.

Device credentials (SSH, SNMP, WMI, vCenter, SQL, Graph, Azure) are resolved on this host and used from this process. They are never placed in a snapshot, never logged (the redactor learns per-job credentials the moment a job is claimed, before the job is logged at all), and never sent anywhere. What leaves the building is the result of using them — and device configuration text is redacted here, before it leaves.

The local UI is loopback-only with cloud-verified login:

  • It binds 127.0.0.1 explicitly and the daemon checks the address the OS actually bound after listen, refusing to serve on anything else.
  • There are no local accounts. Signing in forwards your email and password (with the collector's own key as the Bearer) to the control plane, which accepts only an active account of this collector's own tenant. Disable the account in the portal and the UI closes with it. No password is ever stored — or logged — on this host.
  • Sessions are cookies signed with a secret generated fresh at every daemon start, so restarting the daemon invalidates every session, and there is no session secret at rest to protect. Cookies are HttpOnly, SameSite=Strict, and expire after 8 hours. Five failed logins in fifteen minutes lock the login for everyone until the oldest failure ages out — one limiter across all sessions, because on loopback there is only one address.

3. The UI plane — what it serves, and what it refuses to

Serves, to a signed-in operator on this host:

  • daemon status: version, when it started, when it last polled the control plane, when data last left this host;
  • a per-module table of last runs (read from the use-log ledger — the same file that is your evidence, so the UI can never claim more than the ledger holds);
  • the tail of the daemon log;
  • a Run scan button per module (spawns the same one-shot netdoc-collector scan <module> you could type) and a Restart button (the same restart path the portal's restart signal uses).

Refuses, by construction:

  • to be reachable from any other machine (loopback bind, asserted);
  • to display the collector key, or any stored credential, anywhere — the status payload is built from an allowlist that does not contain them, the page is a static string with nothing interpolated into it, and a test holds both;
  • to accept credentials for storage — there are no device-credential fields in the UI; credentials are configured in the config file, on disk, under its permissions;
  • to answer anything stateful without the session cookie;
  • to serve at all when COLLECTOR_UI=0 — disabled means no listener exists, not a listener that says no.

Install

The collector is distributed on the npm registry as infracensus-collector. The package installs one command, netdoc-collector (package name and command name differ on purpose, the way typescript installs tsc). Node.js 20 or newer is the only prerequisite.

If Node/npm is not on the host yet — Linux: install Node.js 20+ from your distro or nodejs.org; e.g. RHEL/Fedora: sudo dnf install nodejs npm — Debian/Ubuntu: sudo apt install nodejs npm — or nvm. Windows: winget install OpenJS.NodeJS.LTS (or the nodejs.org installer).

Linux

sudo npm install -g --allow-scripts='ssh2,tesseract.js' infracensus-collector
sudo netdoc-collector enrol --show-input # prompts for the token; --show-input echoes it as you paste
sudo netdoc-collector service install    # systemd unit, enabled and started

The service runs as the netdoc-collector system account, keeps its identity at /etc/netdoc-collector/collector.env (mode 0600 root:root, read by systemd before privileges drop), and writes everything — logs, ledger, PID — to /var/lib/netdoc-collector. An npm update -g infracensus-collector replaces the code without touching either.

Windows

From an ADMIN PowerShell:

npm install -g --allow-scripts='ssh2,tesseract.js' infracensus-collector
'enrol_YOUR_TOKEN' | netdoc-collector enrol       # piped, because the console may not paste
netdoc-collector service install                  # registers and starts the Windows service
Get-Service -DisplayName "InfraCensus Collector"  # ask Windows, not us, whether it worked

The token is piped rather than pasted on Windows. enrol draws a readline prompt, and a Server console frequently cannot paste into one: Ctrl+V does nothing in a legacy conhost window, and right-click pastes only with QuickEdit Mode enabled — off by default, and commonly off over RDP. enrol already reads the token from stdin when stdin is not a terminal (the path built for installers), so piping skips the prompt entirely: nothing is echoed and nothing has to be pasted.

That form does put the token in your PowerShell history, which the prompted path never did. Clear it with Remove-Item (Get-PSReadLineOption).HistorySavePath, or avoid it: put the token in a file, run Get-Content -Raw C:\temp\enrol.txt | netdoc-collector enrol, then delete the file. The Linux prompt above still takes the token only at the prompt, never as an argument.

This registers the InfraCensus Collector Windows service. The SCM-level id is infracensuscollector.exe, derived by the service host and not ours to set, which is why the check above asks by display name; netdoc-collector service status answers the same question from the collector's side. The identity lives under C:\ProgramData\InfraCensus Collector — locked to SYSTEM and Administrators, and deliberately outside the npm package so an uninstall or update of the code cannot destroy a key that was shown exactly once.

From a checkout (development / air-gap)

pnpm install in this directory, then the pnpm aliases below; pnpm build bundles dist/. The CLI is the same code either way: npx tsx src/cli.ts <command> in a checkout is netdoc-collector <command> on an installed host. On an air-gapped Linux host, sudo ./scripts/install.sh registers the from-source checkout as a service without touching a registry.

Enrolment

An enrolment is six values shown in the portal under Admin → Collectors, wrapped in one enrol_… token beside the key. The token contains the key: it is shown once, belongs in a password manager, and the prompt that takes it does not echo. An all-sites collector's token carries an empty org and site on purpose — such a collector runs as a daemon and takes tenant, site and targets from each job.


Command reference

One installed command, netdoc-collector (npm's bin shim onto dist/cli.js). enrol / doctor / uselog are standalone scripts underneath — they must work before, or without, a built collector — and the CLI routes those three subcommands to them, wiring the platform's config paths on the way.

| Command | What it does | |---|---| | netdoc-collector run | The daemon: poll the control plane for scan jobs, serve the local UI. This is what the service unit runs. | | netdoc-collector scan [module] | ONE scan in the foreground, then exit. Default module: network. --dry-run builds the result and prints a summary without pushing. | | netdoc-collector status | Local status: enrolment, daemon liveness, last run per module. | | netdoc-collector enrol | Enrol this host. Secrets are shown masked — one dot per character — as they are typed or pasted; --show-input echoes them in full, --replace re-keys an existing install. | | netdoc-collector doctor | Is it running, and is it talking to the cloud. Prints no credential, ever. | | netdoc-collector uselog | What this collector did on your network, from your own ledger. | | netdoc-collector service install | Register and start the background service (Linux: sudo, systemd — Windows: elevated, SCM). Refuses politely until the host is enrolled. | | netdoc-collector service uninstall | Stop and deregister the service. The identity and ledgers stay on disk, and it says so. | | netdoc-collector service status | Registered/active? Exit 0 running · 1 registered but stopped · 2 not installed. | | netdoc-collector --version | Print the version. | | netdoc-collector --help | Print usage. |

Anything else prints the help and exits 2.

Scan modules: network (ICMP/ARP/SNMP/SSH sweep), vmware, hyperv, sql, lb (A10), voice (CUCM/Unity/Webex), identity (Microsoft Entra ID), azure (CSPM), config-import (offline device configs). Each reads its own section of the config; a module with nothing configured says what is missing and exits non-zero.

Checkout equivalents: pnpm scan, pnpm scan:dry, pnpm scan:daemon, pnpm vmware-scan, pnpm hyperv-scan, pnpm sql-scan, pnpm lb-scan, pnpm voice-scan, pnpm identity-scan, pnpm azure-scan, pnpm config-import, pnpm enrol, pnpm doctor, pnpm uselog.


The local UI

http://localhost:9477        # from a browser ON the collector host

Sign in with your InfraCensus account (an active account of this collector's tenant — there is nothing local to sign in to). The page shows the daemon's status, the per-module last-run table with Run-scan buttons, a Restart button, and the daemon log tail, refreshing every five seconds. A scan started from the UI runs as a separate process and narrates itself into the same log tail the page is already showing.

Two environment variables control it — the only two the UI has:

| Variable | Effect | |---|---| | COLLECTOR_UI_PORT | Port for the UI (default 9477; always 127.0.0.1). An unusable value falls back to the default rather than stopping the daemon. | | COLLECTOR_UI=0 | Disable the UI entirely. The daemon then opens no port at all. |

On an installed host, set them in /etc/netdoc-collector/collector.env (Linux) or the service environment (Windows) and restart the service.

If the UI fails to start — a squatted port, say — the daemon logs a warning and keeps scanning. The status page is a convenience; the scans are the job.


Check it, and see what it did

netdoc-collector doctor            # elevated on Windows: the config is ACL'd
netdoc-collector status
netdoc-collector uselog            # your evidence ledger, rendered

doctor answers "is it running, and is it talking to the cloud" entirely locally, printing values only from an allowlist of non-secret config keys; the key itself appears only as a short fingerprint. uselog renders the collector's own ledger — a rotated, redacted JSONL file (collector-use.log, ~25 MB hard ceiling) recording what was scanned, what was contacted, and what was sent where. It is your record, not our telemetry: nothing in it is transmitted, and deleting it costs only your own evidence.


Uninstall

sudo netdoc-collector service uninstall && sudo npm uninstall -g infracensus-collector
# full purge of config + ledgers afterwards (the uninstall prints this too):
sudo rm -rf /etc/netdoc-collector /var/lib/netdoc-collector
# elevated:
netdoc-collector service uninstall
npm uninstall -g infracensus-collector

The identity is left on disk on purpose (the key in it was shown once); the uninstall names the directory and the purge command. Then remove the collector in the portal under Admin → Collectors — the uninstaller says this too. Until you do, its key remains valid for anyone who kept a copy.


If something is wrong

It stops with no error in the log — check EDR / antivirus. The daemon logs uncaught exceptions and keeps running, so a code fault always leaves an ERROR line; silence means the process was killed from outside. To a behavioral engine, a process that sweeps thousands of addresses, opens SSH sessions with stored credentials and spawns PowerShell for AD/WMI looks like lateral movement. Add a tightly-scoped exclusion and check the OS event log around the time it vanished.

Scans sit at "Waiting for a collector." Either no collector is authorized for that site (portal, Admin → Collectors) or the collector is not polling (doctor on its host, or the UI's "last poll" timestamp).

The UI shows the login form and rejects a good password. The control plane must be reachable from the collector host for login to verify — a 502 on the login call means the uplink, not the password. Also check the account is active and belongs to the same tenant as the collector.

It starts and immediately exits. Run it in the foreground: netdoc-collector run (checkout: npx tsx src/cli.ts run). The usual causes are a missing or malformed config, an unreachable control plane URL, or a revoked key.


Files on this host

| File | Path (installed / checkout) | |---|---| | Config — holds the key | Linux /etc/netdoc-collector/collector.env · Windows C:\ProgramData\InfraCensus Collector\collector.config.json · checkout collector.config.json (override: COLLECTOR_CONFIG) | | Daemon log | Linux service /var/lib/netdoc-collector/collector-daemon.log · otherwise collector-daemon.log beside the package | | Use-log ledger | Linux service /var/lib/netdoc-collector/collector-use.log · otherwise collector-use.log beside the package (override: COLLECTOR_USE_LOG) | | PID file | .collector-daemon.pid beside the package (best-effort — under the sandboxed systemd unit, liveness is systemd's answer, not the file's) | | Bundled entrypoint | dist/cli.js — what npm's bin shim, the systemd unit and the Windows service all run |