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

@ironbee-ai/cli

v0.46.0

Published

The CLI for IronBee — Verification and Intelligence Layer for Agentic Development

Readme


IronBee ensures that AI agents verify their code changes before completing a task. When an agent edits code, it cannot finish until it exercises the affected paths through real tools — in the browser for frontend changes, against the wire protocol (HTTP / gRPC / GraphQL / WebSocket) for any-runtime backend changes, or via the Node.js V8 inspector for Node-specific backend changes — and submits a passing verdict.

No more "it should work" — every change is tested.

IronBee also tracks every verification cycle — coding time, fix time, pass/fail rates, problematic files — and links each activity to the pull request(s) and issues the work belongs to, so verification data is attributable to an issue rather than an opaque session id.

Powered by IronBee DevTools (@ironbee-ai/devtools), which runs in three modes from the same package:

  • Browser mode (bdt_* tools, default-on): the agent navigates pages, clicks buttons, fills forms, takes screenshots, checks console errors.
  • Backend mode (bedt_* tools, opt-in, runtime-agnostic): the agent drives real HTTP / gRPC / GraphQL / WebSocket calls against your backend, inspects logs, and queries databases — works for Node, Java, Python, Go, Rust, Ruby, .NET, PHP, Elixir, Kotlin, and Scala backends alike.
  • Node mode (ndt_* tools, opt-in): the agent connects to a running Node process, sets V8 probes (tracepoint / logpoint / exceptionpoint) at the changed code paths, exercises them, and reads back snapshots or runtime logs.

A single Stop hook can drive multiple cycles in parallel — touching frontend, a backend protocol, and a Node runtime in the same change requires evidence for each before the task can complete.

Demo

https://github.com/user-attachments/assets/9d4e602b-6c05-4b48-89a8-3df429d10e00

Supported Clients

| Client | Status | |--------|--------| | Claude Code | Supported | | Cursor | Supported | | Codex | Planned | | OpenCode | Planned |

Quick Start

Install IronBee globally

npm install -g @ironbee-ai/cli

Set up a project

cd your-project
ironbee install

This auto-detects your AI client and writes:

  • Hook configuration (so the client calls IronBee automatically)
  • Verification skill/rules (so the agent knows the workflow — covers every enabled cycle)
  • MCP server entries from the same @ironbee-ai/devtools package (IronBee DevTools), per-cycle gated — only currently enabled cycles get an entry:
    • browser-devtools (PLATFORM=browser, bdt_ prefix) — registered on first install (browser is the default-on cycle); strip with ironbee browser disable
    • backend-devtools (PLATFORM=backend, bedt_ prefix) — only after ironbee backend enable
    • node-devtools (PLATFORM=node, ndt_ prefix) — only after ironbee node enable
  • Permissions matching the registered entries (mcp__browser-devtools__*, plus mcp__backend-devtools__* and/or mcp__node-devtools__* once their cycles are enabled)

Optional: opt out of the browser cycle

ironbee browser disable

The browser cycle is the default-on cycle — every code-file edit (40+ extensions: .ts, .tsx, .css, .html, .py, .go, .java, …) requires browser-driven verification (navigate / screenshot / aria / console). Run browser disable for projects where you don't want browser-cycle enforcement (e.g. backend-only services where only backend enable / node enable apply). With browser off, an enabled node / python / backend cycle switches from its server-layout defaults to its language's broad glob (**/*.{ts,js,…} / **/*.py / multi-language) — browser's globs were the wide net, and without them a desktop app / CLI / library would match no cycle; install and <cycle> enable warn when an enabled cycle matches no tracked file. It writes browser.verifyPatterns: [] to override the legacy 40+ extension default; customizations of alwaysRequired / evidencePaths / additionalVerifyPatterns are preserved.

To re-enable: ironbee browser enable — strips the verifyPatterns: [] override so the code defaults (legacy 40+ extension list) flow back in at runtime. config.json stays minimal; the default list is NOT materialized into the file (it lives in code and tracks the CLI version automatically).

Optional: enable runtime-agnostic backend protocol verification

ironbee backend enable

