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

@aiorouter/dsh-shield

v2.0.2

Published

AIOrouter Shield — privacy-restoration policy controls (GW-2 header, GW-1 markers) and Shield status/usage tooling for the DeepSeek Harness (dsh). Plugin-only: reads the public /v1/me/* whitelist, stores no API keys, writes no files.

Readme

@aiorouter/dsh-shield

AIOrouter Shield controls and status tooling for the DeepSeek Harness (dsh) plugin system.

Merged (2026-08-31): Shield is now part of the unified AIOrouter plugin @aiorouter/dsh-aiorouter-mas — which adds the AIOrouter model route and the multi-agent workflow on top of the same privacy status window. New installs should use @aiorouter/dsh-aiorouter-mas; this package remains available for existing setups and receives security fixes.

This plugin is public (npm package). It only touches the public AIOrouter API contract: account health (GET /v1/me/usage), session protection summary (GET /v1/me/protection-summary?window=session), model discovery (GET /v1/models), and the request header values the gateway already defines. It stores no API keys, writes no files, and never embeds server-side privacy-taxonomy internals.

Features

  • Dashboard-governed privacy (V2.0.0) — Restore/Redact/Disable are controlled exclusively on the AIOrouter Dashboard (https://dashboard.aiorouter.ca, per-key policy + Shield toggle). This plugin no longer writes x-aiorouter-privacy-policy / x-aiorouter-restoration-markers and no longer registers a settings section — there is intentionally no policy control surface in dsh (single control surface, no dual-control drift).
  • aiorouter_shield_status tool — model-facing account card (balance, effective policy, Shield state, dashboard link) and the per-session protection mapping table (type × count × disposition), with metadata-only output (no protected values ever rendered). The effective policy shown is the dashboard-governed GW-3 value.
  • model discovery — on plugin load, when an API key is configured, fills the provider's model list from the gateway's OpenAI-compatible /v1/models (never clobbers user-maintained models; silent if the key is missing or the call fails).
  • PL-9 floating value-comparison window — a draggable, minimisable Shield window in the Web UI (all-English UI). It defaults COLLAPSED to a compact vertical {icon / counts / Detected} card (V1.0.2): three centre-aligned lines (shield icon, the live session detection count, and the label) in a narrow column, so the bottom-right anchor never overlaps the chat composer input. The collapsed card is itself draggable (drag moves it, click expands). Clicking expands the detailed list, which shows (a) the CURRENT Restore/Redact posture (W-5: the dashboard-governed effective policy and Shield state, read-only via the aiorouterShield/getStatus remote) and (b) what was replaced vs what the model actually saw (Type × Before (Original) × LLM Saw × Action, four equal-width columns, with a Detected {N} · Restore {R} · Redact {D} · 10-minute window summary line). Restored entries show the original value; redacted entries never show it. The window reads the ephemeral /v1/me/redaction-trace endpoint through host-side Typert remotes — the API key stays on the host and the payloads are held in pure client memory (never written to disk or localStorage, never sent to the model).
  • Client wire contract (dsh v0.1.0-rc.6, V2.6.4): the bundle declares inject ["slots","connection","remote"] and resolves the namespace face with ctx.get('remote.aiorouterShield') — the reflector-STORE lookup that deliberately has NO cordis inject guard (gateway.client.spec.ts resolves ctx.get('remote.probe') the same way). The two wrong shapes are documented regressions: declaring remote.aiorouterShield in inject deadlocks boot (the api-gateway installs that dotted child service only while this entry's own apply runs ctx.remote.$mount, so cordis inject-wait — which has no timeout — leaves the entry PENDING → 1 entry did not activate … (waiting for service: remote.aiorouterShield)), and accessing it as a plain property without the inject entry throws cannot get property "remote.aiorouterShield" without inject at apply time. The namespace face and its methods are bound INSIDE apply; the window never touches the ctx proxy at render time (React effects / 60s interval / event handlers call only the bound functions), then the bundle mounts a hand-written Typert remote contribution via ctx.remote.$mount({ package, descriptors }) (direct, zero-parameter, cancellation: { parameter: 'signal' }) exposing getRedactionTrace and getStatus; both resolve to the RemoteResult envelope ({ ok: true, value } | { ok: false, error }). The contribution's result MUST be a mode: 'strict' codec — the client api-gateway's requireStrictCodec rejects src-json with field "result" has no strict codec and the whole plugin fails to load; the strict schema is a zod-free shape guard (src/redaction-trace-codec.ts) so zod never enters the client bundle. ctx.connection.api.* is the fixed legacy host-apiproxy face (sessions/goals/settings/…) and does not project plugin remotes — do not regress to it (V2.6.2 fix for Cannot read properties of undefined (reading 'getRedactionTrace')).
  • Host wire contract (dsh v0.1.0-rc.6, V2.6.5): the gateway claims the aiorouterShield/* endpoints only after TWO host-side steps. (1) A HOST strict contribution is registered via ctx.typert.register(...) — the typert-loader auto-registers only packages that export a ./typert host-face artifact whose codecs are real zod v4 schemas; this package intentionally ships zero runtime deps, and the typert REGISTRY's own validation (validateInvocation/validateCodec) accepts the same zod-free shape-guard codecs the client uses (src/typert-contribution.ts). (2) The remote service is mounted with ctx.root.plugin(ShieldHostRemote, { pluginCtx })ctx.root is the common ancestor of every cordis context, so the gateway's receiver resolution (ctx.get('aiorouterShield')) always succeeds; business seams come through pluginCtx because root-scope static inject resolution is not guaranteed. Without BOTH steps the client sees transport failure for /api/aiorouterShield/getRedactionTrace: HTTP 404 (V2.6.4 regression root cause). Both are guarded — plugin apply never rejects, so a dsh web restart cannot regress into a Failed to load plugins web boot.

Installation

dsh plugin add @aiorouter/dsh-shield

Then configure the AIOrouter API key in Settings → Models (AIOROUTER_API_KEY).

V2.0.0 upgrade note: plugin versions ≤ 1.0.2 wrote x-aiorouter-privacy-policy / x-aiorouter-restoration-markers into the provider route and registered an AIOrouter Shield settings section — both are REMOVED. Restore/Redact/Disable are governed exclusively on the dashboard (https://dashboard.aiorouter.ca, per-key). If you upgraded from ≤1.0.2, remove the two stale header lines from your provider (~/.dsh/profiles/web/settings.yamlllm-pi-ai.providers.aiorouter.headers) so requests stop carrying the old policy header; the dashboard settings then take effect for dsh traffic too.

Peer-only runtime (V1.0.1): since V1.0.1 the package declares its @deepseek-ai/* runtime imports (cordis, dsh-tools, dsh-settings, dsh-credentials, dsh-typert-protocol, schemastery) as peerDependencies, provided by the dsh harness. Do not add them back to dependencies: a nested copy in a profile's node_modules shadows the harness junction and breaks Symbol identity (Cannot read properties of undefined (reading 'prepare') — a harness-side peer-resolution bug, fixed in the harness during August 2026). Profiles that run pnpm installs must keep auto-install-peers=false in their .npmrc (installed with the web profile since 2026-08-20).

Display contract (parity with the gateway)

The account card and summary table read the public /v1/me/* whitelist exactly as the gateway serializes it (2026-08-15 audit):

  • effectiveRestorationPolicy / policy arrive as OBJECTS ({ default_mode, overrides? }), not preset-name strings. The plugin maps them to the SD-D9 display names (Restore All / Redact Secrets / Redact All / Custom).
  • The table's Action column prefers policy_result (restored → Restored, redacted → Masked — emitted only when unanimous) and falls back to the raw DLP action semantics (pseudonymized / depseudonymized / blocked / flagged …) when there is no unanimous result.

Updating (V1.0.2)

New versions of this plugin are published to the npm registry. The DSH plugin manager (dsh plugin) has no silent auto-update: after a release, update with the one-command pnpm forwarder (installs the newer version; the DSH reconcile step re-activates the bundle automatically):

dsh plugin --profile <profile> update @aiorouter/dsh-shield
# e.g. dsh plugin --profile web update @aiorouter/dsh-shield
  • The aiorouter_shield_status tool shows a 📦 Update available: X → Y line (checked against the public npm registry metadata at most once per day) when a newer version exists — the update command is printed right there.
  • Model-catalog auto-sync: the aiorouter route's model list refreshes from the gateway's /v1/models every modelRefreshMinutes (default 360 = 6h, 0 = at boot only). New gateway models appear automatically; user-added models are never removed (append-only union-merge).

Privacy posture

  • Zero-disk: API keys live only in the credentials seam, resolved per call.
  • Zero-PII: the status tool renders counts, type labels, dispositions, and policy names only.
  • Header values are the preset names the gateway accepts, or JSON the gateway validates. Structurally invalid JSON (bad shape, empty overrides, no recognized signal) falls back to the preset rather than poisoning the request. Per-type NAMES in the advanced JSON are validated by the gateway itself (this package never embeds the type taxonomy): a mistyped name is a loud, explicit HTTP 400 — never a silent privacy change.
  • This package holds no founder/personal identity and no contract pricing.

License

MIT