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

nominee-eve

v3.0.0

Published

Eve agent tools with policy, approvals, and receipts — without it, the args you pause can change while the token dies out of band.

Readme

Note: Eve is ESM-only, so nominee-eve is ESM-only too.


Installation

npm i nominee nominee-eve

Observe Before Enforcing

Pass new Nominee({ mode: 'observe' }) into nomineeTool or withNominee to inventory the Eve tool callbacks that actually run before writing a policy. Nominee and Eve-native approval gates configured through this adapter are suppressed while the policy verdicts are recorded. Observation reports do not retain raw string/boolean values or user IDs; numeric aggregates may be sensitive. Observe mode is not a security control and cannot be combined with production: true.


How It Works

flowchart LR
    Agent["Eve Agent\ndecides to call tool"] --> T["nomineeTool()\n(wraps defineTool)"]
    T --> RUN["nominee.run()\ndecision-bound path"]
    RUN --> P{"policy:\nallow / deny / ask"}
    P -->|deny| X["PolicyDeniedError\n(tool never runs)"]
    P -->|ask| AP["⏸ wait for a\nhuman decision"]
    AP -->|pending| APE["ActionPendingError\n(durable action id)"]
    AP -->|approved| CAP["consume capability\n(exact input hash)"]
    P -->|allow| CAP
    CAP --> TOK["strategy resolves\ntoken (optional)"]
    TOK --> EX["execute(input, ctx)"]
    EX --> R["receipt appended\nhash-chained record"]

nomineeTool routes every call through nominee.run() — binding authorization to a fingerprint of the arguments and issuing a single-use capability before execute runs. Denied calls throw PolicyDeniedError; ask calls block until a human decides or surface ActionPendingError when the approval outlives the request; every outcome (including refusals) lands on the receipt chain. The same policy and receipts travel with you if the agent moves off Eve.


Quickstart

// agent/tools/star_repo.ts
import { nomineeTool } from 'nominee-eve'
import { Nominee, allow, ask, tokens } from 'nominee'
import { z } from 'zod'

const nominee = new Nominee({
  policy: {
    rules: [allow('github.star'), ask('github.delete_repo')],
    fallback: 'deny',
  },
  strategy: tokens(({ connection }) =>
    process.env[`${connection.toUpperCase()}_TOKEN`]!
  ),
  onApprovalRequest: async (req) => notifyUser(req),
})

export const starRepo = nomineeTool({
  nominee,
  user: 'user_123',
  connection: 'github',                              // fresh token → ctx.token
  action: 'github.star',                             // the name your policy matches on
  description: 'Star a GitHub repository on behalf of the user',
  inputSchema: z.object({
    repo: z.string().describe('owner/repo to star, e.g. vercel/ai'),
  }),
  execute: async ({ repo }, ctx) => {
    await fetch(`https://api.github.com/user/starred/${repo}`, {
      method: 'PUT',
      headers: { Authorization: `Bearer ${ctx.token}` },
    })
    return { starred: repo }
  },
})

Eve's defineTool is called internally — the output is fully branded and accepted by the Eve runtime.


Approvals — Portable, Not Just Eve's

ask rules (and approval: true, which forces the ask even when the policy allows) route through nominee's approval engine — resolve them from Slack, push, a webhook, or a native strategy flow like Auth0 CIBA. Denials throw ApprovalDeniedError before the tool runs, and land on the receipt chain:

export const deleteFile = nomineeTool({
  nominee,
  user: 'user_123',
  connection: 'drive',
  approval: true,                   // ⏸ pauses until a human approves
  action: 'drive.delete',
  description: 'Delete a file from Google Drive',
  inputSchema: z.object({ fileId: z.string() }),
  execute: async ({ fileId }, ctx) => {
    // Only runs after explicit human approval
    return await driveDelete(fileId, ctx.token)
  },
})

Eve's own durable interactive consent still works alongside: pass eveApproval: always() (or once(), never(), or a custom policy from eve/tools/approval) and it is forwarded to Eve's approval field, independent of nominee's portable gate. The older needsApproval adapter option remains as a deprecated alias.


What happens on ask

ask rules (and approval: true) route through nominee.run(). If a human settles the approval inline within the request, the tool runs right away. If the approval outlives the request, execute throws ActionPendingError with a durable actionId instead of hanging — the tool never runs. Catch it, persist the actionId and the original input (the durable action record stores only an input hash), then resume later with resolveActionApproval()resumeAction()executeCapability(). An Eve-native eveApproval gate is independent of this portable path and still applies on top of it. Full walkthrough: Approvals that outlive the request.


withNominee — Shared Defaults

import { withNominee } from 'nominee-eve'

const nomineeTool = withNominee(nominee, {
  user: 'user_123',
})

export const tool1 = nomineeTool({ ... })
export const tool2 = nomineeTool({ ... })

Tool Context

execute: async (input, ctx) => {
  ctx.token     // string — fresh token for the configured connection (if any)
  ctx.user      // string — the resolved principal
  ctx.eve       // raw Eve tool context (session, getToken, requireAuth, …)
}

user can be a fixed id or a function of the Eve context: (ctx) => ctx.session.userId.


Eve Agent Structure

my-agent/
  agent/
    tools/
      star_repo.ts     ← nomineeTool() here
      delete_file.ts
  lib/
    nominee.ts         ← shared Nominee instance (policy + strategy)