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

@innei/kagura

v0.4.0

Published

Slack-native agent integration for Claude Agent SDK and OpenAI Codex CLI, scaffolded for local execution on macOS.

Downloads

83

Readme

🎭 Kagura

Every thread a stage, every response a dance

npm Node version TypeScript pnpm

In Japanese mythology, Ame-no-Uzume performed a divine dance before the closed doors of Amano-Iwato — the heavenly rock cave where Amaterasu had hidden herself, plunging the world into darkness. Her dance, accompanied by music and laughter, drew the sun goddess back into the world. This was the first kagura (神楽) — "the entertainment of the gods."

Kagura brings that spirit to Slack. Run Anthropic Claude Agent SDK or OpenAI Codex CLI natively in your workspace — mention the bot, a configured agent user group, or use a Message Action; Kagura routes the session into the right repository and replies with Slack-native rich text, live progress, and persistent memory.

Why

Running a coding agent inside Slack requires gluing together thread context, workspace routing, streaming UX, session persistence, and memory — all adapted to Slack's API conventions. kagura handles that full lifecycle via Socket Mode for both Claude Agent SDK and Codex CLI, so you can focus on the agent's behavior.

How it works

Slack message event / Message Action
  → ignore ordinary channel chatter
  → route direct bot mentions or configured agent user-group mentions
  → resolve target repo
  → load thread history (text + files + images)
  → run agent in repo cwd
  → stream progress → post rich-text reply and generated attachments
  → persist session & memory to SQLite

Features

Conversation — Thread-aware multimodal context (text + files + images), session resumption across restarts, layered memory (global / workspace / preferences).

Memory — On-demand save/recall for Claude and Codex through the same SQLite store, plus an optional background reconciler that prunes expired memories and deduplicates dirty buckets with an OpenAI-compatible LLM.

A2A orchestration — Mention a configured Slack user group or co-mention multiple agent apps to start a lead-coordinated Agent-to-Agent thread with explicit delegation and final summary.

Web review panel — After every workspace-bound run, Kagura posts a Slack button that opens a read-only code review UI: file tree, changed files, GitHub-style split/unified diff with expandable unmodified lines, and a Shiki-highlighted source view.

Slack UX — Rich text rendering (headings, lists, code blocks, auto-splitting), live progress indicators, reaction lifecycle, native assistant typing.

Workspace routing — Each thread binds to a repo/workdir. Auto-detected from message text, or manually chosen via Message Action.

Agent control — Pluggable provider registry, stop via stop/cancel keyword, :octagonal_sign: reaction, or message shortcut, slash commands for introspection (/usage, /workspace, /memory, /session, /version, /provider).

Operations — Auto-provisioned manifest (message events + commands + shortcuts), online-presence heartbeat, Home tab, Zod-validated inputs, secret redaction in logs.

A2A conversation mode

Kagura separates normal Slack chat from Agent-to-Agent (A2A) coordination. The Slack app subscribes to message events (message.channels, message.groups, and message.im) and filters them in process: ordinary channel messages are ignored, direct bot mentions become single-agent sessions, and configured agent user-group mentions become A2A sessions. The app no longer depends on Slack's app_mention event.

A2A mode starts when the root message either mentions a configured Slack user group, such as @agents, or co-mentions multiple configured agent apps. Slack user groups cannot contain bot users, so the user group is only the group-moment signal; the actual agent participants come from agentTeams config and any explicit agent @mentions in the same first non-empty line.

In an A2A thread, one agent is the lead. The lead owns user-facing coordination, task assignment, and the final summary. Standby agents only run when they are explicitly addressed by the user or by the lead.

Configure A2A teams in config.json:

{
  "a2a": {
    "outputMode": "quiet",
    "diagnosticsDir": "./data/a2a-diagnostics"
  },
  "agentTeams": {
    "S0123456789": {
      "name": "agents",
      "defaultLead": "U0123456789",
      "members": [
        {
          "id": "U0123456789",
          "label": "codex",
          "role": "implementation, verification, and final summary"
        },
        {
          "id": "U9876543210",
          "label": "claude",
          "role": "design review and alternate implementation"
        }
      ]
    }
  }
}

agentTeams keys are Slack user group IDs from <!subteam^S...>. defaultLead is a bot user ID. members accepts either bot user ID strings or objects with id, optional label, and optional role; labels and roles are injected into A2A prompts so agents know which peer to mention for delegation or review. Every production bot instance that should participate in the same team must load compatible agentTeams config and be present in the Slack channel where message events should be received.