Activates the backend protocol cycle — drives real HTTP / gRPC / GraphQL / WebSocket calls against your running backend service via the backend-devtools MCP (bedt_* tools) and verifies the responses. Works for any backend runtime: Node, Java, Python, Go, Rust, Ruby, .NET, PHP, Elixir, Kotlin, Scala. The command writes a minimal { "backend": {} } block to config — code defaults (multi-language paths covering server/**, api/**, routes/**, controllers/**, handlers/**, services/**; the broad multi-language **/*.{…} glob when the browser cycle is disabled) flow in at runtime.

To revert: ironbee backend disable (drops the block clean if no customizations / lower-layer override; otherwise hard-kills via verifyPatterns: []).

Optional: enable Node.js runtime debug verification

ironbee node enable

Run this once per project whose backend is Node.js and you want IronBee to gate at the runtime level (V8 inspector probes via node-devtools). It writes a minimal { "node": {} } block to config — code defaults (e.g. server/**, pages/api/**, **/server.{ts,js,mjs,cjs}; the broad **/*.{ts,tsx,js,jsx,mjs,cjs} glob when the browser cycle is disabled) flow in at runtime; nothing is materialized into the file. From then on, edits to matching paths require Node-cycle verification (connect + probes/logs) alongside any browser-cycle verification. To customize, set node.verifyPatterns (replaces defaults) or node.additionalVerifyPatterns (appends).

The node cycle is independent of the backend cycle — backend drives the wire protocol from outside, while node attaches to a Node.js process and sets non-blocking debug probes. Both can be enabled simultaneously; both must pass.

To revert: ironbee node disable. With no customizations the entire node block is dropped (clean config). With customizations or a lower-layer override, writes verifyPatterns: [] (hard kill, preserves alwaysRequired / evidencePaths / additionalVerifyPatterns so re-enabling later restores your tuned setup).

Optional: monitoring-only mode (no enforcement)

ironbee verification disable

Turns off enforcement but keeps the telemetry path intact. Session lifecycle and tool-call events still flow to the IronBee Collector, but the agent never sees a verify-gate, skill, rule, or /ironbee-verify command — useful when you want observability without slowing the agent down. To re-enable: ironbee verification enable.

The toggle re-renders all client artifacts (hooks, skill, rule, MCP servers, permissions) atomically. The change takes effect on the next agent session — restart your editor / agent after toggling.

Cursor: additional setup

Cursor requires manual activation of MCP servers after install:

  1. Restart Cursor to load the new hooks and MCP config
  2. Go to Settings → Tools & MCP and verify each registered IronBee server is enabled — browser-devtools is always present on a default install; backend-devtools appears after ironbee backend enable; node-devtools appears after ironbee node enable
  3. If a server shows as enabled but tools are unavailable, toggle it off and on

Note: This is a known Cursor limitation — MCP servers added via mcp.json may need manual activation.

That's it

The next time your AI agent edits code, IronBee will require verification before the task can complete — browser cycle for frontend changes, backend cycle for runtime-agnostic protocol calls (if enabled), Node cycle for Node.js runtime debug (if enabled), or any combination in parallel.

Commands

ironbee install [project-dir] [--client <name>] [--all]   Set up hooks and config; --all → batch across every registered project
ironbee uninstall [project-dir] [--client <name>] [--all] [-y]   Remove hooks and config; --all → batch wipe across every registered project (destructive, prompts unless --yes)
ironbee update                                    Update IronBee CLI to the latest version (npm self-update)
ironbee tui [area]                                Interactive full-screen TUI — browse & drive everything (config / platforms / projects / sessions / scenarios / queue). See docs/tui.md
ironbee status [project-dir]                      Show verdict status for active sessions
ironbee session view [--session <id>] [--json]    One session's live verification state — edits waiting, the running cycle, verdict, evidence
ironbee verify run web [--url <url>|--port <n>] [--prompt <text>]   Run a real verification job through the IronBee API (--port opens a reverse tunnel to a local app)
ironbee verify run api [--url <url>|--port <n>] [--prompt <text>]   Same, for a deployed API: verified by calling it, with no browser
ironbee verify status <job-id> [--watch] [--json]   Read a verification job's status and verdict
ironbee verify cancel <job-id> [reason]           Ask a verification job to stop
ironbee verdict [session-id]                      Validate a local session verdict file (dry-run of the Stop hook checks)
ironbee browser <enable|disable>   [-g|--local] [--client <name>]   Manage the browser cycle (default-on; bdt_* tools via browser-devtools)
ironbee backend <enable|disable>   [-g|--local] [--client <name>]   Manage the runtime-agnostic backend protocol cycle (HTTP/gRPC/GraphQL/WS via backend-devtools)
ironbee node <enable|disable>      [-g|--local] [--client <name>]   Manage the Node.js runtime debug cycle (V8 inspector probes via node-devtools)
ironbee verification <enable|disable> [-g|--local] [--client <name>]   Master verification toggle (enable = enforce; disable = monitoring-only, no enforcement but sessions/tools still ship to collector)
ironbee config get   <key>         [-g|--project|--local]   Read a config value (default: merged effective value; flags narrow to one of the three layers)
ironbee config set   <key> <value> [-g|--local] [--client <name>] [--no-rerender] [--json] [--apply-all|--no-apply-all]   Write a config value; auto re-renders client artifacts on artifact-affecting keys; -g writes global, --local writes project-local (gitignored)
ironbee config unset <key>         [-g|--local] [--client <name>] [--no-rerender] [--apply-all|--no-apply-all]   Remove a config value (idempotent); same target / rerender rules as set
ironbee config list                [-g|--project|--local]   Print the entire config (merged / global / project / local)
ironbee config path                [-g|--local]   Print the on-disk path of the targeted config file (project default; -g for global, --local for project-local)
ironbee register   [-p <dir>]   Add this project (path) to the user-home inventory (no artifact writes)
ironbee unregister [-p <dir>]   Remove this project from the user-home inventory (no artifact writes)
ironbee queue status [--session <id>]             Queue status per session (counts, recent dead-letter errors)
ironbee queue drain  [--session <id>]             Synchronously drain pending snapshots
ironbee queue dead-letter list|stats|retry|clear  Inspect / retry / clear dead-letter entries

Verification jobs (ironbee verify)

ironbee verify runs a real verification: it creates a job through the IronBee API, an agent verifies the target — a web application in a cloud browser (web), or an API by calling it (api) — and the command reports the verdict.

# A deployed URL
ironbee verify run web --url https://pr-42.preview.example --prompt "check the checkout flow"

# An application with no public URL — a dev machine, or a CI runner.
# The port is reached through a reverse tunnel this command holds open for the run.
ironbee verify run web --port 3000 --prompt "check the checkout flow"

# An API: HTTP / GraphQL / gRPC / WebSocket, called directly. Same --url / --port
# choice and the same header flags; the run may reach only the hosts it is told about.
ironbee verify run api --url https://pr-42.preview.example --prompt "check the orders endpoints"

The credential and the endpoint come from ironbee login; IRONBEE_ACCESS_TOKEN / IRONBEE_API_KEY / IRONBEE_API_URL override them for CI. The credential is never a command-line argument — an argument is visible in the process table to every other process on the machine.

How a run ends. When the verification finishes, the run environment closes the tunnel with a close frame that says so, and the command stops without reconnecting. If the frame is lost — a killed environment, an intermediary that drops the connection — the command falls back to the job's own status, and reconnects meanwhile; either way the verdict is the same.

Detached use. --no-wait creates the job and prints its id; read it back later with ironbee verify status <job-id> (--watch to follow it, --json for the raw body). --no-wait is refused for --port: a tunnel target is reachable only while this command is holding the tunnel open.

Exit codes, which is what a merge gate reads:

| Code | Meaning | |------|---------| | 0 | the verdict passed | | 1 | the verdict failed, the run errored, or it verified nothing (not_applicable) | | 2 | cancelled — including Ctrl-C, which asks the service to stop the job | | 3 | verify status only: the job has not reached a verdict yet |

Repository binding. The run is bound to the repository automatically, so the agent checks the code out and reads the changeset. The derivation is conservative: a commit no remote has seen is skipped with a warning rather than sent, because it would fail at the agent's checkout after the job had already been charged. A dirty working tree still binds, with a warning that the run reads HEAD from GitHub rather than what is on disk. Override with --commit / --base / --pr, or turn it off with --no-repo.

| Flag | Meaning | |------|---------| | --prompt <text> / --prompt-file <path> | what to verify (- reads the prompt from stdin) | | --project <name> | project the results attach to; derived from the git remote by default | | --url <url> / --port <n> | the target — exactly one | | --header <name:value> | request header, --url targets only (repeatable) | | --name <text> / --timeout <seconds> | job name and run timeout | | --json | print the finished job on stdout and nothing else; on a failure that produced no job, print {"error": {status, code, message, details?}} instead | | --queue-wait <s> / --app-wait <s> | give up waiting for the job to start / the local port to accept |

Exit codes: 0 only for a passing verdict, 2 for a cancelled job, 3 for verify status on a job with no verdict yet, 1 for everything else — including a failing verdict and every error. A caller that has to tell those apart reads the --json failure body: error.code is the API's own code, and the absence of id is what distinguishes the failure shape from a job body.

ironbee verdict is a different thing and reaches no service: it validates the verdict file a local in-editor session wrote, the way the Stop hook would.

Projects inventory

ironbee install records each project it touches in ~/.ironbee/projects.json; ironbee uninstall removes it. The inventory powers two cross-project workflows:

  • ironbee install --all — explicit batch op that re-runs install on every registered project. Use after a global config change to propagate it everywhere; uses each project's currently detected clients (or pass --client <name> to override).
  • ironbee uninstall --all — destructive batch op that wipes ironbee from every registered project. Prompts with default-No before acting; pass --yes / -y to skip the prompt. Refuses without --yes in non-interactive contexts.
  • Prompt on global config writes — ironbee config set <key> <val> -g (and unset) on an artifact-affecting key (collector, verification, browser, backend, node, browserDevTools, backendDevTools, nodeDevTools) lists up to 10 other registered project paths still on the prior state and asks Apply this change to these N projects now? [Y/n] (default Yes). Pass --apply-all / --no-apply-all to skip the prompt; non-TTY contexts skip it and print a hint pointing at install --all.

For pure inventory bookkeeping (no artifact writes):

  • ironbee register — adds the current project to the inventory. Useful for projects set up before this feature existed.
  • ironbee unregister — removes the current project from the inventory. Works on already-deleted project dirs.

Agent Commands (slash commands)

IronBee installs slash commands that the agent can use inside Claude Code or Cursor:

| Command | Description | |---------|-------------| | /ironbee-verify | Verify changes — focused on affected areas (default) | | /ironbee-verify full | Full verification — complete visual + functional + accessibility checklists | | /ironbee-verify visual | Visual-only — contrast, layout, spacing, fonts, images, theming | | /ironbee-verify functional | Functional-only — clicks, forms, navigation, data flow, error handling |

/ironbee-verify guides the agent through a systematic verification process. The default mode focuses on what changed, while full runs every checklist item. Use visual or functional to narrow the scope when you know what type of testing is needed.

In-app view (Claude Code)

On Claude Code 2.1.287+ IronBee also draws its view of the session inside Claude Code, so a verification that runs in the background sub-agent is something you can watch:

  • A line above the prompt — what is waiting to be verified, the running cycle with each platform's progress (IronBee ● checkout flow · browser 3/4 · node ✓ · 0:42), then the verdict (✓ verified · 5 checks / ✗ failed · 2 issues · round 1/3) or why the gate blocked. A scenario run shows the same way: its progress while it runs, then its result (✓ scenario checkout passed · 12 assertions).
  • /ironbee — a pane with the cycle's steps on every platform, what the gate still wants, the verdict with its issues, the captured screenshots and files, and a scenario run's steps. Each screenshot is a row that unfolds its picture in the pane — real pixels in kitty / Ghostty, a low-resolution preview in every other terminal — and a letter next to each item opens it outside the terminal (o the unfolded screenshot at full size, t the run in the IronBee console).

It is a view only: verification works exactly the same without it. It is rendered per machine into .claude/skills/ironbee/ (gitignored) by ironbee install; turn it off with ironbee config set claude.mod.enable false and re-run ironbee install. ironbee session view prints the same view in any terminal.

Configuration

IronBee loads config from three layers and deep-merges them in order (each later layer overrides the earlier ones), then layers env-var overrides on top:

  1. Global — ~/.ironbee/config.json
  2. Project — <project>/.ironbee/config.json (committed; team-shared)
  3. Project-local — <project>/.ironbee/config.local.json (gitignored; per-machine / per-developer override)
  4. Env-var overrides — selected IRONBEE_* env vars (e.g. IRONBEE_API_KEY → collector.apiKey); env always wins over every file layer. See Env-var overrides below.

The local layer is optional — ironbee install adds .ironbee/config.local.json to .gitignore automatically, but the file is only created when you actually write to it (e.g. ironbee config set ... --local).

{
  "ignoredVerifyPatterns": ["*.test.ts", "*.spec.ts"],
  "maxRetries": 5,

  "browser": {
    "verifyPatterns": ["*.ts", "*.tsx", "*.css"],
    "additionalVerifyPatterns": ["*.mdx"]
  },

  "backend": {
    "verifyPatterns": ["routes/**/*.{go,py,java,ts}", "controllers/**/*.{go,py,java}"]
  },

  "node": {
    "verifyPatterns": ["server/**/*.ts", "pages/api/**/*.ts"]
  },

  "verification": {
    "enable": false
  },

  "fileChange": {
    "captureChangeset": true
  }
}

