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

@radnine/claude-session-daemon

v0.6.2

Published

Node.js daemon for managing Claude CLI sessions

Readme

@radnine/claude-session-daemon

Node.js daemon that manages Claude CLI sessions over WebSocket. Pairs with @radnine/storybook-addon-claude to give designers and developers an AI chat panel inside Storybook.

Install

npm install @radnine/storybook-addon-claude @radnine/claude-session-daemon

Configure Storybook

In your .storybook/main.js:

export default {
  addons: [
    '@radnine/storybook-addon-claude',
    // ... other addons
  ],
};

Run the Daemon

Option A: Docker (recommended)

Docker runs Claude inside a container with filesystem isolation. Claude can only access your mounted project directory, so file edits happen automatically without permission prompts.

  1. Create a docker-compose.yml in your project root:
services:
  claude-daemon:
    build:
      context: ./node_modules/@radnine/claude-session-daemon
    ports:
      - "${CLAUDE_DAEMON_PORT:-3001}:3001"
    volumes:
      - .:/workspace
    environment:
      - ANTHROPIC_API_KEY
      - CLAUDE_DAEMON_MODE=standalone
      - CLAUDE_WORKING_DIR=/workspace
      - CLAUDE_DAEMON_PORT=3001
      - CLAUDE_SKIP_PERMISSIONS=true
      - CLAUDE_DISABLE_AUTH=true
    stop_grace_period: 10s
    restart: unless-stopped
  1. Add your API key to a .env file:
ANTHROPIC_API_KEY=sk-ant-...

Get an API key from https://console.anthropic.com/settings/keys

  1. Start it:
docker compose up -d

Stop with docker compose down.

Option B: Host mode

Runs the daemon directly on your machine. Claude will prompt for permission on each file edit since there's no filesystem isolation.

npx @radnine/claude-session-daemon start

Or add to your package.json scripts:

{
  "scripts": {
    "claude-daemon": "claude-session-daemon start",
    "claude-daemon:stop": "claude-session-daemon stop",
    "claude-daemon:restart": "claude-session-daemon restart",
    "claude-daemon:status": "claude-session-daemon status"
  }
}

The daemon manages a .claude-daemon.pid file in your project root. Add it to your .gitignore.

Authentication (host mode only)

Docker mode uses the ANTHROPIC_API_KEY environment variable. For host mode, choose one:

API Key — Set ANTHROPIC_API_KEY before starting the daemon, or add it to a .env file.

Claude Login — If you have a Claude Pro, Team, or Enterprise subscription:

npx @anthropic-ai/claude-code login

This authenticates via your browser. Credentials are stored locally and the daemon uses them automatically.

WebSocket Authentication (Shared Secret)

By default, the daemon allows unauthenticated connections from localhost and auto-generates a random token for non-localhost connections (logged on startup). This works for local development but not for remote environments like GitHub Codespaces where port forwarding proxies prevent the localhost bypass.

To configure a shared secret that both the daemon and addon use:

  1. Set CLAUDE_AUTH_TOKEN for the daemon and STORYBOOK_CLAUDE_DAEMON_TOKEN for Storybook:
# Generate a secret (or use any string)
export CLAUDE_SHARED_SECRET=$(openssl rand -hex 32)

# Daemon reads this
export CLAUDE_AUTH_TOKEN=$CLAUDE_SHARED_SECRET

# Storybook addon reads this
export STORYBOOK_CLAUDE_DAEMON_TOKEN=$CLAUDE_SHARED_SECRET
  1. Inject the token into Storybook's manager frame via managerHead in your .storybook/main.js:
export default {
  addons: ['@radnine/storybook-addon-claude'],

  managerHead: (head) => {
    const port = process.env.STORYBOOK_CLAUDE_DAEMON_PORT || 3001;
    const token = process.env.STORYBOOK_CLAUDE_DAEMON_TOKEN || '';
    return `${head}<script>window.__CLAUDE_DAEMON_PORT__ = ${port};${
      token ? `window.__CLAUDE_DAEMON_TOKEN__ = "${token}";` : ''
    }</script>`;
  },
};

The addon reads the token from window.__CLAUDE_DAEMON_TOKEN__ (most reliable in the Storybook manager frame) and falls back to process.env.STORYBOOK_CLAUDE_DAEMON_TOKEN.

