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

vulgarian

v0.3.0

Published

Incremental log analysis as validated JSONL with rotating model CLI enrichment

Readme

Vulgarian

Vulgarian watches a growing log file and emits a bounded, versioned stream of JSON observations. Deterministic parsers run for every batch; installed model CLIs can then enrich successive batches in a Claude → Codex → Grok rotation. The same validated data drives an offline browser UI or any JSONL-aware TUI.

log file → complete-line tailer → deterministic parsers → rotating model CLI
                                                  ↓
                         JSONL | latest JSON | HTTP/SSE | browser/TUI

Quick start

npm install
node .\bin\vulgarian.js .\server.log

JSONL observations go to stdout. Human-readable status goes to stderr, and the browser UI is served on http://127.0.0.1:2025. The UI maps metric series to locally served Chart.js charts and tables, tracked variables to a key/value table, and events or diagnostics to typed tables.

Useful modes:

# Deterministic extraction only; no model receives log contents.
node .\bin\vulgarian.js .\server.log --providers none

# Append JSONL to a file and atomically replace a latest-snapshot file.
node .\bin\vulgarian.js .\server.log --jsonl .\observations.jsonl --snapshot .\latest.json

# Analyze all complete content present at startup, using bounded reads.
node .\bin\vulgarian.js .\server.log --once --no-server --from-start --providers none

# Machine-clean stdout for a TUI; diagnostics remain on stderr.
node .\bin\vulgarian.js .\server.log --no-server --jsonl - | your-tui

Run node .\bin\vulgarian.js --help for every option.

Built-in parsing

Every nonempty scheduled batch is parsed without a model. The deterministic passes recognize:

  • JSON Lines fields such as timestamp, level, message, numeric metrics, and primitive facts;
  • common ISO timestamps and TRACE/DEBUG/INFO/WARN/ERROR/FATAL levels in text logs;
  • key=value tokens, including numbers, booleans, strings, and obvious units such as ms, %, and bytes;
  • stable metric series across repeated keys, severity counts, source byte offsets, truncation, and file replacement.

Input is buffered by complete line, preserves split UTF-8 characters, and is bounded independently from the model cadence. A slow model does not overlap another model call; newly arrived lines are coalesced for the next batch.

Model rotation

At startup Vulgarian resolves default commands from absolute PATH directories, then safely probes those absolute executables with --version. Available providers rotate once per analysis batch in stable order:

| Provider | Commands | Fast default model | | --- | --- | --- | | Claude | claude | fable | | Codex | codex | gpt-5.3-codex-spark | | Grok | grok, then agent fallback | grok-build |

Override models with --model-claude, --model-codex, and --model-grok, or the VULGARIAN_CLAUDE_MODEL, VULGARIAN_CODEX_MODEL, and VULGARIAN_GROK_MODEL environment variables. The former PEACOCK_* names remain supported as fallbacks. Restrict discovery with, for example, --providers claude,codex.

Prompts never appear in command-line arguments and shell execution is disabled. Claude and Codex read stdin; Grok uses its documented headless prompt-file mode with a private temporary file that is removed after each run. Provider runs use isolated temporary working directories and have time and output limits. Claude tools are disabled, Codex runs read-only without user config, and Grok tools/web search/subagents are disabled. Invalid JSON, schema errors, timeouts, unavailable authentication, and nonzero exits become structured diagnostics; deterministic data and the last good accumulated values remain.

Each model is explicitly asked to extract every evidenced key/value variable into bounded facts entries with stable keys. The Tracked Variables panel shows their latest value, update time, and source; repeated numeric variables may also be returned as chartable metric series.

An installed CLI can still be unauthenticated. In that case it stays in the rotation and reports a provider diagnostic until it is authenticated or excluded.

JSONL observation contract

Each line is one complete schemaVersion: 1 observation. Script and model observations use exactly the same envelope:

{
  "schemaVersion": 1,
  "kind": "observation",
  "id": "session-id:2",
  "sequence": 2,
  "generatedAt": "2026-07-18T12:00:01.000Z",
  "source": {
    "path": "C:\\logs\\server.log",
    "generation": "0",
    "fromOffset": 120,
    "toOffset": 240,
    "lineCount": 3,
    "byteCount": 120
  },
  "generator": {
    "kind": "model",
    "name": "claude",
    "provider": "claude",
    "model": "fable",
    "status": "ok",
    "durationMs": 412
  },
  "summary": "Three healthy requests completed.",
  "metrics": [
    {
      "id": "latency_ms",
      "label": "Latency Ms",
      "unit": "ms",
      "points": [{ "at": "2026-07-18T12:00:00.000Z", "value": 12.5 }]
    }
  ],
  "facts": [{ "key": "service", "value": "api" }],
  "events": [
    { "at": "2026-07-18T12:00:00.000Z", "level": "info", "message": "ready" }
  ],
  "diagnostics": []
}

The latest-snapshot file and /api/v1/snapshot contain the accumulated, bounded form of these observations. /api/v1/events publishes the same snapshots over Server-Sent Events. Consumers should reject unknown schemaVersion values.

Startup and output semantics

  • Default: inspect the most recent 64 KiB, aligned to complete lines.
  • --from-start: begin at byte zero, still using bounded reads.
  • --from-end: ignore content that already exists.
  • JSONL files are append-only so sessions remain inspectable.
  • --snapshot writes a complete temporary file and atomically renames it.
  • The HTTP server binds 127.0.0.1 unless explicitly configured otherwise.

Data handling

Logs often contain credentials or private data. Deterministic mode keeps log contents local. Enabling model providers sends each selected batch through the corresponding CLI and may transmit it to that provider's service. Use --providers none for sensitive logs that must remain local.

Development

npm test
npm pack --dry-run

The automated suite uses fixture child processes and never makes paid model requests.