| Key | Description | Default | |-----|-------------|---------| | browser.verifyPatterns | Glob patterns for files requiring browser verification (replaces defaults). Four-state semantic: block-absent → code defaults (40+ ext, default-on); block-present + verifyPatterns unset → code defaults (post-browser enable shape); [] → hard kill (also disables additionalVerifyPatterns); custom [...] → user-defined. | 40+ code extensions when block absent OR verifyPatterns unset | | browser.additionalVerifyPatterns | Extra browser patterns appended to defaults | [] | | backend.verifyPatterns | Glob patterns activating the runtime-agnostic backend protocol cycle (backend-devtools MCP, bedt_* tools — HTTP / gRPC / GraphQL / WebSocket). Same four-state semantic, default-off: block absent → cycle disabled; block present + verifyPatterns unset → 13 default patterns from code (multi-language: routes/**, controllers/**, handlers/**, services/** across .ts/.js/.py/.go/.java/.rb/.cs/.rs/.kt/.scala/.ex/.exs/.php/.clj); [] → hard kill; custom [...] → user-defined. Opt in via ironbee backend enable. | block absent → disabled; block present + unset → 13 code defaults | | backend.additionalVerifyPatterns | Extra patterns appended to backend.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns: []. | [] | | backend.alwaysRequired | Backend-cycle required tools (all-of). Empty default — backend uses any-of evidence paths. | [] | | backend.evidencePaths | Alternative tool paths — at least one must be fully satisfied. Defaults: protocol-call (any bedt_request_*) OR log-evidence (bedt_log_register-source AND any read/follow) OR db-evidence (bedt_db_connect AND any inspect tool). | protocol-call OR log-evidence OR db-evidence | | node.verifyPatterns | Glob patterns activating the Node.js runtime debug cycle (node-devtools MCP, ndt_* tools — V8 inspector probes). Same four-state semantic as browser.verifyPatterns, but default-off: block absent → cycle disabled; block present + verifyPatterns unset → 9 default patterns from code (server/**, pages/api/**, **/server.{ts,js,mjs,cjs}, …); [] → hard kill; custom [...] → user-defined. Opt in via ironbee node enable. | block absent → disabled; block present + unset → 9 code defaults | | node.additionalVerifyPatterns | Extra patterns appended to node.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns: []. | [] | | node.alwaysRequired | Node-cycle required tools (all-of) | ["ndt_debug_connect"] | | node.evidencePaths | Alternative tool paths — at least one must be fully satisfied | probe path + log path | | ignoredVerifyPatterns | Patterns to exclude from verification (checked first, applies to all cycles) | [] | | maxRetries | Max retry attempts before allowing completion (single global counter regardless of how many cycles run) | 3 | | verification.enable | Master switch for enforcement. Inverse semantics from recording/jobQueue/collector — verification is the core feature, opt-out via enable: false. When disabled, ironbee runs in monitoring-only mode (no enforcement hooks, skill, rule, or MCP servers; only session/activity/tool_call telemetry flows to the collector). | true | | fileChange.captureChangeset | When true, every file_change event carries a hunks-only unified-diff changeset string (@@ headers + space/-/+ lines, no filename header — file_path already lives on the parent event). Off by default — the default tool_input whitelist deliberately strips file content from the wire; turning this on routes content through file_change instead. PreToolUse pre-reads the file when enabled so PostToolUse can produce a real before/after diff (Write/Edit on Claude; Write/StrReplace/Delete on Cursor). Skipped on binary content (NUL byte in first 4 KB). | false | | fileChange.maxChangesetBytes | Hard cap on the changeset string size. Diffs over the cap are sliced on a UTF-8 byte boundary and end with a \n... (truncated, N bytes omitted)\n footer so the collector POST stays within typical reverse-proxy body limits. | 65536 (64 KB) |

