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

intervene-cli

v1.0.2

Published

Intervene routes approvals, decisions, and notifications from coding agents to the messaging provider on your phone

Readme

Intervene

An escalation daemon and MCP server that bridges coding agents and messaging providers, letting you monitor and control autonomous coding sessions from your phone.

Inspired by SebastienMelki/escalate.

Why Intervene?

Without Intervene, running an autonomous coding agent often means one of two things:

Sitting at your computer watching. The agent stops every few minutes to ask for permission — "Can I run this Bash command?", "Can I write this file?" You're glued to your screen, clicking Approve over and over. You can't step away for coffee, take a walk, or do anything else. You're basically a human rubber stamp.

Using remote sessions. Remote agent sessions let you check back later. But there's a catch: when the agent hits a decision point, it just waits. Silently. You have no idea it's blocked until you manually check in. If it needs permission at minute 3 of a 30-minute task, the remaining 27 minutes are wasted. There's no notification, no ping, no way to know.

With Intervene, you get a third option. Start the agent on a big task, put your phone in your pocket, and walk away. When it actually needs you — a permission approval, a decision about approach, a failure that needs attention — your phone buzzes with a message. You glance at it, tap Approve, and the session keeps going. The rest of the time: silence.

What it looks like

  1. You kick off a task: intervene codex
  2. The agent works autonomously — reading files, planning, writing code
  3. It needs to run rm -rf old-auth/ → your phone buzzes
  4. You see: "PreToolUse: Bash" with the command and context
  5. You tap Approve → the agent continues instantly
  6. Later, the run finishes and you get a session summary

That's it. You were making lunch the whole time.

How It Works

Agent Adapter / MCP Client ──> Intervene Daemon / MCP Server ──> Provider API ──> Your Phone
                                       │                                          │
                                  SQLite store  <──────── link tap/reply ─────────┘
                                       │
Agent Adapter / MCP Client <───────────┘
  1. Agent adapters send escalation requests into Intervene.
  2. Intervene stores state locally and routes the request to the configured provider.
  3. Provider adapters send Block Kit messages, bot messages, or signed approval links.
  4. You respond by tapping a button, replying in-chat, or opening a signed link.
  5. Intervene hands the response back to the agent adapter or MCP client.

Claude still works through its plugin hooks. Codex has two paths:

  • intervene codex for native Codex approval mirroring
  • plain MCP tool usage for generic request_human_approval

Prerequisites

  • Node.js >= 22
  • A messaging provider account such as Slack, Telegram, Teams, Email, or WhatsApp
  • Claude Code, Codex, or another MCP-capable agent runtime

Providers

Intervene currently supports:

  • Slack via Incoming Webhooks and signed approval links
  • Telegram via bot messages and signed approval links
  • Microsoft Teams via Adaptive Cards with signed approval links
  • Email via SMTP with signed approval links
  • WhatsApp Cloud API via signed approval links

Use the CLI to scaffold provider-specific config:

intervene init slack
intervene init telegram
intervene init --non-interactive teams
intervene init --list-providers

The command writes intervene.config.json plus a matching .env template for the selected provider. It also writes project-scoped MCP config for Codex in .codex/config.toml and a generic .mcp.json for agents that read standard MCP config files.

Agent Runtimes

Intervene currently supports three integration styles:

  • Claude Code via plugin hooks
  • Codex via intervene codex, which mirrors Codex's native approval prompts into your provider
  • Generic MCP-capable agents via the request_human_approval MCP tool

The core service stays the same in both cases. Agent-specific logic is just the adapter on the front side.

Slack Setup

Create or reuse a Slack Incoming Webhook for the target channel. Intervene posts messages to that webhook and uses signed approval links that route back through Intervene's own HTTP bridge.

Installation

Install globally from npm:

npm install -g intervene-cli

Or clone and build locally:

git clone https://github.com/PeterHdd/intervene.git
cd intervene
pnpm install
pnpm build

Running Intervene

Run Intervene as a local daemon if you want the shared core without attaching a client:

intervene daemon

This starts the local HTTP bridge, provider adapter, and SQLite state store without attaching stdio MCP transport.

For Claude Code, load the plugin:

claude --plugin-dir /path/to/intervene

For Codex, the recommended path is:

intervene codex

That command starts Intervene, starts a Codex app-server proxy, and mirrors native Codex approval prompts into your configured provider.

If you only want generic MCP tool access, intervene init also writes project-scoped MCP configuration automatically. In that mode, you can still run:

codex

Codex will auto-start Intervene for that project as an MCP server. Intervene exposes request_human_approval, which sends the request through Slack/Telegram/Teams/Email/WhatsApp and waits for a human response. That MCP path is useful for generic human-in-the-loop questions, but it does not replace Codex's native approval system. intervene codex is the path that mirrors native approvals like command execution prompts.

Configuration

Environment Variables

Set these in your shell or .env (never commit secrets):

export INTERVENE_RESPONSE_SIGNING_SECRET="replace-with-a-random-secret"

Optional (only needed for voice note transcription):

export INTERVENE_OPENAI_API_KEY="sk-..."       # OpenAI API key for Whisper

Config File

The fastest path is:

intervene init slack

If you want to create the file manually, use:

Create intervene.config.json in your project root:

{
  "provider": "slack",
  "server": {
    "publicBaseUrl": "https://intervene.example.com"
  },
  "slack": {
    "webhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/replace-me"
  }
}

webhookUrl is the Slack Incoming Webhook URL for the channel that should receive escalation messages. server.publicBaseUrl must be a public HTTPS URL that can receive approval link traffic from your phone.

Other providers use the same root file with a different provider field and provider-specific block:

