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

reactive-context-toolkit

v1.2.1

Published

Readme

reactive-context-toolkit

A zero-dependency Claude Code hook library that reactively injects context into AI sessions based on configurable rules, events, and file references.

What It Does

RCT runs as a Claude Code hook handler. It reads an rct.config.{json,ts,js} in your project and, on each hook event, decides what context to add to Claude's prompt — or whether to block a tool call entirely.

  • Context injection — inject file contents (XML or JSON) into Claude's additionalContext based on event and match conditions
  • Rules — block or warn when Claude attempts a matched tool use
  • Language ecosystem — auto-surface bun scripts, pixi tasks, cargo info, and tsconfig path aliases per language
  • Per-language testing — run test suites per language with configurable brief formatting and caching
  • Stale detection — flag dated files that have gone out of date
  • Plugins — declarative plugins contribute files and rules; custom extensions use createHook()
  • Auto-derivationrct init detects your stack and writes a fully-populated config; rct update re-derives while preserving overrides

Getting Started

bun add github:zaynram/reactive-context-toolkit
bunx rct init

rct init runs an interactive wizard that detects your project stack (Node/Python/Rust), writes an rct.config.json with all derived values explicit, and patches .claude/settings.json with the required hook commands. Use --yes for non-interactive mode (CI, Docker, scripts).

RCT has zero production dependencies — Bun resolves the bin field directly to source, no build step.

Updating

bunx rct update

Re-derives config from your project, merges with existing config preserving your overrides, and updates settings. Uses a stored _derived baseline for three-way merge.

Configuration

rct.config.json (or .ts / .js):

{
    "globals": { "format": "xml", "plugins": ["track-work"], "minify": true },
    "files": [
        {
            "alias": "scope",
            "path": "dev/scope.xml",
            "injectOn": "SessionStart",
            "staleCheck": { "dateTag": "date", "wrapTag": "stale-scope" }
        }
    ],
    "rules": [
        {
            "on": "PreToolUse",
            "match": { "target": "file_path", "pattern": "\\.env$" },
            "action": "block",
            "message": "Do not read .env files"
        }
    ],
    "lang": {
        "node": {
            "tools": [{ "name": "bun", "scripts": true }],
            "test": { "command": "bun test", "brief": "{lang}: {status}" }
        },
        "rust": { "tools": [{ "name": "cargo" }], "test": { "command": "cargo test" } }
    },
    "test": { "injectOn": "SessionStart", "cache": true, "cacheTTL": 300 }
}

Config sections

| Section | Purpose | | ------------ | -------------------------------------------------------------------------------------------------- | | globals | Format (xml|json), wrapper tag, briefByDefault, minify, plugins | | files | Register files with aliases; injectOn auto-creates injection entries | | injections | Explicit injection rules with event/match/file filtering | | rules | Block or warn on matched tool use | | lang | Per-language declarations (node/python/rust) with tools, config, test | | test | Top-level test defaults (injectOn, cache, cacheTTL); per-language overrides in lang.*.test | | meta | Inject a summary of the config itself |

Languages

RCT supports three language ecosystems: node (TypeScript + JavaScript), python, rust. The node language auto-discovers tsconfig.json / jsconfig.json if config is omitted.

Hook Events

SessionStart · PreToolUse · PostToolUse · PostToolUseFailure · UserPromptSubmit · SubagentStart · Notification · Setup

Match System

Rules and injections use a match condition system:

  • Targets: file_path, new_string, content, command, user_prompt, tool_name, error
  • Operators: regex (default), contains, equals, not_contains, starts_with, ends_with, glob
  • Multiple conditions = AND logic; multiple patterns within a condition = OR logic

FileRef Syntax

Inject references use the pattern alias[:metaAlias][~brief]:

  • scope — full content of the scope file
  • scope~brief — brief/summary mode
  • scope:changelog — a meta-file attached to scope

Plugins and Extensions

Plugins are declarative — they contribute files[] and rules[] to the RCT pipeline.

Extensions are imperative — custom hook scripts using createHook() or the low-level standard/dynamic/block helpers.

Built-in plugins

{ "globals": { "plugins": ["track-work", "issue-scope"] } }
  • track-work — registers chores (dev/chores.xml) and plans (.claude/plans/index.xml)
  • issue-scope — registers scope (.claude/context/scope.xml, with stale check) and candidates (.claude/context/issues.xml)

Custom plugins

Place plugin files at .claude/hooks/rct/*.{ts,js} or install as npm packages:

import { definePlugin } from 'reactive-context-toolkit'

export default definePlugin({
    name: 'my-plugin',
    files: [
        { alias: 'guidelines', path: 'docs/guidelines.md', injectOn: 'SessionStart' },
    ],
    rules: [
        {
            on: 'PreToolUse',
            match: { target: 'file_path', pattern: '\\.sql$' },
            action: 'warn',
            message: 'Check with DBA',
        },
    ],
})

Plugins can also provide dynamic behavior and lifecycle hooks:

export default definePlugin({
    files,
    // Scaffold files on first use
    setup() {
        for (const f of files) {
            if (!fs.existsSync(f.path)) fs.copyFileSync(template, f.path)
        }
    },
    // Inject dynamic context on SessionStart
    context(event) {
        if (event === 'SessionStart') return '<status>all systems go</status>'
    },
    // Block or warn on specific tool usage
    trigger(event, input) {
        if (input.toolName === 'DangerousTool')
            return { action: 'block', message: 'Not allowed' }
    },
})

name is optional — derived from the package name with rct-plugin- prefix stripped.

Plugin resolution: built-in name → local file (./ prefix) → package name.

Self-briefing

Use meta to brief Claude on what RCT provides at session start:

{
    "meta": {
        "injectOn": "SessionStart",
        "include": ["files", "rules", "plugins"],
        "brief": true
    }
}

Custom extensions

import { createHook } from 'reactive-context-toolkit'

createHook(async input => {
    return { hookSpecificOutput: { additionalContext: 'Hello from my hook' } }
})

Public API

RCT exports a barrel at src/index.ts for programmatic use:

import {
    // Config
    loadConfig,
    validateConfig,
    desugarFileInjections,
    applyPlugins,
    buildFileRegistry,
    deriveFromProject,
    // Engine
    evaluateRules,
    evaluateInjections,
    evaluateMatch,
    evaluateCondition,
    generateMeta,
    composeOutput,
    // Lang
    evaluateLang,
    // Test
    resolveTestCommand,
    resolveLangTestCommand,
    runTest,
    formatTestResult,
    // Library (extensions)
    definePlugin,
    createHook,
    standard,
    dynamic,
    block,
    // Utilities
    fs,
    xml,
    normalize,
    minify,
    condense,
    // Plugin
    pluginRegistry,
    displayName,
} from 'reactive-context-toolkit'
import type {
    RCTConfig,
    RCTPlugin,
    HookEvent,
    LangTestConfig,
    FileRef,
    RuleEntry,
    InjectionEntry,
    MatchCondition,
} from 'reactive-context-toolkit'

All engine and config functions are composable — consumers can build custom pipelines by importing and chaining them directly.