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

dsh-fence

v0.1.0

Published

Declarative tool fencing for DeepSeek Harness: allow/deny/ask rules over tool invocations with argument globs, wired to the native approval flow, with an audit trail.

Readme

dsh-fence

Declarative tool fencing for DeepSeek Harness (dsh).

dsh gives you tools/pre-execute waterfalls and approval policies, but keeping agents away from rm -rf, .env writes, or internal URLs still means hand-writing listeners. dsh-fence turns that into config:

# in your profile's cordis.patch.yml
- id: fence
  name: dsh-fence
  config:
    rules:
      - match: { tool: bash, arguments: { command: "*rm -rf*" } }
        decision: deny
        reason: "no recursive deletes"
      - match: { tool: write, arguments: { path: ".env*" } }
        decision: ask
      - match: { tool: web_fetch, arguments: { url: "**internal.example.com**" } }
        decision: deny
    defaultDecision: allow
  • First match wins — rules are evaluated top to bottom; the first matching rule decides.
  • allow / deny / ask — ask hands off to dsh's native approval flow (UI prompt or headless responder). dsh-fence never auto-approves anything.
  • Argument globs — constrain any argument path (command, path, nested options.mode, …) with * patterns. * matches any characters including separators, so *rm -rf* catches rm -rf /tmp/x. Over-matching is the safe default for a fence.
  • Audit trail — every decision is recorded (tool, decision, matched rule, reason) and shown via the /fence command.

Unmatched tools fall through to defaultDecision (allow unless you say otherwise).

Install

Requires a dsh profile (see the dsh plugin docs):

dsh plugin --profile <name> add dsh-fence
# or from git:
dsh plugin --profile <name> add github:leesama/dsh-fence

Rule reference

| Field | Type | Notes | |---|---|---| | match.tool | glob | Tool name, e.g. bash, write, * | | match.arguments | map of path → glob | Dot paths into the parsed tool arguments; missing value ⇒ rule doesn't match | | decision | allow | deny | ask | ask delegates to the native approval waterfall | | reason | string | Shown on deny/ask and in the audit report |

Commands

  • /fence — decision counts and the most recent 20 audited calls.

How it works

tools/pre-execute (waterfall)
  ├─ evaluateRules(config, toolName, arguments)   ← pure engine, first match wins
  ├─ allow → next()                               ← tool proceeds through the pipeline
  ├─ deny  → { kind: "deny", reason }             ← tool never runs
  └─ ask   → preserve downstream denial, otherwise { kind: "ask", reason }
                                                   (allowed-once runs; otherwise rejected)

The rule engine (src/engine.ts) is pure and unit-tested; src/index.ts provides the Cordis wiring. The suite named test:e2e drives apply() against a mock DSH pipeline. These are simulated integration tests; they do not start a real DSH process or verify its approval UI.

test:package separately builds the release, packs and installs the tarball into a temporary directory, and imports its entry in a fresh Node process. This verifies the published module layout, not full DSH behavior.

Development

npm install
npm run typecheck   # tsc --noEmit (strict)
npm test            # unit + e2e
npm run test:coverage
npm run test:package # pack, install and load the built module
npm run build       # tsc → lib/

License

MIT