Set a2a.outputMode to quiet to reduce Slack thread noise during A2A work. In quiet mode, Kagura buffers non-delegation assistant messages and posts the final message for the turn; explicit <@agent> delegation remains public so standby agents can still wake up. Buffered messages are written to a2a.diagnosticsDir as per-thread JSONL files for debugging. The default verbose mode preserves the legacy behavior.

A2A routing cases

| Case | Expected behavior | | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | Ordinary root message without bot or configured group mention | Ignored. | | Root message directly mentions one bot | Creates a normal single-agent session for that bot. | | Root message mentions @agents | Creates an A2A session; the configured/default lead runs first. | | Root message mentions @agents and explicitly mentions one agent | Creates an A2A session; the explicitly mentioned configured agent becomes lead. | | Root message co-mentions multiple agent apps | Creates an A2A session; the first mentioned/configured lead runs first, other agents stay on standby. | | User replies in the A2A thread without mentioning an agent | The lead handles the reply. | | User explicitly mentions one standby agent | That mentioned agent handles the reply. | | User explicitly mentions multiple agents | The lead handles the reply, decides whether to delegate, and may assign tasks. | | Lead explicitly mentions one or more standby agents | Mentioned standby agents run; multiple standby agents may run in parallel. | | All assigned standby agents reach completed, failed, or stopped | Kagura automatically wakes the original lead provider to post the final summary. | | Bot-authored messages in General Chat | Still ignored by default. | | Bot-authored lead messages in A2A | Allowed to trigger mentioned standby participants; self-mentions are ignored to avoid loops. |

Final summaries are driven by Kagura's execution lifecycle, not by parsing Slack prose. The summary should report successful work, failed or stopped assignments, and the user-visible conclusion.

Verified A2A live cases

The live E2E suite includes:

  • dual-agent-a2a-auto-summary: user starts with @agents; lead assigns a standby agent; standby completes; Kagura wakes the lead for a final summary.
  • dual-agent-a2a-user-reply-routing: verifies ordinary root messages are ignored, @agents root messages start the lead, user replies route correctly with no explicit agent mention, one explicit agent mention, and multiple explicit agent mentions, and a later standby agent can use prior thread history. The multi-agent reply path validates lead reply -> task dispatch -> standby completion -> lead summary.

Install

npm install -g @innei/kagura
# or: pnpm add -g @innei/kagura

Requires Node.js ≥ 24. The package ships three bins: kagura (the CLI router + wizard), kagura-app (the bot, bypassing the CLI), and kagura-memory (direct memory save/recall helper).

First run

kagura

kagura detects that no configuration exists and launches an interactive wizard:

  1. Select an AI providerclaude-code (Anthropic Claude via Claude Agent SDK) or codex-cli (OpenAI Codex via the codex CLI).
  2. Set up your Slack app
    • Create a new one — kagura opens api.slack.com/apps?new_app=1&manifest_json=… with the manifest already filled in; click Create → Install. If you have a Slack config token set, it can also call apps.manifest.create directly.
    • Reuse an existing one — paste the App ID and credentials.
    • Skip for now — a .env skeleton with commented placeholders is written so you can fill it in later.
  3. Paste tokens — Bot Token (xoxb-), App-Level Token (xapp-), and Signing Secret. Each token is live-validated against Slack's auth.test before being written.
  4. Point at your reposREPO_ROOT_DIR, e.g. ~/git.
  5. Start now — the wizard offers to launch the bot inline once everything is in place.

Re-run kagura init at any time to reconfigure.

Configuration layout

Everything lands under ~/.config/kagura/ by default. Override with $KAGURA_HOME (useful for Docker or multi-tenant installs). When invoked inside a kagura repo checkout, cwd wins so dev mode keeps working.

~/.config/kagura/
├── .env             # secrets: Slack tokens, API keys
├── config.json      # non-secret tunables: provider, model, paths, log level
├── data/
│   ├── sessions.db                 # Drizzle-managed SQLite
│   └── slack-config-tokens.json    # rotating Slack config tokens
└── logs/                           # daily logs (when LOG_TO_FILE=true)

Precedence when a key lives in more than one place: environment > config.json > built-in default. Put secrets in .env and everything else in config.json. See docs/configuration.md for the full key reference.

Example config.json:

{
  "codex": {
    "model": "gpt-5.5",
    "reasoningEffort": "medium",
    "sandbox": "danger-full-access"
  },
  "defaultProviderId": "codex-cli",
  "logLevel": "info",
  "repoRootDir": "~/git",
  "worktreeRootDir": "~/git/kagura-worktrees"
}