Editing config from the CLI (ironbee config)

You can edit any of the three config layers via the CLI instead of hand-rolling JSON:

# Read the effective (merged) value across all three layers
ironbee config get collector.url

# Write to project config (default — committed, team-shared)
ironbee config set collector.url https://collector.example.com
ironbee config set maxRetries 5
ironbee config set verification.enable false
ironbee config set browser.verifyPatterns '["*.ts", "*.tsx", "*.css"]'

# Write to global config (~/.ironbee/config.json)
ironbee config set collector.apiKey sk-... --global

# Write to project-local config (<project>/.ironbee/config.local.json — gitignored, per-machine)
ironbee config set collector.url http://localhost:4000 --local

# Remove a value (idempotent — no-op if absent)
ironbee config unset collector.url            # project layer
ironbee config unset collector.url --local    # local layer

# Inspect (default reads merged effective; flags narrow to a single layer)
ironbee config list                # merged effective config across all three layers
ironbee config list --global       # global file only
ironbee config list --project      # project file only
ironbee config list --local        # project-local file only
ironbee config path                # print the project config file path
ironbee config path --local        # print the project-local config file path

Target flags are mutually exclusive: pass at most one of -g/--global, --project (read-only — --project is the default for writes), or --local.

Type coercion — set parses the value as JSON when it can (true/42/[…]/{…}) and falls back to a raw string when JSON parse fails. URLs and paths pass through unquoted; pass --json to force strict JSON parsing (e.g. when you want the literal string "42" instead of the number 42).

