fix(rkd): run the bot only in the session started as a channel #2

Merged
dozken merged 1 commit from fix/channel-only-in-channel-sessions into main 2026-09-19 19:53:17 +02:00
Owner

Summary

Once installed, the plugin's MCP server starts in every Claude Code session, and each one took the single-session lock and connected as the bot. Opening any ordinary session would kill the real channel session's server, connect as the bot where channel messages never reach the model (so triggers vanished), and rotate the refresh token underneath the channel session. Found while setting up the local walkthrough: an unrelated session on this Mac was already holding bot.pid. The Telegram channel plugin behaves the same way, which likely explains its disconnect earlier today.

Part of nanoya-biz/rkd#917.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup (no user-visible change)
  • UI / UX
  • Build, CI, or tooling
  • Docs

Test plan

Automated:

  • pnpm test: 95 passed. New channel-mode.test.ts covers the flag forms (--channels, =, comma lists, @inline, server:plugin:rkd:, the versioned binary path), non-matches (other plugins, rkd-extra, --plugin-dir alone, a shell -c script that mentions the flag, a non-claude process), the ancestor walk through a wrapper, maxDepth and the RKD_CHANNEL override
  • pnpm typecheck, pnpm check:dist, claude plugin validate --strict rkd, handshake smoke
  • Integration test against a local rkd-server: 8/8 (it now sets RKD_CHANNEL=1, since its parent is vitest)

Manual, with a configured bot (claude_code_bot on a local server):

  • Started from a plain shell: status says connected: no / idle: this Claude Code session was not started with the rkd channel…, and no bot.pid is written
  • claude -p --plugin-dir rkd --dangerously-load-development-channels plugin:rkd@inline: status says connected: yes, as claude_code_bot
  • Found and fixed on the way: the first version also matched a shell whose -c script contained the flag text. Now only the claude binary's own arguments count

Review checklist

  • No console.log / dbg! / commented-out code left behind
  • No secrets, tokens, or personal URLs added
  • README updated

Notes for the reviewer

Claude Code sends the same initialize (same capabilities and env) whether or not the server was loaded as a channel. I checked both with a probe plugin under 2.1.278, so the launching command line is the only signal. It walks up to 4 ancestors with ps, which is fine on macOS and Linux. The Claude desktop app, or a future settings-based way to enable channels, wouldn't show the flag: RKD_CHANNEL=1 covers that. Version bumped to 0.1.1 so installed copies pick it up.

https://claude.ai/code/session_01GdkP2Y3vcxcGz5XCFFWW16

## Summary Once installed, the plugin's MCP server starts in every Claude Code session, and each one took the single-session lock and connected as the bot. Opening any ordinary session would kill the real channel session's server, connect as the bot where channel messages never reach the model (so triggers vanished), and rotate the refresh token underneath the channel session. Found while setting up the local walkthrough: an unrelated session on this Mac was already holding `bot.pid`. The Telegram channel plugin behaves the same way, which likely explains its disconnect earlier today. Part of nanoya-biz/rkd#917. ## Type of change - [x] Bug fix - [ ] New feature - [ ] Refactor / cleanup (no user-visible change) - [ ] UI / UX - [ ] Build, CI, or tooling - [x] Docs ## Test plan Automated: - [x] `pnpm test`: 95 passed. New `channel-mode.test.ts` covers the flag forms (`--channels`, `=`, comma lists, `@inline`, `server:plugin:rkd:`, the versioned binary path), non-matches (other plugins, `rkd-extra`, `--plugin-dir` alone, a shell `-c` script that mentions the flag, a non-claude process), the ancestor walk through a wrapper, maxDepth and the `RKD_CHANNEL` override - [x] `pnpm typecheck`, `pnpm check:dist`, `claude plugin validate --strict rkd`, handshake smoke - [x] Integration test against a local `rkd-server`: 8/8 (it now sets `RKD_CHANNEL=1`, since its parent is vitest) Manual, with a configured bot (`claude_code_bot` on a local server): - [x] Started from a plain shell: `status` says `connected: no` / `idle: this Claude Code session was not started with the rkd channel…`, and no `bot.pid` is written - [x] `claude -p --plugin-dir rkd --dangerously-load-development-channels plugin:rkd@inline`: `status` says `connected: yes, as claude_code_bot` - [x] Found and fixed on the way: the first version also matched a shell whose `-c` script contained the flag text. Now only the `claude` binary's own arguments count ## Review checklist - [x] No `console.log` / `dbg!` / commented-out code left behind - [x] No secrets, tokens, or personal URLs added - [x] README updated ## Notes for the reviewer Claude Code sends the same `initialize` (same capabilities and env) whether or not the server was loaded as a channel. I checked both with a probe plugin under 2.1.278, so the launching command line is the only signal. It walks up to 4 ancestors with `ps`, which is fine on macOS and Linux. The Claude desktop app, or a future settings-based way to enable channels, wouldn't show the flag: `RKD_CHANNEL=1` covers that. Version bumped to 0.1.1 so installed copies pick it up. https://claude.ai/code/session_01GdkP2Y3vcxcGz5XCFFWW16
fix(rkd): run the bot only in the session started as a channel
All checks were successful
CI / rkd-plugin (pull_request) Successful in 33s
bcb9552c49
Once installed, the plugin's MCP server starts in every Claude Code
session. Each one took the single-session lock, killing the real
channel session's server, and connected as the bot in a session that
never delivers channel messages to the model: triggers vanished, and
the refresh token rotated underneath the channel session.

Claude Code doesn't say in initialize whether a server was loaded as a
channel, so read the launching claude command line (walking up through
wrappers) for plugin:rkd@… in --channels or the development flag. Only
the claude binary's own arguments count, not a shell script that
mentions the text. Elsewhere the server stays idle: no socket, no lock,
and status explains how to start a channel session. RKD_CHANNEL=1/0
overrides the detection.

Claude-Session: https://claude.ai/code/session_01GdkP2Y3vcxcGz5XCFFWW16
dozken merged commit 6ce348b280 into main 2026-09-19 19:53:17 +02:00
dozken deleted branch fix/channel-only-in-channel-sessions 2026-09-19 19:53:18 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rkd/claude-plugins!2
No description provided.