{
  "provider": "telegram",
  "telegram": {
    "chatId": "123456789"
  }
}
{
  "provider": "teams",
  "server": {
    "publicBaseUrl": "https://intervene.example.com"
  },
  "teams": {
    "webhookUrl": "https://outlook.office.com/webhook/..."
  }
}

Register as a Claude Code Plugin

claude --plugin-dir /path/to/intervene

Or add to your project's .claude/plugins.json.

Connect from Codex

Codex stores MCP config in .codex/config.toml for trusted projects. intervene init updates that file automatically with an intervene MCP server entry pointing at Intervene's local server/main.js. It also writes .mcp.json so other MCP-capable agents can reuse the same project configuration.

For native Codex approval mirroring, use:

intervene codex

For plain MCP tool access, use:

codex

Inside Codex, Intervene should appear as an active MCP server. The agent can then call request_human_approval whenever it needs a real human decision. For native command or permission prompts, prefer intervene codex.

Releases

GitHub Actions now handles:

  • ci.yml for typecheck, test, and build on pushes and pull requests
  • release.yml for npm publishing on GitHub release publication

To publish successfully, set the NPM_TOKEN repository secret in GitHub and publish a GitHub release.

Smoke Tests

Use these before trusting a provider in day-to-day work.

Local provider smoke test

  1. Run intervene init <provider> in a throwaway project.
  2. Confirm intervene.config.json, .env, .codex/config.toml, and .mcp.json were written.
  3. Start the agent path you actually plan to use:
    • Claude: claude --plugin-dir /path/to/intervene
    • Codex native approvals: intervene codex
    • Generic MCP agent: run the agent normally and confirm intervene appears in its MCP list
  4. Trigger an approval request:
    • Claude: ask for a dangerous file or shell action
    • Codex native: ask Codex to open a file in Finder or run a gated shell command
    • Generic MCP: ask the agent to call request_human_approval
  5. Verify the provider receives the message.
  6. Approve or deny from the provider.
  7. Verify the agent resumes with the correct decision.

Same-laptop signed-link smoke test

If you are testing signed approval links locally on one machine:

  1. Set server.port to a fixed value, for example 8787.
  2. Set server.publicBaseUrl to http://127.0.0.1:8787.
  3. Set INTERVENE_RESPONSE_SIGNING_SECRET in .env.
  4. Start the agent session.
  5. Confirm the bridge is up with:
curl http://127.0.0.1:8787/health
  1. Click the approval link from the same laptop.

For phone-based testing, publicBaseUrl must be a public HTTPS URL that resolves back to the laptop.

Testing Strategy

Intervene needs three layers of testing:

  1. Unit tests

    • message formatting
    • signature generation and verification
    • Claude hook output translation
    • Codex native approval mapping
  2. Local integration tests

    • HTTP bridge routes
    • store resolution
    • provider adapter payload generation
    • signed-link approval roundtrips against a local bridge
  3. Real-provider smoke tests

    • Slack webhook channel
    • Telegram bot chat
    • Teams webhook
    • email inbox
    • WhatsApp test recipient

The practical way to automate the third layer is to use dedicated test destinations and a retryable smoke runner that:

  • starts Intervene in a temp project
  • triggers a known approval event
  • polls the provider-side test destination or callback path
  • resolves the approval
  • verifies the agent resumes

For most teams, that should run in CI only for sandbox providers or on a scheduled staging machine with real credentials, not on every local test run.

What Gets Intervened

| Event | What Happens | Your Options | |-------|-------------|--------------| | PermissionRequest | The agent needs permission for an action | Approve / Deny | | PreToolUse | Dangerous tool (Bash, Write, Edit) about to run | Approve / Deny | | Stop | The agent wants to end the session | Stop / Continue | | PostToolUseFailure | A tool failed (notification only) | Acknowledged |

Architecture

intervene/
├── src/adapters/
│   ├── claude/                   # Claude hook adapter + output translation
│   └── codex/                    # Codex native approval bridge + app-server proxy
├── .claude-plugin/plugin.json    # Claude plugin manifest
├── hooks/hooks.json              # Claude hook registration
├── scripts/                      # Thin hook dispatchers (<50 lines each)
│   ├── on-permission-request.ts
│   ├── on-pre-tool-use.ts
│   ├── on-stop.ts
│   ├── on-post-tool-failure.ts
│   └── lib/
│       ├── bridge-client.ts      # Shared HTTP client for hook scripts
├── src/
│   ├── config/                   # Zod-validated config loading
│   ├── state/                    # SQLite escalation store
│   ├── server/
│   │   ├── mcp-server.ts         # MCP server for generic MCP agents
│   │   ├── http-bridge.ts        # Shared HTTP bridge for hooks and signed replies
│   │   ├── runtime.ts            # Shared escalation runtime helpers
│   │   └── index.ts              # Daemon / server entrypoint
│   ├── slack/
│   │   ├── adapter.ts            # SlackAdapter (Incoming Webhook + signed links)
│   │   └── blocks.ts             # Block Kit message builder
│   ├── providers/                # Telegram/Teams/Email/WhatsApp adapters
│   └── types/                    # Shared TypeScript types
└── test/                         # Vitest test suite

The important split is:

  • src/adapters/claude: translates Claude hook events into Intervene escalations and back into Claude hook JSON.
  • src/adapters/codex: intercepts Codex native approval requests and resolves them through Intervene.
  • src/server + src/providers: shared core used by every agent adapter.

Development

# Run tests
pnpm test

# Watch mode
pnpm test:watch

# Type check
pnpm typecheck

# Lint
pnpm lint

# Format
pnpm format

License

MIT -- see LICENSE for details.

Contributing

See CONTRIBUTING.md for guidelines.