Smart artifact re-render — when a top-level key affects installed client artifacts (verification, telemetry, collector, browser, backend, node, browserDevTools, backendDevTools, nodeDevTools), set and unset re-render the client files (hooks, MCP entries, skill, rule, permissions) automatically — same code path verification enable / backend enable / node enable use. Other keys (maxRetries, recording, jobQueue, vcs, ignoredVerifyPatterns) are pure config flips that the next agent session picks up — no rerender needed.

Pass --no-rerender to skip the rerender on artifact-affecting keys (handy for scripted bulk edits — follow up with ironbee install to resync). If a rerender fails midway, the config file is rolled back to its prior bytes so disk state never diverges from installed artifacts.

Restart your editor / agent session after changing artifact-affecting keys — the host caches hook config at session start, so the new state takes effect on the next run.

Env-var overrides

A small allowlist of IRONBEE_* env vars overrides specific config paths on top of the three file layers. Useful for secrets that shouldn't be committed (CI runners, ephemeral shells, multi-env desktop setups). Set to a non-empty string to override; unset or empty-string falls back to the file value. Env always wins over every file layer.

| Env var | Config path | Notes | |---|---|---| | IRONBEE_API_KEY | collector.apiKey | Lets CI / per-shell setups supply the collector API key without committing it. Combined with a file-set collector.url, the merged effective config has both required fields. |

