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

@kubeopencode/opencode-slack-plugin

v0.1.7

Published

OpenCode plugin that connects to Slack via Socket Mode — zero port exposure, runs inside your OpenCode process

Readme

opencode-slack-plugin

OpenCode plugin that connects to Slack via Socket Mode. Run it as part of your opencode serve process — zero port exposure, no separate bot process needed.

Architecture

Your machine (MacBook / Linux / K8s Pod)
+----------------------------------------------+
|  opencode serve                               |
|    +-- plugins/                               |
|          +-- opencode-slack-plugin             |
|                |                              |
|                |  WebSocket (outbound only)    |
|                v                              |
|          Slack Socket Mode API                |
|                                               |
|          Zero ports exposed                   |
+----------------------------------------------+
  • The plugin runs inside the OpenCode process
  • Connects to Slack via Socket Mode (outbound WebSocket, no public URL)
  • Each Slack thread maps to an independent OpenCode session
  • Tool call progress and permission requests are forwarded to Slack in real time

Setup

1. Create a Slack App

  1. Go to api.slack.com/apps and click Create New App > From scratch
  2. Enable Socket Mode (sidebar > Socket Mode > toggle ON)
    • Generate an App-Level Token with scope connections:write
    • Copy the xapp-... token — this is your SLACK_APP_TOKEN
  3. Add Bot Token Scopes (sidebar > OAuth & Permissions > Scopes):
    • chat:write
    • app_mentions:read
    • channels:history
    • groups:history
    • im:history
  4. Subscribe to Bot Events (sidebar > Event Subscriptions > toggle ON):
    • app_mention
    • message.im
  5. Enable App Home > Messages Tab (check "Allow users to send Slash commands and messages from the messages tab")
  6. Install to Workspace and copy the xoxb-... Bot Token — this is your SLACK_BOT_TOKEN

2. Install the Plugin

From npm

Add to your opencode.json:

{
  "plugin": ["@kubeopencode/opencode-slack-plugin"]
}

Local install

Copy the built output or the source file into your OpenCode plugins directory:

# Option A: copy source directly
cp src/index.ts ~/.config/opencode/plugins/opencode-slack.ts

# Option B: build and copy dist
npm run build
cp dist/index.js ~/.config/opencode/plugins/opencode-slack.js

Then add dependencies to ~/.config/opencode/package.json:

{
  "dependencies": {
    "@slack/socket-mode": "^2.0.5",
    "@slack/web-api": "^7.13.0"
  }
}

3. Configure Environment Variables

export SLACK_BOT_TOKEN=xoxb-your-bot-token
export SLACK_APP_TOKEN=xapp-your-app-token

4. Run OpenCode

TUI mode (interactive terminal — plugin loads automatically):

opencode

Serve mode (headless server — plugin loads on first request):

opencode serve uses lazy instance loading — plugins only initialize when the first HTTP request arrives for a project directory. In KubeOpenCode, the Kubernetes StartupProbe (GET /session/status) triggers this automatically. For local testing, send a warmup request manually:

# Start the server
opencode serve &

# Send a warmup request to trigger plugin loading
sleep 1 && curl -s "http://127.0.0.1:4096/session/status?directory=$(pwd)" > /dev/null

# The server is now running with Slack connected.
# Look for "[slack-plugin] Slack Socket Mode connected" in the output.

The plugin activates automatically when both SLACK_BOT_TOKEN and SLACK_APP_TOKEN are set. If either is missing, the plugin silently skips initialization.

Usage

  • DM the bot directly for private conversations
  • @mention the bot in a channel to start a threaded conversation
  • Each Slack thread creates a separate OpenCode session with its own context

Permission Requests

When OpenCode needs permission (e.g., to write a file), the request is forwarded to the Slack thread:

Permission Request
write file
Pattern: src/index.ts

1. Yes (once)
2. Always
3. No (reject)

Reply: 1/y/yes, 2/always, or 3/n/no

Reply with the corresponding number or keyword.

Tool Updates

Completed tool calls are posted to the thread in real time:

*file_write* - wrote src/index.ts
*bash* - ran tests

Debugging

Log Locations

The plugin produces two categories of logs:

| Source | Location | Contents | |--------|----------|----------| | OpenCode structured log | ~/.local/share/opencode/log/ | Session lifecycle, LLM calls, tool execution, permission events, errors. File per startup, 10 most recent retained. | | Plugin console output | OpenCode process stdout/stderr | [slack-plugin] prefixed messages: connection status, session creation, typing indicators, prompt results. |

