@windyroad/connect 0.2.1-preview.38 → 0.3.0-preview.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,28 @@
1
1
  #!/bin/bash
2
2
  # wr-connect - SessionStart hook
3
- # Warns if env vars are configured but --channels is not active.
3
+ # Outputs collaboration primer when Discord channel is active.
4
4
  # Always exits 0 (warns, never blocks).
5
5
 
6
- # If bot token is not set, plugin is inactive exit silently
7
- if [ -z "${WR_CONNECT_BOT_TOKEN:-}" ]; then
6
+ # Check if the Discord plugin is configured (token saved)
7
+ DISCORD_ENV="$HOME/.claude/channels/discord/.env"
8
+ if [ ! -f "$DISCORD_ENV" ]; then
9
+ # Discord plugin not configured — plugin is inactive, exit silently
8
10
  exit 0
9
11
  fi
10
12
 
11
- # If --channels is active, output collaboration primer
13
+ # Check if --channels is active
12
14
  # NOTE: CLAUDE_CHANNELS is the expected env var when --channels is active.
13
15
  # This may change in future Claude Code versions; update if needed.
14
16
  if [ -n "${CLAUDE_CHANNELS:-}" ]; then
15
- SESSION_NAME="${WR_CONNECT_SESSION_NAME:-unnamed}"
17
+ # Detect session name from env var or git remote
18
+ SESSION_NAME="${WR_CONNECT_SESSION_NAME:-}"
19
+ if [ -z "$SESSION_NAME" ]; then
20
+ SESSION_NAME=$(git remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||;s|\.git$||' || echo "")
21
+ fi
22
+ if [ -z "$SESSION_NAME" ]; then
23
+ SESSION_NAME=$(basename "$PWD")
24
+ fi
25
+
16
26
  cat <<PRIMER
17
27
  wr-connect: Collaboration channel active. Your session name is "${SESSION_NAME}".
18
28
 
@@ -30,13 +40,14 @@ SENDING:
30
40
  - Use /wr-connect:send to message the channel.
31
41
  - Use @<session-name> to direct a message to a specific session.
32
42
  - Be concise — other sessions will read your messages too.
43
+ - Always prefix your replies with **${SESSION_NAME}:** so others know who sent it.
33
44
  PRIMER
34
45
  exit 0
35
46
  fi
36
47
 
37
- # Env vars set but --channels not active — warn
48
+ # Discord configured but --channels not active — warn
38
49
  cat <<'EOF'
39
- wr-connect: Environment configured but --channels is not active.
50
+ wr-connect: Discord is configured but --channels is not active.
40
51
  To enable cross-repo collaboration, restart with:
41
52
  claude --channels plugin:discord@claude-plugins-official
42
53
  EOF
@@ -1,48 +1,66 @@
1
1
  #!/usr/bin/env bats
2
2
 
3
3
  # Tests for session-start.sh (SessionStart hook)
4
- # Verifies three states: no config, config without channels, config with channels.
4
+ # Verifies: no config, config without channels, config with channels.
5
5
 
6
6
  setup() {
7
7
  SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
8
8
  HOOK="$SCRIPT_DIR/session-start.sh"
9
- # Clear env vars for each test
10
- unset WR_CONNECT_BOT_TOKEN
11
- unset WR_CONNECT_CHANNEL_ID
12
- unset WR_CONNECT_SESSION_NAME
9
+ # Set up a fake Discord config
10
+ TEST_DIR=$(mktemp -d)
11
+ export HOME="$TEST_DIR"
13
12
  unset CLAUDE_CHANNELS
13
+ unset WR_CONNECT_SESSION_NAME
14
+ }
15
+
16
+ teardown() {
17
+ rm -rf "$TEST_DIR"
14
18
  }
15
19
 
16
- @test "no env vars: exits 0, no output" {
20
+ @test "no discord config: exits 0, no output" {
17
21
  run "$HOOK"
18
22
  [ "$status" -eq 0 ]
19
23
  [ -z "$output" ]
20
24
  }
21
25
 
22
- @test "env vars set, no CLAUDE_CHANNELS: exits 0, warns about --channels" {
23
- export WR_CONNECT_BOT_TOKEN="test-token"
26
+ @test "discord configured, no CLAUDE_CHANNELS: exits 0, warns about --channels" {
27
+ mkdir -p "$HOME/.claude/channels/discord"
28
+ echo "DISCORD_BOT_TOKEN=test" > "$HOME/.claude/channels/discord/.env"
24
29
  run "$HOOK"
25
30
  [ "$status" -eq 0 ]
26
31
  [[ "$output" == *"--channels"* ]]
27
32
  [[ "$output" == *"plugin:discord@claude-plugins-official"* ]]
28
33
  }
29
34
 
30
- @test "env vars set, CLAUDE_CHANNELS active: exits 0, outputs primer with session name" {
31
- export WR_CONNECT_BOT_TOKEN="test-token"
32
- export WR_CONNECT_SESSION_NAME="repo-b"
35
+ @test "discord configured, CLAUDE_CHANNELS active: exits 0, outputs primer" {
36
+ mkdir -p "$HOME/.claude/channels/discord"
37
+ echo "DISCORD_BOT_TOKEN=test" > "$HOME/.claude/channels/discord/.env"
33
38
  export CLAUDE_CHANNELS=1
39
+ export WR_CONNECT_SESSION_NAME="test-repo"
34
40
  run "$HOOK"
35
41
  [ "$status" -eq 0 ]
36
- [[ "$output" == *"repo-b"* ]]
37
- [[ "$output" == *"@repo-b"* ]]
42
+ [[ "$output" == *"test-repo"* ]]
43
+ [[ "$output" == *"@test-repo"* ]]
38
44
  }
39
45
 
40
46
  @test "primer tells agent to prioritise @mentions" {
41
- export WR_CONNECT_BOT_TOKEN="test-token"
42
- export WR_CONNECT_SESSION_NAME="my-repo"
47
+ mkdir -p "$HOME/.claude/channels/discord"
48
+ echo "DISCORD_BOT_TOKEN=test" > "$HOME/.claude/channels/discord/.env"
43
49
  export CLAUDE_CHANNELS=1
50
+ export WR_CONNECT_SESSION_NAME="my-repo"
44
51
  run "$HOOK"
45
52
  [ "$status" -eq 0 ]
46
53
  [[ "$output" == *"@my-repo"* ]]
47
54
  [[ "$output" == *"relevant"* ]]
48
55
  }
56
+
57
+ @test "primer includes prefix instruction" {
58
+ mkdir -p "$HOME/.claude/channels/discord"
59
+ echo "DISCORD_BOT_TOKEN=test" > "$HOME/.claude/channels/discord/.env"
60
+ export CLAUDE_CHANNELS=1
61
+ export WR_CONNECT_SESSION_NAME="my-repo"
62
+ run "$HOOK"
63
+ [ "$status" -eq 0 ]
64
+ [[ "$output" == *"prefix"* ]]
65
+ [[ "$output" == *"my-repo"* ]]
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/connect",
3
- "version": "0.2.1-preview.38",
3
+ "version": "0.3.0-preview.41",
4
4
  "description": "Connect Claude Code sessions across repos via Discord (experimental)",
5
5
  "bin": {
6
6
  "windyroad-connect": "./bin/install.mjs"
@@ -1,34 +1,49 @@
1
1
  ---
2
2
  name: wr-connect:send
3
- description: Send a message to other Claude Code sessions via Discord.
4
- allowed-tools: Bash, AskUserQuestion
3
+ description: Send a message to other Claude Code sessions via the Discord channel.
4
+ allowed-tools: Bash, AskUserQuestion, mcp__plugin_discord_discord__reply, mcp__plugin_discord_discord__react, mcp__plugin_discord_discord__fetch_messages
5
5
  ---
6
6
 
7
7
  # Send Message
8
8
 
9
- Send a message from this session to other Claude Code sessions listening on the
10
- configured Discord channel.
9
+ Send a message from this session to other Claude Code sessions on the shared
10
+ Discord channel. Uses the Discord plugin's reply tool directly.
11
+
12
+ ## Prerequisites
13
+
14
+ The Discord channel plugin must be active (`--channels plugin:discord@claude-plugins-official`).
15
+ If not set up, run `/wr-connect:setup` first.
11
16
 
12
17
  ## Instructions
13
18
 
14
- ### 1. Check environment variables
19
+ ### 1. Determine the channel
15
20
 
16
- Verify these environment variables are set:
17
- - `WR_CONNECT_BOT_TOKEN`
18
- - `WR_CONNECT_CHANNEL_ID`
19
- - `WR_CONNECT_SESSION_NAME`
21
+ Check if `WR_CONNECT_CHANNEL_ID` is set:
20
22
 
21
23
  ```bash
22
- [ -n "$WR_CONNECT_BOT_TOKEN" ] && [ -n "$WR_CONNECT_CHANNEL_ID" ] && [ -n "$WR_CONNECT_SESSION_NAME" ] && echo "OK" || echo "MISSING"
24
+ echo "${WR_CONNECT_CHANNEL_ID:-NOT SET}"
23
25
  ```
24
26
 
25
- If any are missing, tell the user:
27
+ If not set, use `fetch_messages` to find the active guild channel, or ask the user
28
+ which channel to send to via AskUserQuestion.
26
29
 
27
- > wr-connect is not configured. Run `/wr-connect:setup` first.
30
+ ### 2. Determine session name
28
31
 
29
- Then stop.
32
+ Check if `WR_CONNECT_SESSION_NAME` is set:
30
33
 
31
- ### 2. Get the message
34
+ ```bash
35
+ echo "${WR_CONNECT_SESSION_NAME:-}"
36
+ ```
37
+
38
+ If not set, detect from git remote:
39
+
40
+ ```bash
41
+ git remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||;s|\.git$||'
42
+ ```
43
+
44
+ If neither works, use the current directory name.
45
+
46
+ ### 3. Get the message
32
47
 
33
48
  The message to send is provided via `$ARGUMENTS`.
34
49
 
@@ -37,34 +52,22 @@ If `$ARGUMENTS` is empty, use AskUserQuestion to ask:
37
52
  > What message would you like to send to the other session(s)?
38
53
  > To direct your message to a specific session, start with @session-name.
39
54
 
40
- ### 3. Send the message
55
+ ### 4. Send the message
41
56
 
42
- Format the message as: `[wr-connect] from: <SESSION_NAME> | <message>`
57
+ Format the message as: `**<session-name>:** <message>`
43
58
 
44
- **@mentions:** If the user's message starts with `@<name>`, preserve it as-is in the
45
- message body. This tells the target session to prioritise the message. Messages
46
- without an `@` are treated as broadcast to all listening sessions.
59
+ Use the Discord plugin's `reply` tool to send it to the channel:
47
60
 
48
- Send via the Discord API:
49
-
50
- ```bash
51
- curl -s -o /tmp/wr-connect-response.json -w "%{http_code}" \
52
- -X POST "https://discord.com/api/v10/channels/${WR_CONNECT_CHANNEL_ID}/messages" \
53
- -H "Authorization: Bot ${WR_CONNECT_BOT_TOKEN}" \
54
- -H "Content-Type: application/json" \
55
- -d "{\"content\": \"[wr-connect] from: ${WR_CONNECT_SESSION_NAME} | <MESSAGE>\"}"
61
+ ```
62
+ reply(chat_id: "<channel-id>", text: "**<session-name>:** <message>")
56
63
  ```
57
64
 
58
- Replace `<MESSAGE>` with the actual message content. Escape any double quotes in the
59
- message before inserting into the JSON payload.
65
+ **@mentions:** If the user's message starts with `@<name>`, preserve it in the
66
+ message body. This tells the target session to prioritise the message.
60
67
 
61
- ### 4. Report result
68
+ ### 5. Report result
62
69
 
63
- Check the HTTP status code returned by curl:
64
- - **200** or **201**: Message sent successfully. Report the formatted message to the user.
65
- - **429**: Rate limited. Tell the user to wait a moment and try again.
66
- - **401** or **403**: Authentication failed. Tell the user to check their bot token.
67
- - **Other**: Report the status code and response body for debugging.
70
+ Confirm the message was sent and show the formatted text.
68
71
 
69
72
  ## Examples
70
73
 
@@ -74,16 +77,16 @@ Check the HTTP status code returned by curl:
74
77
  ```
75
78
  Sends:
76
79
  ```
77
- [wr-connect] from: repo-a | BUG: Widget.parse() throws on null input at line 47
80
+ **windyroad/agent-plugins:** BUG: Widget.parse() throws on null input at line 47
78
81
  ```
79
82
 
80
83
  **Directed (specific session):**
81
84
  ```
82
- /wr-connect:send @repo-b BUG: Widget.parse() throws on null input at line 47
85
+ /wr-connect:send @bbstats please fix Widget.parse()
83
86
  ```
84
87
  Sends:
85
88
  ```
86
- [wr-connect] from: repo-a | @repo-b BUG: Widget.parse() throws on null input at line 47
89
+ **windyroad/agent-plugins:** @bbstats please fix Widget.parse()
87
90
  ```
88
91
 
89
92
  $ARGUMENTS
@@ -15,6 +15,9 @@ across different repos can communicate with zero idle token cost.
15
15
  **This is an interactive walkthrough.** Use AskUserQuestion at each step to confirm
16
16
  progress and gather details. Do NOT skip ahead — wait for the user at each checkpoint.
17
17
 
18
+ **Important:** Each repo should have its own Discord bot so sessions are
19
+ distinguishable in Discord. The bot name defaults to the org/repo from git remote.
20
+
18
21
  ## Steps
19
22
 
20
23
  ### 1. Explain and opt-in
@@ -27,10 +30,11 @@ Tell the user:
27
30
  > wasting tokens. Sessions can hand off findings, ask questions, share context, or
28
31
  > coordinate work.
29
32
  >
30
- > It works by using Discord as a message channel. You will need:
33
+ > Each repo gets its own Discord bot (so you can tell sessions apart in Discord).
34
+ > You will need:
31
35
  > - A Discord account
32
- > - A Discord bot (created in the next step)
33
- > - A private Discord server or channel
36
+ > - A Discord server with a channel for agent collaboration
37
+ > - A few minutes to create a bot in the Discord Developer Portal
34
38
 
35
39
  Use AskUserQuestion:
36
40
  - "Would you like to proceed with setting up cross-repo collaboration via Discord?"
@@ -42,201 +46,191 @@ If no:
42
46
 
43
47
  Stop — do not proceed.
44
48
 
45
- ### 2. Check for existing Discord server
49
+ ### 2. Detect bot name
50
+
51
+ Detect the org/repo from git remote to suggest a bot name:
52
+
53
+ ```bash
54
+ git remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||;s|\.git$||' | tr '/' '-'
55
+ ```
56
+
57
+ If no remote is found, use the directory name as a fallback.
58
+
59
+ Use AskUserQuestion:
60
+ - "What should the Discord bot be called? This name will appear in Discord when this session sends messages."
61
+ - Options: "<detected-name>" (e.g., "windyroad-agent-plugins") / "I want a different name"
62
+
63
+ ### 3. Check for existing Discord server
46
64
 
47
65
  Use AskUserQuestion:
48
- - "Do you already have a Discord server you'd like to use, or do you need to create one?"
66
+ - "Do you already have a Discord server for agent collaboration, or do you need to create one?"
49
67
  - Options: "I have a server" / "I need to create one"
50
68
 
51
69
  If they need to create one, guide them:
52
70
  1. Open Discord and click the **+** button in the server list
53
71
  2. Choose **Create My Own** > **For me and my friends**
54
- 3. Name it something like `dev-agents` or `wr-connect`
72
+ 3. Name it something like `dev-agents`
73
+ 4. Create a private channel (e.g., `#agent-collab`)
55
74
 
56
- ### 3. Create a Discord bot
75
+ ### 4. Create a Discord bot
57
76
 
58
- Tell the user to go to https://discord.com/developers/applications, then guide
59
- them step by step. Use AskUserQuestion after giving the instructions:
77
+ Tell the user to go to https://discord.com/developers/applications:
60
78
 
61
79
  **Instructions:**
62
- 1. Click **New Application** — name it `wr-connect`
63
- 2. Go to **Bot** > click **Add Bot** > confirm
64
- 3. Under **Token**, click **Reset Token** and copy the token
80
+ 1. Click **New Application** — name it `<detected-bot-name>` from step 2
81
+ 2. Go to **Bot** in the sidebar. Give the bot the same username.
82
+ 3. Under **Token**, click **Reset Token** and copy the token (shown once).
65
83
  4. Under **Privileged Gateway Intents**, enable:
66
84
  - **Message Content Intent** (to read message text)
67
- - **Server Members Intent** (optional — for member awareness)
68
85
  5. Go to **OAuth2 > URL Generator**:
69
86
  - Scopes: `bot`
70
- - Bot permissions: `Send Messages`, `Read Messages/View Channels`, `Add Reactions`, `Read Message History`
87
+ - Bot permissions: `View Channels`, `Send Messages`, `Send Messages in Threads`,
88
+ `Read Message History`, `Attach Files`, `Add Reactions`
89
+ - Integration type: **Guild Install**
71
90
  6. Copy the generated URL, open it in a browser, and add the bot to your server
72
91
 
73
92
  Use AskUserQuestion:
74
93
  - "Have you created the bot and copied the token?"
75
94
  - Options: "Yes, I have the token" / "I need help with a step"
76
95
 
77
- If they need help, ask which step is unclear and provide more detail.
96
+ If they need help, ask which step is unclear.
78
97
 
79
- ### 4. Get the channel ID
98
+ ### 5. Configure the Discord plugin with the token
80
99
 
81
- Tell the user:
82
- 1. In Discord, go to **User Settings > Advanced** and enable **Developer Mode**
83
- 2. Create a channel (e.g., `#agent-collab`) or pick an existing one
84
- 3. Right-click the channel and click **Copy Channel ID**
85
-
86
- Use AskUserQuestion:
87
- - "Have you copied the channel ID?"
88
- - Options: "Yes, I have the channel ID" / "I need help"
100
+ Tell the user to run the following command. **Do NOT paste the token yourself** —
101
+ the user should type it directly to avoid the token appearing in conversation history:
89
102
 
90
- ### 5. Store credentials
103
+ > Run this command, replacing `<token>` with the bot token you copied:
104
+ > ```
105
+ > /discord:configure <token>
106
+ > ```
107
+ > This saves the token securely at `~/.claude/channels/discord/.env`.
91
108
 
92
109
  Use AskUserQuestion:
93
- - "Where would you like to store the bot token and channel ID?"
94
- - Options:
95
- - ".env file (recommended)" — "Store in a .env file in the project root. The file must be in .gitignore."
96
- - "1Password CLI" — "Use `op` CLI to store secrets in 1Password and reference them via `op://`"
97
- - "Shell profile" — "Add exports to ~/.zshrc or ~/.bashrc"
98
-
99
- **If .env file:**
110
+ - "Have you run `/discord:configure` with your token?"
111
+ - Options: "Yes, token is configured" / "I need help"
100
112
 
101
- Check that `.env` is in `.gitignore`:
102
- ```bash
103
- grep -q '\.env' .gitignore 2>/dev/null && echo ".env is in .gitignore" || echo "WARNING: .env is NOT in .gitignore"
104
- ```
113
+ ### 6. Restart with channels active
105
114
 
106
- If not in `.gitignore`, warn the user and offer to add it.
107
-
108
- Use AskUserQuestion to get the values:
109
- - "Paste your bot token (from step 3):"
110
- - "Paste your channel ID (from step 4):"
111
- - "What should this session be called? (e.g., `windyroad-plugins`, `repo-a`)"
112
-
113
- Write the `.env` file (or append to it if it exists):
114
- ```
115
- WR_CONNECT_BOT_TOKEN=<token>
116
- WR_CONNECT_CHANNEL_ID=<channel-id>
117
- WR_CONNECT_SESSION_NAME=<session-name>
118
- ```
115
+ Tell the user:
119
116
 
120
- **If 1Password CLI:**
117
+ > You need to restart Claude Code with the channels flag to connect to Discord:
118
+ > ```
119
+ > claude --channels plugin:discord@claude-plugins-official
120
+ > ```
121
+ > The Discord plugin won't connect without this flag.
121
122
 
122
- Check if `op` is available:
123
- ```bash
124
- command -v op && echo "1Password CLI available" || echo "1Password CLI not found"
125
- ```
123
+ Use AskUserQuestion:
124
+ - "Have you restarted with `--channels`? (If we're in a new session, just confirm)"
125
+ - Options: "Yes, restarted" / "Not yet I'll do it after setup"
126
126
 
127
- Guide the user to create a vault item and reference it:
128
- ```bash
129
- op item create --category=API\ Credential --title="wr-connect" \
130
- 'bot_token=<token>' \
131
- 'channel_id=<channel-id>' \
132
- 'session_name=<session-name>'
133
- ```
127
+ If not yet, note that steps 7-9 must be done in the restarted session.
134
128
 
135
- Then add to shell profile:
136
- ```bash
137
- export WR_CONNECT_BOT_TOKEN="$(op read 'op://Private/wr-connect/bot_token')"
138
- export WR_CONNECT_CHANNEL_ID="$(op read 'op://Private/wr-connect/channel_id')"
139
- export WR_CONNECT_SESSION_NAME="$(op read 'op://Private/wr-connect/session_name')"
140
- ```
129
+ ### 7. Pair via DM
141
130
 
142
- **If shell profile:**
131
+ Tell the user:
143
132
 
144
- Use AskUserQuestion to get the values (same as .env), then tell the user to add
145
- the exports to their `~/.zshrc` or `~/.bashrc` and run `source ~/.zshrc`.
133
+ > Open Discord and send a DM to your bot. The bot will reply with a 6-character
134
+ > pairing code. Then run:
135
+ > ```
136
+ > /discord:access pair <code>
137
+ > ```
138
+ > This adds your Discord user ID to the allowlist.
146
139
 
147
- **Security warning:** The bot token gives anyone who has it the ability to send
148
- messages to your Claude Code session. Never commit it to source control.
140
+ Use AskUserQuestion:
141
+ - "Have you paired successfully?"
142
+ - Options: "Yes, I'm paired" / "The bot didn't respond" / "I need help"
149
143
 
150
- ### 6. Verify environment variables
144
+ If the bot didn't respond:
145
+ - Check that the session is running with `--channels`
146
+ - Check that the token was saved correctly (`/discord:configure` with no args shows status)
151
147
 
152
- Check the env vars are set in the current shell:
148
+ ### 8. Lock down access
153
149
 
154
- ```bash
155
- [ -n "$WR_CONNECT_BOT_TOKEN" ] && echo "BOT_TOKEN: set" || echo "BOT_TOKEN: NOT SET"
156
- [ -n "$WR_CONNECT_CHANNEL_ID" ] && echo "CHANNEL_ID: set" || echo "CHANNEL_ID: NOT SET"
157
- [ -n "$WR_CONNECT_SESSION_NAME" ] && echo "SESSION_NAME: set" || echo "SESSION_NAME: NOT SET"
158
- ```
150
+ Tell the user:
159
151
 
160
- If any are not set:
161
- - For .env: remind the user to run `source .env` or check the file
162
- - For 1Password: remind the user to run `eval $(op signin)` first
163
- - For shell profile: remind the user to `source ~/.zshrc`
152
+ > Now let's lock down access so only you can reach this session via Discord.
153
+ > Switch from `pairing` mode (which lets anyone trigger pairing codes) to
154
+ > `allowlist` mode:
155
+ > ```
156
+ > /discord:access policy allowlist
157
+ > ```
164
158
 
165
159
  Use AskUserQuestion:
166
- - "Are all three variables showing as set?"
167
- - Options: "Yes, all set" / "No, some are missing"
160
+ - "Have you locked down to allowlist policy?"
161
+ - Options: "Yes, locked down" / "I want to add more people first"
168
162
 
169
- If missing, help troubleshoot.
163
+ If they want to add more people, guide them:
164
+ > Have them DM the bot to get a pairing code, then approve with
165
+ > `/discord:access pair <code>`. Once everyone's in, run
166
+ > `/discord:access policy allowlist` to lock it.
170
167
 
171
- ### 7. Install the Discord channel plugin
172
-
173
- ```bash
174
- claude plugin install discord@claude-plugins-official
175
- ```
176
-
177
- ### 8. Configure the Discord allowlist (security)
178
-
179
- This is critical. Without the allowlist, anyone who can message the bot can send
180
- instructions to the Claude Code session.
168
+ ### 9. Set up guild channel (optional)
181
169
 
182
170
  Tell the user:
183
171
 
184
- > To find your Discord user ID: In Discord with Developer Mode enabled,
185
- > click your username at the bottom left, then click **Copy User ID**.
186
-
187
- Guide the user to configure the allowlist so only their own Discord user ID can
188
- send messages. The exact command depends on the Discord channel plugin's interface —
189
- check its documentation for the allowlist or access policy setting.
172
+ > For multi-agent collaboration, you'll want a shared guild channel that all
173
+ > sessions can see. Get the channel ID by right-clicking the channel in Discord
174
+ > (with Developer Mode enabled) and clicking **Copy Channel ID**.
175
+ >
176
+ > Then run:
177
+ > ```
178
+ > /discord:access group add <channel-id>
179
+ > ```
180
+ > Use `--no-mention` if you want the bot to see all messages (not just @mentions).
190
181
 
191
182
  Use AskUserQuestion:
192
- - "Have you configured the Discord allowlist with your user ID?"
193
- - Options: "Yes, allowlist configured" / "I need help finding my user ID" / "I'll do this later"
183
+ - "Would you like to set up a guild channel now?"
184
+ - Options: "Yes, I have the channel ID" / "No, DMs are enough for now"
194
185
 
195
- ### 9. Restart with channels active
186
+ If yes, guide them through the command.
196
187
 
197
- Tell the user:
198
-
199
- > To activate, restart Claude Code with:
200
- > ```
201
- > claude --channels plugin:discord@claude-plugins-official
202
- > ```
203
- > Claude will send a pairing code. Follow the prompts to pair your Discord account.
188
+ ### 10. Configure session name (optional)
204
189
 
205
- ### 10. Test the setup
190
+ The session name is used by the `/wr-connect:send` skill to identify this session
191
+ in messages. Detect from git remote:
206
192
 
207
- Use AskUserQuestion:
208
- - "Would you like to send a test message to verify the setup?"
209
- - Options: "Yes, send a test" / "No, I'll test later"
193
+ ```bash
194
+ git remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||;s|\.git$||'
195
+ ```
210
196
 
211
- If yes, tell them to use:
197
+ If a `.env.tpl` exists in the project, check if `WR_CONNECT_SESSION_NAME` is defined.
198
+ If not, suggest adding it:
212
199
 
213
200
  ```
214
- /wr-connect:send test message from setup
201
+ WR_CONNECT_SESSION_NAME={{ op://Private/wr-connect/session_name }}
215
202
  ```
216
203
 
217
- Or from another terminal:
218
-
204
+ Or for projects without 1Password, the session name can be set directly:
219
205
  ```bash
220
- curl -s -X POST "https://discord.com/api/v10/channels/$WR_CONNECT_CHANNEL_ID/messages" \
221
- -H "Authorization: Bot $WR_CONNECT_BOT_TOKEN" \
222
- -H "Content-Type: application/json" \
223
- -d '{"content": "[wr-connect] from: test | setup verification"}'
206
+ export WR_CONNECT_SESSION_NAME="<org/repo>"
224
207
  ```
225
208
 
226
- ### 11. Explain collaboration behaviour
209
+ ### 11. Test the setup
210
+
211
+ Use AskUserQuestion:
212
+ - "Would you like to send a test message to verify everything works?"
213
+ - Options: "Yes, send a test" / "No, I'll test later"
214
+
215
+ If yes and a guild channel is set up, use the reply tool to send a message to
216
+ the guild channel. If DM only, tell the user to DM the bot and check if it arrives.
217
+
218
+ ### 12. Explain collaboration behaviour
227
219
 
228
220
  Tell the user:
229
221
 
230
- > Your session is now part of a shared collaboration channel. Here's how it works:
222
+ > Setup complete! Here's how collaboration works:
231
223
  >
232
- > - **Multiple sessions and humans** can share the same Discord channel.
224
+ > - **Each repo has its own bot** — so you can see which session sent a message.
225
+ > - **Multiple sessions and humans** can share the same guild channel.
233
226
  > - Use `@session-name` in messages to direct them at a specific session
234
227
  > (e.g. `/wr-connect:send @repo-b please fix Widget.parse()`).
235
228
  > - Messages without `@` are broadcast — all sessions see them.
236
229
  > - Each session reads everything for context but only responds when the message
237
230
  > is relevant to its work.
238
- > - Your session name is whatever you set in `WR_CONNECT_SESSION_NAME`. Other
239
- > sessions will use `@your-name` to get your attention.
240
231
  > - Agents can react to messages for lightweight acknowledgement.
232
+ >
233
+ > To set up another repo, install the wr-connect plugin there and run
234
+ > `/wr-connect:setup` — it will create a new bot for that repo.
241
235
 
242
236
  $ARGUMENTS