# Use a one-shot key for this shell only
export IRONBEE_API_KEY=sk-...
ironbee config get collector.apiKey         # returns the env value (merged read)
ironbee config get collector.apiKey --project   # returns only what's in the project file (env bypassed)

Layer-specific reads (--global / --project / --local) bypass env overrides and show only what's on disk in that layer. The default merged read surfaces the env value when set, so it always reflects what the runtime will actually use.

ironbee config set / unset warn when the targeted path is shadowed by a live env override — the file write still succeeds, but the operator's value won't take effect until the env var is unset.

Default verify patterns

By default, the browser cycle is enabled and matches common code file extensions: .ts, .tsx, .js, .jsx, .css, .scss, .html, .py, .go, .rs, .java, .vue, .svelte, and many more (DEFAULT_BROWSER_VERIFY_PATTERNS). Backend file edits trigger browser verification by default since they often affect frontend behavior. Run ironbee browser disable for projects where the browser-cycle gate isn't appropriate (e.g. backend-only services); ironbee browser enable re-enables.

Patterns are NOT materialized into config.json — they live in the CLI source (DEFAULT_BROWSER_VERIFY_PATTERNS / DEFAULT_BACKEND_VERIFY_PATTERNS / DEFAULT_NODE_VERIFY_PATTERNS) and flow in at runtime when the cycle block exists without an explicit verifyPatterns key. Keeps config.json minimal AND lets defaults track CLI updates automatically (no frozen-at-install-time drift). To customize, set the explicit <cycle>.verifyPatterns (replaces defaults) or <cycle>.additionalVerifyPatterns (appends).

