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

@runenv/agent-edge

v0.3.0

Published

Local exposure scanner and secure runtime edge for RunEnv Agent Guard

Readme

@runenv/agent-edge

Find agent-readable credentials and unsafe agent configuration locally, without uploading credential values.

@runenv/agent-edge is the open RunEnv Agent Guard edge scanner. It provides a bounded command-line doctor and an ESM API for producing local exposure reports and explicit privacy-preserving upload projections.

Installation

npm install @runenv/agent-edge

Current package version: @runenv/[email protected]. See CHANGELOG.md for release notes.

Requires Node.js 20 or newer.

Quick Start

Scan the current directory and render a human-readable report:

npx @runenv/agent-edge doctor .

Request the same local report as JSON:

npx @runenv/agent-edge doctor . --json

The doctor command never publishes a report. Its exit codes are:

| Code | Meaning | | --- | --- | | 0 | The scan completed without critical or high-severity findings. | | 1 | The command or scan failed. | | 2 | The scan found at least one critical or high-severity exposure. |

Treat local JSON as sensitive metadata: it contains relative paths and may contain keyed credential fingerprints when the programmatic API enables them. It never contains the detected credential values.

What It Detects

The scanner currently checks for:

  • literal credential-like assignments in .env* files;
  • high-confidence API keys, access tokens, private keys, and credential-bearing service URLs;
  • credentials embedded in MCP and supported agent configuration files;
  • enabled auto-approval or permission-bypass settings;
  • wildcard tool allowlists;
  • well-known cloud and package credential files inside the scan root;
  • overly broad permissions on credential-bearing files on non-Windows systems; and
  • duplicate credentials when a caller supplies a fingerprintKey.

Generated findings include remediation guidance, but never the matched credential value.

Programmatic API

import { randomBytes } from 'node:crypto'
import {
  renderExposureReport,
  scanExposure,
  toExposureUpload,
} from '@runenv/agent-edge'

const report = scanExposure(process.cwd(), {
  fingerprintKey: randomBytes(32),
  limits: {
    maxEntries: 10_000,
    maxFiles: 2_000,
  },
})

console.log(renderExposureReport(report))

// This creates a privacy-preserving DTO; it does not send a network request.
const upload = toExposureUpload(report, randomBytes(32))

Exports

| Export | Purpose | | --- | --- | | scanExposure(root, options?) | Synchronously scan a directory and return a validated ExposureReport. | | renderExposureReport(report) | Render a validated report for a terminal or log stream. | | toExposureUpload(report, uploadKey) | Create a validated upload-safe projection using a key of at least 32 bytes. | | DEFAULT_EXPOSURE_SCAN_LIMITS | Read-only default traversal and resource budgets. | | AGENT_EDGE_VERSION | Scanner version recorded in generated reports. | | ExposureScanLimits | TypeScript interface for all scanner budgets. | | ExposureScanOptions | TypeScript interface for limits, clock injection, and keyed fingerprints. |

scanExposure() resolves the requested root to a real directory and throws when the root is invalid or a supplied limit is not a positive integer. The scanner uses synchronous filesystem operations, so server applications should run large scans outside latency-sensitive request handlers.

Scan Limits

Every scan is bounded. The defaults are:

| Limit | Default | | --- | ---: | | Visited directory entries | 50,000 | | Scanned files | 5,000 | | Bytes per file | 1,000,000 | | Total scanned bytes | 50,000,000 | | Findings | 500 | | Directory depth | 20 | | Duration | 30,000 ms |

The entry budget is charged before ignore, file-type, extension, symlink, and readability filters. Symlinks are not followed, and common generated or dependency directories such as .git, node_modules, dist, and vendor are skipped. A report is marked truncated when a terminal budget is reached; inspect its skipped entries before treating it as complete.

Privacy and Security

Local scanning requires no RunEnv account and performs no network request.

scanExposure() deliberately retains relative paths so a developer can remediate local findings. If fingerprintKey contains at least 32 bytes, it also emits HMAC fingerprints used to identify duplicate credentials within the scan. Keep that local report on the device.

Before any publication, call toExposureUpload() with a separate key of at least 32 bytes. The projection:

  • replaces relative paths with keyed path hashes;
  • removes paths from skipped-file entries;
  • removes credential fingerprints;
  • replaces stable local finding IDs with report-scoped keyed digests; and
  • revalidates the result against the strict exposure upload contract.

The function only returns a DTO. Authentication, authorization, transport, and the decision to publish remain the caller's responsibility.

Compatibility

  • Node.js >=20.0.0
  • ECMAScript modules (import / ESM)
  • @runenv/[email protected]
  • macOS, Linux, and Windows filesystem paths; file-mode findings are intentionally omitted on Windows

License

Apache License 2.0. See LICENSE and NOTICE.