GitHub Codespaces

In Codespaces, each forwarded port gets its own subdomain (e.g. codespace-name-3001.app.github.dev). The addon auto-detects this URL pattern and connects via wss:// instead of ws://localhost.

Setup:

  1. Add the shared secret env vars to your devcontainer.json:
{
  "containerEnv": {
    "CLAUDE_SHARED_SECRET": "${localEnv:CLAUDE_SHARED_SECRET}"
  },
  "postStartCommand": "export CLAUDE_AUTH_TOKEN=$CLAUDE_SHARED_SECRET && export STORYBOOK_CLAUDE_DAEMON_TOKEN=$CLAUDE_SHARED_SECRET"
}

Or generate a fresh secret on every Codespace start:

{
  "postStartCommand": "export CLAUDE_SHARED_SECRET=$(openssl rand -hex 32) && export CLAUDE_AUTH_TOKEN=$CLAUDE_SHARED_SECRET && export STORYBOOK_CLAUDE_DAEMON_TOKEN=$CLAUDE_SHARED_SECRET"
}
  1. Set the daemon port to public visibility in the Codespaces Ports tab. The shared secret provides the auth layer — you don't need GitHub's proxy auth.

  2. Add the managerHead injection to your .storybook/main.js (see above).

  3. Start the daemon and Storybook as usual. The addon will automatically detect the Codespaces hostname and connect to wss://codespace-name-PORT.app.github.dev.

Custom Skills

The addon's skills bar shows configurable shortcut buttons. Define them in a YAML file at .storybook/claude-skills.yml in your project:

skills:
  - id: sync-components
    label: Sync Components
    icon: "↻"
    type: prompt
    prompt: "Synchronize all Storybook components with their Figma designs. Report what changed."
    description: "Sync components with designs"

  - id: run-tests
    label: Run Tests
    icon: "▶"
    type: slash_command
    command: /test
    description: "Run the full test suite"

  - id: audit-stories
    label: Audit
    icon: "🔍"
    type: prompt
    prompt: "Audit all components and list any that are missing Storybook stories or have outdated ones."
    description: "Find missing or outdated stories"

Each skill requires id, label, icon, and either prompt or command:

  • type: prompt (default) — sends the prompt text as a chat message
  • type: slash_command — sends the command value (e.g. /test) as a chat message
  • description — shown as a tooltip on hover; falls back to prompt if omitted

If no YAML file is found, the addon falls back to built-in default skills. The dynamic PR skill (New PR / Finalize PR) is always included regardless of config — it's driven by git context, not YAML.

The daemon looks for the YAML file relative to its working directory. By default this is process.cwd(). If you run the daemon from a different directory than your Storybook project (e.g. via a Procfile from the repo root), set CLAUDE_WORKING_DIR to point to the directory containing .storybook/:

CLAUDE_WORKING_DIR=path/to/storybook-project claude-session-daemon start

In Docker mode, CLAUDE_WORKING_DIR should point to your mounted workspace (e.g. /workspace).

Environment Variables

| Variable | Default | Description | |---|---|---| | ANTHROPIC_API_KEY | — | Required for Docker mode | | CLAUDE_WORKING_DIR | process.cwd() | Project root for skills config and git context | | CLAUDE_DAEMON_PORT | 3001 | WebSocket server port | | CLAUDE_AUTH_TOKEN | random UUID | Shared secret for WebSocket auth (see above) | | CLAUDE_MAX_SESSIONS | 10 | Max concurrent Claude sessions | | CLAUDE_LOG_LEVEL | info | Log level (debug, info, warn, error) | | CLAUDE_SKIP_PERMISSIONS | false | Skip Claude CLI permission prompts (Docker only) | | CLAUDE_DISABLE_AUTH | false | Disable WebSocket auth (Docker only) |

Addon-side variables (set when starting Storybook):

| Variable | Default | Description | |---|---|---| | STORYBOOK_CLAUDE_DAEMON_PORT | 3001 | Daemon port (or inject via window.__CLAUDE_DAEMON_PORT__) | | STORYBOOK_CLAUDE_DAEMON_TOKEN | — | Shared secret (or inject via window.__CLAUDE_DAEMON_TOKEN__) |

License

Proprietary. See LICENSE for terms.