The backend cycle is opt-in via ironbee backend enable and is runtime-agnostic (drives wire protocols via backend-devtools). The node cycle is opt-in via ironbee node enable (only meaningful for Node.js backends — node-devtools is a V8 inspector wrapper).

Non-code files like README.md, package.json, or .gitignore do not trigger any cycle.

Devtools MCP server config

IronBee can register up to three MCP server entries from the same @ironbee-ai/devtools package (IronBee DevTools) — browser-devtools (bdt_ prefix, browser mode), backend-devtools (bedt_ prefix, runtime-agnostic backend mode), and node-devtools (ndt_ prefix, Node mode). Each is per-cycle gated (only enabled cycles get an entry) and can be customized independently via its own config block.

For the browser server, use browserDevTools:

{
  "browserDevTools": {
    "mcp": {
      "url": "http://localhost:4000/mcp"
    }
  }
}

For the backend server, use backendDevTools:

{
  "backendDevTools": {
    "env": { "BACKEND_DEFAULT_HOST": "http://localhost:8080" }
  }
}

For the node server, use nodeDevTools:

{
  "nodeDevTools": {
    "env": { "NODE_INSPECTOR_HOST": "127.0.0.1" }
  }
}

You can mix-and-match: full config replacement via mcp, or just env-var additions via env. The two blocks below combine — one uses mcp for full replacement on the browser server, the other adds env vars to the backend server:

{
  "browserDevTools": {
    "mcp": {
      "command": "node",
      "args": ["./my-server.js"],
      "env": { "MY_VAR": "value" }
    }
  },
  "backendDevTools": {
    "env": { "OTEL_ENABLE": "true" }
  }
}

| Key | Description | |-----|-------------| | browserDevTools.mcp / backendDevTools.mcp / nodeDevTools.mcp | Full MCP server config — used as-is when provided. Supports command+args (stdio) or url (HTTP) | | browserDevTools.env / backendDevTools.env / nodeDevTools.env | Extra env vars merged into the default config. Only used when mcp is not provided |

Note: IronBee always sets TOOL_NAME_PREFIX (bdt_ / bedt_ / ndt_), TOOL_INPUT_METADATA_ENABLE=true, and PLATFORM (browser / backend / node) — these cannot be overridden. When collector is configured, an OTEL exporter env block is also auto-injected on every server entry; operators can override individual OTEL_* keys via the env block above.

Verification Flow (multi-cycle)

When the agent tries to complete a task, IronBee runs these checks:

  1. Were code files edited? — If no matching files were changed, the agent completes normally.
  2. Which cycles are active? — IronBee matches each edited file against browser.verifyPatterns and (if you opted in) backend.verifyPatterns and/or node.verifyPatterns. A single file may activate two or three cycles; they all run in parallel and pass/fail combine with AND.
  3. Were the cycle's required tools used?
    • Browser cycle: navigate, screenshot, accessibility snapshot, console check (all-of)
    • Backend cycle: at least one evidence path must be fully exercised — protocol-call (any one of bedt_request_http / bedt_request_grpc / bedt_request_graphql / bedt_request_websocket-open / bedt_request_replay), OR log-evidence (bedt_log_register-source AND any one of bedt_log_read / bedt_log_read-multi / bedt_log_follow), OR db-evidence (bedt_db_connect AND any one of bedt_db_query / bedt_db_describe-table / bedt_db_list-tables / bedt_db_snapshot / bedt_db_diff / bedt_db_get-changes)
    • Node cycle: connect; then either probe path ((put-tracepoint | put-logpoint | put-exceptionpoint) AND get-probe-snapshots) OR log path (get-logs)
  4. Does a verdict exist? — The agent must submit a single verdict via ironbee hook submit-verdict.
  5. Is the verdict valid? — Required: status ∈ {pass, fail} + checks (non-empty array). On fail, issues is required; on pass-after-fail, fixes is required.
  6. Pass or fail? — Server-derived pass criteria from tool_call records is currently a no-op stub (TODO — see verify-gate.ts). For now status: "pass" is honored as-is. When evidence extractors land, per-cycle pass criteria (zero console errors, probe triggered, evidence path exercised) will be derived from the agent's tool_calls and override status: pass to fail when criteria don't hold.
  7. Retry limit — After maxRetries failed attempts (default 3, single global counter), the agent is allowed to complete but must report unresolved issues.