When agents create git worktrees, the default centralized root is REPO_ROOT_DIR/kagura-worktrees unless WORKTREE_ROOT_DIR or worktreeRootDir overrides it.

Memory

Kagura stores durable memory in SQLite and exposes it differently per provider:

  • Claude uses the in-process MCP tools save_memory and recall_memory.
  • Codex shells out to kagura-memory save and kagura-memory recall; the adapter injects the correct KAGURA_DB_PATH for the active session database.

The startup prompt only includes identity/preferences by default. Project facts, decisions, observations, and completed-task notes are recalled on demand so the prompt stays small and reconciled memory is visible without restarting the bot.

The optional background reconciler always prunes expired rows. LLM consolidation is enabled separately with KAGURA_MEMORY_RECONCILER_ENABLED=true and KAGURA_MEMORY_RECONCILER_API_KEY; BASE_URL accepts OpenAI-compatible providers. Full settings live in docs/configuration.md § Memory reconciler.

Subcommands

| Command | What it does | | -------------------------------- | ------------------------------------------------------------------- | | kagura | Run the bot; launch init wizard if config is incomplete | | kagura init | Run the onboarding wizard unconditionally | | kagura doctor | Diagnose config + connectivity; exit 0 / 1 / 2 by worst severity | | kagura doctor --json | Machine-readable report (for CI / scripts) | | kagura manifest print | Print the kagura-desired Slack manifest (no API call) | | kagura manifest export | Fetch the live manifest of your Slack app via config token | | kagura manifest sync | Push the kagura-desired manifest into your Slack app | | kagura manifest sync --dry-run | Show what would change without writing | | kagura config path | Print ~/.config/kagura/ (useful for $(kagura config path)/.env) | | kagura config path --json | Emit { configDir, envFile, configJsonFile, dbPath, logDir, … } | | kagura-memory recall | Query global or workspace memory from SQLite | | kagura-memory save | Persist a memory record from scripts or the Codex provider | | kagura --version | Print version + commit hash + commit date | | kagura --help | Show help (works on every subcommand) | | kagura-app | Run the bot directly, skipping config detection (systemd/Docker) |

Common recipes

# Diagnose why the bot won't start
kagura doctor

# Edit secrets or tunables by hand
$EDITOR "$(kagura config path)/.env"
$EDITOR "$(kagura config path)/config.json"

# Generate a manifest.json you can upload to Slack manually
kagura manifest print > manifest.json

# After changing desired scopes / commands, push to Slack
kagura manifest sync --dry-run
kagura manifest sync

Prerequisites

  • A Slack workspace where you can create apps.
  • Socket Mode enabled on the app (the manifest template does this automatically).
  • The AI CLI you picked logged in and ready:
    • Claude: run claude login first, or set ANTHROPIC_API_KEY.
    • Codex: run codex login first, or set OPENAI_API_KEY.

If something is off, kagura doctor will tell you which check failed.

Getting started (development)

git clone https://github.com/Innei/kagura.git
cd kagura
pnpm install
cp .env.example .env # fill in SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_SIGNING_SECRET, REPO_ROOT_DIR
pnpm dev             # or: pnpm build && pnpm start

Documentation

| Document | Contents | | --------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | Configuration | Environment variables, Slack manifest, token rotation, Docker | | Architecture | Composition root, agent providers, rendering, workspace routing, memory model, project structure | | Slash commands & controls | All slash commands, stop controls, reaction lifecycle | | Live E2E testing | E2E setup, environment, running scenarios | | Specs | Detailed subsystem specifications |

Scripts

| Command | Description | | ----------------------------- | ----------------------------- | | pnpm dev | Run with nodemon + tsx | | pnpm build | Compile TypeScript | | pnpm test | Run Vitest test suite | | pnpm start | Run compiled output | | pnpm typecheck | Type-check without emitting | | pnpm e2e | Run all live Slack E2E cases | | pnpm e2e -- <id> | Run a specific scenario by id | | pnpm e2e -- --interactive | Interactive scenario picker | | pnpm e2e -- --list | List all discovered scenarios | | pnpm e2e -- --search <term> | Search/filter by keyword | | pnpm db:generate | Generate Drizzle migrations | | pnpm db:migrate | Apply migrations | | pnpm db:studio | Open Drizzle Studio |

License

MIT © Innei, Released under the MIT License.

Personal Website · GitHub @Innei