To find the current log directory:

opencode debug paths   # prints all paths including "log"

On macOS the default is ~/.local/share/opencode/log/. On Linux it follows $XDG_DATA_HOME/opencode/log/.

Investigating a Failed Slack Message

When a Slack message gets no reply, follow this sequence:

1. Find the session ID — look for [slack-plugin] Created session in stdout, or find the session by thread timestamp:

grep "Slack thread" ~/.local/share/opencode/log/2026-05-08T*.log

2. Trace the session in the structured log — search for the session ID to see the full lifecycle:

grep "ses_XXXXX" ~/.local/share/opencode/log/2026-05-08T*.log

Key events to look for:

| Log entry | Meaning | |-----------|---------| | service=session ... created | Session was created successfully | | service=session.prompt step=0 loop | LLM prompt loop started | | service=llm ... stream | LLM call initiated | | service=llm ... stream error | LLM call failed (check error= field) | | service=session.processor ... error= | Processor crashed while handling LLM response | | service=session.prompt ... exiting loop | Prompt completed normally | | service=permission ... evaluated | Permission was auto-resolved or user-replied |

3. Check for LLM provider errors — filter for ERROR level:

grep "ERROR.*ses_XXXXX" ~/.local/share/opencode/log/2026-05-08T*.log

Common Failure Modes

Bot shows "is thinking..." but never replies:

The plugin's session.prompt() returned data with no text parts. This happens when the LLM provider fails. Check the structured log for stream error — common causes:

  • OAuth token expired (Google Vertex): POST https://oauth2.googleapis.com/token fails. Fix: gcloud auth application-default login
  • Proxy misconfiguration: The LLM provider's HTTP client inherits http_proxy/https_proxy env vars. If your proxy is down, LLM calls fail silently.
  • Rate limiting: Look for HTTP 429 in the error JSON.

Bot creates a session but the second message in the thread is ignored:

The thread requires @mention for each message in channel threads (by design — prevents capturing human-to-human conversation). DMs do not require @mention.

"Session idle" appears in stdout but no Slack message:

This means session.prompt() completed but returned empty text parts. Search the structured log for ERROR entries on that session ID to find the root cause.

Enabling Verbose Logging

# Print logs to stderr instead of file (useful for local debugging)
opencode serve --print-logs

# Set log level to DEBUG for maximum detail
opencode serve --log-level DEBUG

KubeOpenCode Integration

When running inside a KubeOpenCode Agent, the plugin additionally:

  • Heartbeat: Patches the kubeopencode.io/last-connection-active annotation to prevent standby auto-suspend while Slack conversations are active
  • Graceful shutdown: Disconnects cleanly when the OpenCode server is disposed

Deploy via the Agent spec:

apiVersion: kubeopencode.io/v1alpha1
kind: Agent
metadata:
  name: my-agent
spec:
  plugins:
    - name: "opencode-slack-plugin"
  credentials:
    - secretRef:
        name: slack-credentials   # Secret with SLACK_BOT_TOKEN and SLACK_APP_TOKEN

The heartbeat requires AGENT_NAME and AGENT_NAMESPACE env vars (auto-injected by the controller) and a ServiceAccount with RBAC permission to patch Agent resources. If any of these are missing, heartbeat is silently disabled.

Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | SLACK_BOT_TOKEN | Yes | Bot User OAuth Token (xoxb-...) | | SLACK_APP_TOKEN | Yes | App-Level Token for Socket Mode (xapp-...) | | AGENT_NAME | No | KubeOpenCode Agent name (for heartbeat, auto-injected) | | AGENT_NAMESPACE | No | KubeOpenCode Agent namespace (for heartbeat, auto-injected) |

How It Differs from @opencode-ai/slack

| | This plugin | @opencode-ai/slack | |---|---|---| | Architecture | Runs inside OpenCode process | Separate Node.js process | | Communication | Internal function calls (no HTTP) | HTTP to OpenCode server | | Deployment | Just opencode serve | Must run bot + server separately | | Port exposure | Zero | OpenCode server port (at least localhost) | | Install | Add to opencode.json plugins | bun run packages/slack | | K8s heartbeat | Yes (prevents standby auto-suspend) | No | | Graceful shutdown | Yes (listens for server.instance.disposed) | No |

License

MIT