Verdict format

Verdicts are platform-agnostic — the same minimal shape regardless of which cycles (browser / backend / node / multi-cycle) ran. Structural evidence (pages tested, console error counts, endpoints called, log sources, DB connections, probe snapshots, …) is intentionally NOT part of the verdict — the gate (will) derive it from the tool_call records of your bdt_* / bedt_* / ndt_* invocations, so the agent cannot misreport it.

Submit via echo '<json>' | ironbee hook submit-verdict:

{
  "session_id": "<your-session-id>",
  "status": "pass",
  "checks": ["form submits successfully", "new item appears in list"]
}

On failure, include an issues array describing what went wrong:

{
  "session_id": "<your-session-id>",
  "status": "fail",
  "checks": ["form renders", "submit button unresponsive"],
  "issues": ["button click handler not firing", "TypeError in console"]
}

On pass after a previous fail, include a fixes array describing what was fixed:

{
  "session_id": "<your-session-id>",
  "status": "pass",
  "checks": ["form submits successfully", "new item appears in list"],
  "fixes": ["reattached click handler to submit button", "fixed TypeError in event handler"]
}

Multi-cycle (e.g. browser + backend + node all active in the same turn): same single verdict. Cycles are derived from the file_changes you made; pass criteria for each is derived from your tool_calls.

The agent must submit a verdict after every verification attempt — both pass and fail. File edits are blocked until a verdict is submitted after using devtools tools.

Session Isolation

Each AI session gets its own directory under .ironbee/sessions/<session-id>/:

.ironbee/sessions/<session-id>/
  actions.jsonl    # Event log (file edits, tool calls, verification markers)
  verdict.json     # Current verdict (cleared on code edit)
  state.json       # Session state (retries, activeVerificationId, activeTraceId,
                   #                lastVerdictStatus, activeFixId, activeActivityId,
                   #                phase, active, recordingRequired, recordingActive,
                   #                userEmail, usageType, usagePlan)
  session.log      # Debug log
  queue/           # File-backed job queue (jobs.jsonl, dead-letter.jsonl, worker.log)

This means parallel sessions (e.g., multiple Claude Code instances) don't interfere with each other.

VCS & issue attribution

When a collector is configured, IronBee links each activity's commit to the pull request(s) it belongs to and to the issues the work is attributed to (GitHub closing issues plus tracker keys — e.g. Jira — mined from branch names, commit messages, PR titles, and the agent's own tracker lookups). One vcs_link event per activity ships to the collector, re-emitted under the same deterministic id whenever the resolution improves (a PR opened later, an issue status change) — so a session's verification data is attributable to an issue rather than an opaque session id. Only structural signals cross the wire (repo / branch / refs / titles — never code). Opt out with vcs.enable: false.

Telemetry

IronBee collects anonymous usage data to help improve the product. No source code, file contents, or personally identifiable information is ever sent.

Events collected: install/uninstall, session start, verdict submissions (pass/fail status only), and verification gate decisions.

To opt out, set the environment variable:

export IRONBEE_TELEMETRY=false

Or set telemetryEnabled: false in ~/.ironbee/telemetry.json.

Development

Requires Node.js ≥ 22 (Node 20 hit EOL on 2026-04-30).

npm install
npm run build       # tsc + scripts/copy-assets.js (mirrors .md/.mdc + assets/ to dist/)
npm run lint        # ESLint
npm run test        # Jest (unit + integration + client tests)
npm run dev         # Run via ts-node

CI runs the full test suite across linux × x64/arm64, darwin (Apple Silicon), and windows × x64/arm64 with Node 22 and 24. The build script is pure Node (no bash) so npm run build produces identical output on every OS.

License

Elastic License 2.0 (ELv2) — free to use, copy, modify, distribute, and embed in your own products. The only restriction is that you may not offer IronBee itself (or a substantially similar derivative) as a hosted or managed service to third parties.