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

@silmaril-security/pi-firewall-plugin

v0.2.3

Published

Silmaril Firewall lifecycle protection for Pi coding agents.

Readme

Pi Firewall Plugin

Silmaril Firewall lifecycle protection for Pi coding agents.

This Pi package classifies raw user input, tool calls, tool results, and finalized assistant text with @silmaril-security/sdk. Shadow is silent, Warn adds one bounded warning where Pi exposes same-turn context, and Block uses Pi-native handled, block, or content-replacement responses only for the exact SDK prediction MALICIOUS.

Install

Install the published npm package with:

pi install npm:@silmaril-security/[email protected]

The immutable GitHub tag is also supported:

pi install git:github.com/Silmaril-Security/[email protected]

For local development or review:

git clone https://github.com/Silmaril-Security/PiFirewallPlugin.git
cd PiFirewallPlugin
npm ci
pi -e .

Configure

The macOS app writes a private configuration file at ~/.pi/agent/silmaril-firewall.json:

{
  "enabled": true,
  "apiUrl": "https://...",
  "apiKey": "...",
  "endpointId": "2b64e603-f82a-4aec-9524-9736472dc80a",
  "timeoutMs": 2500,
  "mode": "warn",
  "debug": false
}

The file must be a regular file owned by the current user with no group or world permissions. Symbolic links, files larger than 64 KiB, malformed JSON, invalid recognized fields, and insecure permissions are rejected without falling back to ambient credentials. SILMARIL_CONFIG_PATH can select a different private file.

Environment variables remain supported as a fallback when the private file is missing. When a valid private file exists, it is fully authoritative so stale process environment cannot disable protection, change its mode, or redirect classified content.

export SILMARIL_API_URL="https://..."
export SILMARIL_API_KEY="..."
export SILMARIL_ENDPOINT_ID="2b64e603-f82a-4aec-9524-9736472dc80a"
export SILMARIL_TIMEOUT_MS="2500"
export SILMARIL_BLOCK_MALICIOUS="false"
export SILMARIL_DEBUG="false"
export SILMARIL_ENABLED="true"

SILMARIL_TIMEOUT_MS accepts 250 through 10000. Missing or insecure configuration, malformed event data, invalid classifier responses, SDK construction, network errors, timeouts, and local evidence failures fail open. Every Pi handler catches failures internally so Pi's fail-safe tool_call error semantics cannot accidentally turn a Firewall outage into a tool block.

SILMARIL_DEBUG=true writes metadata-only summaries to stderr. Raw prompts, assistant text, reasoning, tool arguments, and tool results are never logged.

Every classifier request carries plugin-owned metadata.silmaril.provenance. If the app-provided canonical UUID v4 is absent, the plugin continues with harness-only provenance.

Coverage

| Pi event | Firewall label | Shadow behavior | Block-mode behavior | | --- | --- | --- | --- | | input | user_input | Continue | Return handled and show a bounded notice | | tool_call | tool_call | Continue | Return Pi's native tool block response | | tool_result | tool_response | Preserve result | Replace malicious result before model reuse | | assistant message_end | llm_output | Preserve message | Replace malicious finalized content before delivery |

Input with source === "extension" is always ignored to prevent feedback loops. Assistant classification includes visible text parts only; thinking blocks and tool calls are not duplicated through message_end. Tool calls are protected regardless of which extension registered the tool.

Pi-specific subagent packages, worker adapters, and delegation semantics are not included in v0.1.0. This does not weaken ordinary tool-call protection.

Enforcement semantics

Shadow mode returns no Pi mutation. Omit mode to use the backend, set SILMARIL_MODE=block for a pilot override, or use the legacy block boolean. A supplied mode is sent on the classify request and remains authoritative during mixed-version rollout: an older backend response cannot strengthen an explicit Shadow or Warn request into Block. Casing variants and unknown predictions never block.

The SDK client is cached per extension instance after successful construction. Failed construction is retryable on the next event. Stable logical request IDs use Pi's session ID and host event identity; no process-global synthetic counter is used.

Local evidence

Each completed classification emits a bounded LocalProtectionEventV1 record to:

~/Library/Application Support/Silmaril/Evidence/incoming

The directory is private (0700), each file is private (0600), and writes use a temporary file plus atomic rename. Records contain only fingerprints, bounded consequence metadata, numeric scores, native actions, and version provenance. They never contain prompts, assistant output, tool arguments/results, reasoning, API keys, endpoints, session files, or working-directory paths.

Set SILMARIL_LOCAL_EVENT_DIR only when the default spool must be overridden. Evidence failure never changes the Pi response.

Demo

The package includes a silmaril-demo skill and credential-safe launcher for the hosted demo:

node scripts/open-playground.mjs
node scripts/open-playground.mjs --open
node scripts/open-playground.mjs --route playground --json
SILMARIL_DEMO_BASE_URL="http://localhost:3001" node scripts/open-playground.mjs

JSON output reports only the URL, configuration presence, API-key presence, and API origin. It never prints the key.

Development

npm ci
npm run lint
npm test
npm run pack:dry
pi -e .

Pi loads the TypeScript extension directly. Runtime dependencies are in dependencies; Pi's core package is a "*" peer dependency as required by Pi package distribution.

Security and license

Report vulnerabilities through GitHub private vulnerability reporting. See SECURITY.md. The plugin is licensed under Apache-2.0; see LICENSE and NOTICE.

References