discord-agent-bridge 0.2.0 โ†’ 0.4.0

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.
Files changed (43) hide show
  1. package/README.ko.md +386 -0
  2. package/README.md +302 -116
  3. package/dist/app.js +7 -10
  4. package/dist/app.js.map +1 -1
  5. package/dist/cli.js +11 -4
  6. package/dist/cli.js.map +1 -1
  7. package/dist/core/configResolver.js +4 -0
  8. package/dist/core/configResolver.js.map +1 -1
  9. package/dist/core/configSchema.js +8 -0
  10. package/dist/core/configSchema.js.map +1 -1
  11. package/dist/core/providerCatalog.js +10 -35
  12. package/dist/core/providerCatalog.js.map +1 -1
  13. package/dist/core/sessionOrchestrator.js +148 -4
  14. package/dist/core/sessionOrchestrator.js.map +1 -1
  15. package/dist/discord/configPanel.js +38 -6
  16. package/dist/discord/configPanel.js.map +1 -1
  17. package/dist/discord/format.js +30 -11
  18. package/dist/discord/format.js.map +1 -1
  19. package/dist/discord/i18n.js +4 -0
  20. package/dist/discord/i18n.js.map +1 -1
  21. package/dist/discord/interactionRouter.js +32 -8
  22. package/dist/discord/interactionRouter.js.map +1 -1
  23. package/dist/discord/renderers/index.js +63 -11
  24. package/dist/discord/renderers/index.js.map +1 -1
  25. package/dist/discord/renderers/streamEmbed.js +11 -0
  26. package/dist/discord/renderers/streamEmbed.js.map +1 -1
  27. package/dist/modes/claude/session.js +6 -0
  28. package/dist/modes/claude/session.js.map +1 -1
  29. package/dist/modes/codex/index.js +3 -0
  30. package/dist/modes/codex/index.js.map +1 -1
  31. package/dist/service/index.js +140 -0
  32. package/dist/service/index.js.map +1 -0
  33. package/dist/service/launchd.js +106 -0
  34. package/dist/service/launchd.js.map +1 -0
  35. package/dist/service/runScript.js +37 -0
  36. package/dist/service/runScript.js.map +1 -0
  37. package/dist/service/schtasks.js +78 -0
  38. package/dist/service/schtasks.js.map +1 -0
  39. package/dist/service/systemd.js +87 -0
  40. package/dist/service/systemd.js.map +1 -0
  41. package/dist/service/types.js +10 -0
  42. package/dist/service/types.js.map +1 -0
  43. package/package.json +2 -2
package/README.md CHANGED
@@ -1,201 +1,387 @@
1
1
  # discord-agent-bridge
2
2
 
3
+ ๐ŸŒ [ํ•œ๊ตญ์–ด](README.ko.md) | **English**
4
+
3
5
  > Self-hosted Discord bot that runs AI coding agents โ€” Claude Code, Codex, and more โ€” per channel. Role-based access, multi-server, extensible.
4
6
 
5
- **์ฑ„๋„๋งˆ๋‹ค Claude Code / Codex ๊ฐ™์€ AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ๋ฅผ ๋ถ™์—ฌ ์“ฐ๋Š” ์…€ํ”„ํ˜ธ์ŠคํŒ… Discord ๋ด‡์ž…๋‹ˆ๋‹ค.** ๋‚ด PC์—์„œ ์‹คํ–‰๋˜๊ณ , ์—ญํ•  ๊ธฐ๋ฐ˜ ๊ถŒํ•œ ยท ๋‹ค์ค‘ ์„œ๋ฒ„ ยท ํ™•์žฅ ๊ฐ€๋Šฅ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
7
+ **A self-hosted Discord bot that connects an AI coding agent โ€” Claude Code or Codex โ€” to each channel.** It runs on your own machine, with role-based permissions, multi-server support, and an extensible backend design.
6
8
 
7
- - ํ˜„์žฌ ์ง€์›: **Claude Code**, **Codex**
8
- - ํ™•์žฅ: ๋ชจ๋“œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€๋กœ ๋‹ค๋ฅธ ์—์ด์ „ํŠธ(์˜ˆ: opencode) ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ
9
+ - Currently supports: **Claude Code**, **Codex**
10
+ - Extensible: add a mode plugin to connect other agents (e.g. opencode) in the future
9
11
 
10
- > ๐Ÿšง **์ƒํƒœ: ๊ฐœ๋ฐœ ์ค‘ (Phase 1).** `npx discord-agent-bridge` ๋กœ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜(๊ถŒ์žฅ), ์•„๋ž˜ **"์†Œ์Šค์—์„œ ์‹คํ–‰"** ์œผ๋กœ ๋ฐ›์•„ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
12
+ > โœ… **Published on npm.** Run it instantly with `npx discord-agent-bridge` (recommended), or install globally / build from source. Supports both **Claude Code** and **Codex** backends.
11
13
 
12
14
  ---
13
15
 
14
- ## ์ด๊ฒŒ ๋ญ์˜ˆ์š”?
16
+ ## What is this?
15
17
 
16
- Discord ์ฑ„๋„์—์„œ ๋Œ€ํ™”ํ•˜๋“ฏ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด, ๋‚ด ์ปดํ“จํ„ฐ์—์„œ Claude Code(๋˜๋Š” Codex)๊ฐ€ ๊ทธ ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ž‘์—…ํ•ด ์ฃผ๋Š” ๋ด‡์ž…๋‹ˆ๋‹ค.
18
+ Send a message in a Discord channel like you're chatting, and Claude Code (or Codex) works on that project's folder from your own computer.
17
19
 
18
- - **์ฑ„๋„ = ์„ธ์…˜ = ํ”„๋กœ์ ํŠธ ํ•˜๋‚˜.** ์ฑ„๋„์„ ๋งŒ๋“ค ๋•Œ ์ž‘์—… ํด๋”์™€ ๋ฐฑ์—”๋“œ(Claude/Codex)๋ฅผ ์ •ํ•ฉ๋‹ˆ๋‹ค.
19
- - **์—ฌ๋Ÿฌ ์„œ๋ฒ„**์— ๊ฐ™์€ ๋ด‡์„ ์ดˆ๋Œ€ํ•ด ์“ธ ์ˆ˜ ์žˆ๊ณ , **์„œ๋ฒ„/ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์„ค์ •์ด ๋”ฐ๋กœ** ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
20
- - **์—ญํ• (Role)๋กœ ๋ˆ„๊ฐ€ ์“ธ ์ˆ˜ ์žˆ๋Š”์ง€** ํ†ต์ œํ•ฉ๋‹ˆ๋‹ค.
20
+ - **One channel = one session = one project.** When you create a channel, you set its working folder and backend (Claude/Codex).
21
+ - **Invite the same bot to multiple servers** โ€” each server/project gets its own independent configuration.
22
+ - **Roles control who can use it.**
21
23
 
22
24
  ---
23
25
 
24
- ## ์ค€๋น„๋ฌผ
26
+ ## Prerequisites
25
27
 
26
- - **Node.js 20 ์ด์ƒ**
27
- - ์‚ฌ์šฉํ•  ๋ฐฑ์—”๋“œ์— ๋งž๋Š” CLI๊ฐ€ **์„ค์น˜ + ๋กœ๊ทธ์ธ**๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
28
- - **Claude ๋ชจ๋“œ** โ†’ [Claude Code](https://docs.anthropic.com/en/docs/claude-code) ์ธ์ฆ (`claude` ๋กœ๊ทธ์ธ ๋˜๋Š” `ANTHROPIC_API_KEY`). ์‚ฌ์šฉ๋Ÿ‰/ํ•œ๋„ ํŒจ๋„์„ ๋ณด๋ ค๋ฉด **Claude Pro/Max ๊ตฌ๋… ๋กœ๊ทธ์ธ**์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
29
- - **Codex ๋ชจ๋“œ** โ†’ `codex` CLI ์„ค์น˜ + ๋กœ๊ทธ์ธ.
30
- - **Discord ๋ด‡ ํ† ํฐ** (์•„๋ž˜ 1๋‹จ๊ณ„์—์„œ ๋ฐœ๊ธ‰)
28
+ - **Node.js 20 or later**
29
+ - The CLI for whichever backend you use must already be **installed and logged in**:
30
+ - **Claude mode** โ†’ [Claude Code](https://docs.anthropic.com/en/docs/claude-code) authentication (`claude` login, or an `ANTHROPIC_API_KEY`). Viewing the usage/limits panel requires being **logged in with a Claude Pro/Max subscription**.
31
+ - **Codex mode** โ†’ the `codex` CLI installed and logged in.
32
+ - **A Discord bot token** (create one in Step 1 below)
31
33
 
32
34
  ---
33
35
 
34
- ## 1๋‹จ๊ณ„ โ€” Discord ๋ด‡ ๋งŒ๋“ค๊ธฐ (Developer Portal)
36
+ ## Step 1 โ€” Create a Discord bot (Developer Portal)
35
37
 
36
- ๋ด‡์„ ์ง์ ‘ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 5๋ถ„์ด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
38
+ You need to create your own bot. Takes about 5 minutes.
37
39
 
38
- 1. **[Discord Developer Portal](https://discord.com/developers/applications)** ์ ‘์† โ†’ ์˜ค๋ฅธ์ชฝ ์œ„ **New Application** โ†’ ์ด๋ฆ„ ์ž…๋ ฅ(์˜ˆ: `my-agent-bot`) โ†’ **Create**.
39
- 2. ์™ผ์ชฝ ๋ฉ”๋‰ด **Bot** ํƒญ โ†’ **Reset Token** โ†’ ๋‚˜์˜ค๋Š” **ํ† ํฐ์„ ๋ณต์‚ฌ**ํ•ด ์•ˆ์ „ํ•œ ๊ณณ์— ๋ณด๊ด€.
40
- - โš ๏ธ ์ด ํ† ํฐ์€ ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค. ๋…ธ์ถœ๋˜๋ฉด ์ฆ‰์‹œ **Reset Token**์œผ๋กœ ์žฌ๋ฐœ๊ธ‰ํ•˜์„ธ์š”.
41
- 3. ๊ฐ™์€ **Bot** ํƒญ ์•„๋ž˜ **Privileged Gateway Intents**:
42
- - โœ… **MESSAGE CONTENT INTENT** โ€” **ํ•„์ˆ˜** (๋ด‡์ด ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์„ ์ฝ์–ด์•ผ ํ•จ)
43
- - โœ… **SERVER MEMBERS INTENT** โ€” ๊ถŒ์žฅ (์—ญํ•  ๊ธฐ๋ฐ˜ ๊ถŒํ•œ ํ™•์ธ์— ์‚ฌ์šฉ)
44
- - ์ผœ๊ณ  **Save Changes**.
45
- 4. ์™ผ์ชฝ **OAuth2** ํƒญ โ†’ **Client ID(Application ID)** ๋ณต์‚ฌ (์…‹์—…์— ํ•„์š”).
46
- 5. **์ดˆ๋Œ€ ๋งํฌ ๋งŒ๋“ค๊ธฐ** โ€” OAuth2 โ†’ **URL Generator**:
40
+ 1. Go to the **[Discord Developer Portal](https://discord.com/developers/applications)** โ†’ top-right **New Application** โ†’ enter a name (e.g. `my-agent-bot`) โ†’ **Create**.
41
+ 2. Left sidebar **Bot** tab โ†’ **Reset Token** โ†’ **copy the token** and keep it somewhere safe.
42
+ - โš ๏ธ This token is a password. If it's ever exposed, reset it immediately with **Reset Token**.
43
+ 3. Still under the **Bot** tab, in **Privileged Gateway Intents**:
44
+ - โœ… **MESSAGE CONTENT INTENT** โ€” **required** (the bot needs to read message content)
45
+ - โœ… **SERVER MEMBERS INTENT** โ€” recommended (used for role-based permission checks)
46
+ - Enable them and **Save Changes**.
47
+ 4. Left sidebar **OAuth2** tab โ†’ copy the **Client ID (Application ID)** (needed for setup).
48
+ 5. **Build an invite link** โ€” OAuth2 โ†’ **URL Generator**:
47
49
  - **Scopes**: `bot`, `applications.commands`
48
50
  - **Bot Permissions**: `Manage Channels`, `Send Messages`, `Embed Links`, `Attach Files`, `Read Message History`, `Create Public Threads`, `Send Messages in Threads`, `Manage Threads`, `Add Reactions`
49
- - ์ƒ์„ฑ๋œ URL์„ ๋ธŒ๋ผ์šฐ์ €์— ๋ถ™์—ฌ๋„ฃ์–ด **๋‚ด ์„œ๋ฒ„์— ์ดˆ๋Œ€**.
50
- - (์…‹์—… ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ์ด ์ดˆ๋Œ€ ๋งํฌ๋ฅผ ์ž๋™ ์ƒ์„ฑํ•ด ์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค โ€” 2๋‹จ๊ณ„ ์ฐธ๊ณ .)
51
+ - Paste the generated URL into your browser and **invite it to your server**.
52
+ - (The setup wizard can also generate this invite link for you automatically โ€” see Step 2.)
53
+
54
+ ---
55
+
56
+ ## Step 2 โ€” Install & run
57
+
58
+ ### Install & auto-start (recommended)
59
+
60
+ The simplest path. These three lines take you from install to auto-start on reboot. `service install` registers the right auto-start for your OS โ€” **launchd on macOS, systemd on Linux, Task Scheduler on Windows**.
61
+
62
+ ```bash
63
+ npm install -g discord-agent-bridge # install
64
+ discord-agent-bridge --setup # first time only (enter token, etc.)
65
+ discord-agent-bridge service install # register auto-start + start now
66
+ ```
67
+
68
+ Management:
69
+
70
+ ```bash
71
+ discord-agent-bridge service status # registered / running?
72
+ discord-agent-bridge service restart # restart
73
+ discord-agent-bridge service uninstall # remove
74
+ ```
75
+
76
+ To upgrade, install the latest and restart:
77
+
78
+ ```bash
79
+ npm install -g discord-agent-bridge@latest
80
+ discord-agent-bridge service restart
81
+ ```
82
+
83
+ > โš ๏ธ **Windows note**: it registers a Task Scheduler logon trigger, so the bot **starts at login** (no admin needed). It does not guarantee auto-restart on crash (macOS/Linux do). If `service install` doesn't work, see **Manual setup โ€” Windows (Task Scheduler)** below.
51
84
 
52
85
  ---
53
86
 
54
- ## 2๋‹จ๊ณ„ โ€” ์„ค์น˜ & ์‹คํ–‰
87
+ The rest of this section is the **manual methods**, for when `service install` doesn't work or you want to set it up yourself.
88
+
89
+ ### Manual setup โ€” macOS (launchd)
90
+
91
+ Run the bot directly under **launchd**, the built-in macOS service manager โ€” it starts at login and restarts automatically if it stops.
92
+
93
+ ```bash
94
+ # 1) Install globally (and run setup once if you haven't)
95
+ npm install -g discord-agent-bridge
96
+ discord-agent-bridge --setup # skip if already configured
97
+
98
+ # 2) Create a launcher wrapper โ€” it finds nvm's default node dynamically,
99
+ # so it keeps working even after you switch node versions.
100
+ mkdir -p ~/.discord-agent-bridge
101
+ cat > ~/.discord-agent-bridge/run.sh <<'EOF'
102
+ #!/bin/bash
103
+ export NVM_DIR="$HOME/.nvm"
104
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
105
+ nvm use default >/dev/null 2>&1 || nvm use node >/dev/null 2>&1
106
+ exec discord-agent-bridge
107
+ EOF
108
+ chmod +x ~/.discord-agent-bridge/run.sh
109
+ # Not using nvm? run.sh can just be `#!/bin/bash` + `exec discord-agent-bridge` (node must be on PATH).
110
+
111
+ # 3) Create the LaunchAgent ($HOME is expanded to an absolute path as the file is written)
112
+ cat > ~/Library/LaunchAgents/com.discord-agent-bridge.plist <<EOF
113
+ <?xml version="1.0" encoding="UTF-8"?>
114
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
115
+ <plist version="1.0">
116
+ <dict>
117
+ <key>Label</key><string>com.discord-agent-bridge</string>
118
+ <key>ProgramArguments</key>
119
+ <array>
120
+ <string>/bin/bash</string>
121
+ <string>$HOME/.discord-agent-bridge/run.sh</string>
122
+ </array>
123
+ <key>EnvironmentVariables</key>
124
+ <dict><key>HOME</key><string>$HOME</string></dict>
125
+ <key>RunAtLoad</key><true/>
126
+ <key>KeepAlive</key><true/>
127
+ <key>StandardOutPath</key><string>$HOME/.discord-agent-bridge/agent.out.log</string>
128
+ <key>StandardErrorPath</key><string>$HOME/.discord-agent-bridge/agent.err.log</string>
129
+ </dict>
130
+ </plist>
131
+ EOF
132
+
133
+ # 4) Start it
134
+ launchctl load -w ~/Library/LaunchAgents/com.discord-agent-bridge.plist
135
+
136
+ # 5) Verify โ€” seeing 'gateway ready' means success (Ctrl+C only exits the log view; the bot keeps running)
137
+ tail -f ~/.discord-agent-bridge/agent.out.log
138
+ ```
139
+
140
+ Management:
141
+
142
+ ```bash
143
+ launchctl list | grep discord-agent-bridge # status (col 1 = PID, col 2 = last exit code)
144
+ launchctl unload ~/Library/LaunchAgents/com.discord-agent-bridge.plist # stop
145
+ launchctl load -w ~/Library/LaunchAgents/com.discord-agent-bridge.plist # start
146
+ ```
147
+
148
+ Upgrading:
149
+
150
+ ```bash
151
+ npm install -g discord-agent-bridge@latest
152
+ launchctl unload ~/Library/LaunchAgents/com.discord-agent-bridge.plist
153
+ launchctl load -w ~/Library/LaunchAgents/com.discord-agent-bridge.plist
154
+ ```
155
+
156
+ > โš ๏ธ If you switch node versions with nvm, run `npm install -g discord-agent-bridge` once under the new version (nvm keeps global packages per version). The wrapper follows nvm's default node, so the plist itself never needs editing.
157
+
158
+ ### Manual setup โ€” Windows (Task Scheduler)
159
+
160
+ Register it yourself when `discord-agent-bridge service install` doesn't work.
55
161
 
56
- ### npx๋กœ ์‹คํ–‰ (๊ถŒ์žฅ)
162
+ **Commands (no admin needed)** โ€” first find the bot's real path in PowerShell:
57
163
 
58
- ์„ค์น˜ ์—†์ด ๋ฐ”๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. `npx` ๊ฐ€ ์ตœ์‹  ๋ฒ„์ „์„ ๋ฐ›์•„ ์‹คํ–‰ํ•˜๋ฉฐ, ์ตœ์ดˆ ์‹คํ–‰์ด๋ฉด ์…‹์—… ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋จผ์ € ๋œฌ ๋’ค ์ด์–ด์„œ ๋ด‡์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
164
+ ```powershell
165
+ where.exe discord-agent-bridge # e.g. C:\Users\<you>\AppData\Roaming\npm\discord-agent-bridge.cmd
166
+
167
+ # Register a logon-triggered task using the path from above
168
+ schtasks /create /tn discord-agent-bridge /sc onlogon /tr "C:\Users\<you>\AppData\Roaming\npm\discord-agent-bridge.cmd" /f
169
+ schtasks /query /tn discord-agent-bridge # status
170
+ schtasks /run /tn discord-agent-bridge # start now
171
+ schtasks /delete /tn discord-agent-bridge /f # remove
172
+ ```
173
+
174
+ **GUI**: Start menu โ†’ **Task Scheduler** โ†’ **Create Basic Task** โ†’ name `discord-agent-bridge`, trigger **When I log on**, action **Start a program** โ†’ the `.cmd` path from `where.exe` โ†’ Finish.
175
+
176
+ > A logon task runs **at login** and does **not** guarantee restart on crash. For crash recovery / running before login you need a real Windows service โ€” register one with [nssm](https://nssm.cc/) (admin required):
177
+ >
178
+ > ```powershell
179
+ > nssm install discord-agent-bridge "C:\Program Files\nodejs\node.exe" "C:\Users\<you>\AppData\Roaming\npm\node_modules\discord-agent-bridge\dist\cli.js"
180
+ > nssm start discord-agent-bridge
181
+ > ```
182
+
183
+ ### Manual setup โ€” PM2 (Linux / Windows alternative)
184
+
185
+ On Linux/Windows you can also use [PM2](https://pm2.keymetrics.io/) (handy logs, restart, status). **On macOS, use `service install`/launchd instead** โ€” PM2's fork wrapper can prevent the bot from opening its gateway connection on macOS.
186
+
187
+ ```bash
188
+ # 1) Install the bot globally (so PM2 has a stable command to run)
189
+ npm install -g discord-agent-bridge
190
+
191
+ # 2) Run --setup once if you haven't yet
192
+ discord-agent-bridge --setup
193
+
194
+ # 3) Install PM2
195
+ npm install -g pm2
196
+
197
+ # 4) Register the bot with PM2 and start it
198
+ pm2 start discord-agent-bridge --name discord-agent-bridge
199
+
200
+ # 5) Snapshot the current process list (so PM2 knows what to restore on boot)
201
+ pm2 save
202
+
203
+ # 6) Register PM2 to start at boot (on macOS this wires up launchd)
204
+ pm2 startup
205
+ # โ†‘ Copy-paste the `sudo ...` command it prints and run it once.
206
+ ```
207
+
208
+ Day-to-day management:
209
+
210
+ ```bash
211
+ pm2 status # is it running?
212
+ pm2 logs discord-agent-bridge # tail logs
213
+ pm2 restart discord-agent-bridge # restart (also do this after upgrading)
214
+ pm2 stop discord-agent-bridge # stop
215
+ pm2 delete discord-agent-bridge # unregister
216
+ ```
217
+
218
+ Upgrading under PM2:
59
219
 
60
220
  ```bash
61
- # ์ตœ์ดˆ ์‹คํ–‰ โ€” ์…‹์—… ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋œฌ ๋’ค ์ด์–ด์„œ ๋ด‡์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
62
- # (ํ† ํฐ/Client ID ์ž…๋ ฅ, ์ธํ…ํŠธ ํ™•์ธ, ์ดˆ๋Œ€ ๋งํฌ ์ƒ์„ฑ โ€” ๊ธฐ๋ณธ๊ฐ’์€ ์•ˆ ๋ฌผ์–ด๋ด„)
221
+ npm install -g discord-agent-bridge@latest
222
+ pm2 restart discord-agent-bridge
223
+ ```
224
+
225
+ > โš ๏ธ If you use nvm/asdf, PM2 needs to find the same `node` at boot time as it does in your shell. Verify with `which node` and make sure that path is available to the boot environment โ€” otherwise PM2 may fail to start the bot on reboot.
226
+
227
+ ### Run with npx (quick try)
228
+
229
+ Use this to spin it up once without installing. `npx` fetches the latest version and runs it; on first run, the setup wizard appears first and the bot starts right after. (Closing the terminal stops the bot โ€” use PM2 above to keep it running.)
230
+
231
+ ```bash
232
+ # First run โ€” the setup wizard runs automatically, then the bot starts.
233
+ # (asks for your token/Client ID, checks intents, generates an invite link โ€” no other defaults are asked)
63
234
  npx discord-agent-bridge
64
235
 
65
- # ์ดํ›„ ์‹คํ–‰ โ€” ์ด๋ฏธ ์„ค์ •๋ผ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ๋ด‡์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
236
+ # Later runs โ€” if already configured, the bot starts directly.
66
237
  npx discord-agent-bridge
67
238
 
68
- # ๋‹ค์‹œ ์„ค์ •๋งŒ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ (๋ด‡์€ ์‹œ์ž‘ํ•˜์ง€ ์•Š์Œ)
239
+ # To reconfigure only (without starting the bot)
69
240
  npx discord-agent-bridge --setup
70
241
  ```
71
242
 
72
- ์ „์—ญ ์„ค์น˜๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค: `npm install -g discord-agent-bridge` ํ›„ `discord-agent-bridge` / `discord-agent-bridge --setup`.
243
+ Global install also works: `npm install -g discord-agent-bridge`, then `discord-agent-bridge` / `discord-agent-bridge --setup`.
244
+
245
+ ### Upgrading
73
246
 
74
- ### ์†Œ์Šค์—์„œ ์‹คํ–‰
247
+ When a new version is released:
75
248
 
76
249
  ```bash
77
- git clone https://github.com/10000DOO/discord-agent-bridge.git
78
- cd discord-agent-bridge
79
- npm install
80
- npm run build
250
+ # npx users โ€” appending @latest always fetches the newest version (npx can otherwise cache).
251
+ npx discord-agent-bridge@latest
81
252
 
82
- node dist/cli.js # ์ตœ์ดˆ 1ํšŒ: ์…‹์—… ๋งˆ๋ฒ•์‚ฌ ์ž๋™ ์‹คํ–‰ โ†’ ์ด์–ด์„œ ๋ด‡ ์‹œ์ž‘ / ์ดํ›„: ๋ฐ”๋กœ ๋ด‡ ์‹œ์ž‘
83
- node dist/cli.js --setup # ์„ค์ •๋งŒ ๋‹ค์‹œ (๋ด‡์€ ์‹œ์ž‘ ์•ˆ ํ•จ)
253
+ # Global-install users
254
+ npm install -g discord-agent-bridge@latest
84
255
  ```
85
256
 
86
- **์…‹์—… ๋งˆ๋ฒ•์‚ฌ(`--setup`)** ๊ฐ€ ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ โ€” **ํ† ํฐ(๋น„๋ฐ€)๋งŒ ํ„ฐ๋ฏธ๋„์—์„œ ์ž…๋ ฅ**ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์™ธ ๊ฐ’์€ ํ•˜๋‚˜๋„ ์•ˆ ๋ฌผ์–ด๋ด…๋‹ˆ๋‹ค:
87
- 1. Discord ๋ด‡ **ํ† ํฐ** (๋น„๋ฐ€ โ†’ ํ„ฐ๋ฏธ๋„์—์„œ๋งŒ ๋ถ™์—ฌ๋„ฃ๊ธฐ)
88
- 2. **Client ID**
89
- 3. Message Content Intent ์ผฐ๋Š”์ง€ ํ™•์ธ
90
- 4. ์ดˆ๋Œ€ URL ์ƒ์„ฑ โ†’ ์„œ๋ฒ„์— ์ดˆ๋Œ€
257
+ Check your installed version with: `discord-agent-bridge --version`.
258
+
259
+ **What the setup wizard (`--setup`) asks for** โ€” the **token (secret) is the only thing you type into the terminal**. Nothing else is asked here:
260
+ 1. Your Discord bot **token** (secret โ€” paste it only in the terminal)
261
+ 2. Your **Client ID**
262
+ 3. Confirmation that Message Content Intent is enabled
263
+ 4. Generates an invite URL โ†’ invite it to your server
91
264
 
92
- > **์—ญํ• ๋„, ๊ธฐ๋ณธ๊ฐ’๋„ ํ„ฐ๋ฏธ๋„์—์„œ ์•ˆ ์ •ํ•ฉ๋‹ˆ๋‹ค.** ๋ด‡์„ ์„œ๋ฒ„์— ์ดˆ๋Œ€ํ•œ ๋’ค Discord์—์„œ **`/config`** ๋ช…๋ น์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”:
93
- > - **์—ญํ•  ํ‹ฐ์–ด** โ€” ์—ญํ•  ์ด๋ฆ„์„ **ํด๋ฆญ**ํ•ด ์ง€์ •(์—ญํ•  ID ๋ณต์‚ฌยท๊ฐœ๋ฐœ์ž ๋ชจ๋“œ ๋ถˆํ•„์š”). ์ง€์ • ์ „์—๋Š” **๋ชจ๋‘ ๊ฑฐ๋ถ€(deny-by-default)**.
94
- > - **๊ธฐ๋ณธ๊ฐ’** โ€” **๊ธฐ๋ณธ ๋ฐฑ์—”๋“œยท๋ชจ๋ธยท๊ถŒํ•œ ๋ชจ๋“œยท์–ธ์–ด(locale)** ๋Š” ๋“œ๋กญ๋‹ค์šด์—์„œ ๊ณ ๋ฅด๋ฉด **๋ฐ”๋กœ ์ €์žฅ**๋˜๊ณ , **Codex ๊ธฐ๋ณธ ๊ฒฝ๋กœ(codexHome)** ๋Š” "Codex ๊ฒฝ๋กœ ์„ค์ •" ๋ฒ„ํŠผ โ†’ ์ž…๋ ฅ์ฐฝ(๋ชจ๋‹ฌ)์—์„œ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์–ธ์–ด๋Š” `ํ•œ๊ตญ์–ด (ko)` / `English (en)` ์ค‘์—์„œ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
265
+ > **Roles and defaults are never configured in the terminal.** After inviting the bot to your server, configure them in Discord with the **`/config`** command:
266
+ > - **Role tiers** โ€” assign them by **clicking** a role name (no need to copy a role ID or enable Developer Mode). Until assigned, access is **deny-by-default**.
267
+ > - **Defaults** โ€” **default backend, model, permission mode, and language (locale)** are saved instantly from a dropdown; the **Codex base path (codexHome)** is set via the "Set Codex Path" button โ†’ a text-input modal. Language choices are `ํ•œ๊ตญ์–ด (ko)` / `English (en)`.
95
268
 
96
- ์„ค์ •์€ `~/.discord-agent-bridge/` ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค(ํ† ํฐ ํŒŒ์ผ ๊ถŒํ•œ 600). ์—ญํ• ยท๊ธฐ๋ณธ๊ฐ’์€ ์„œ๋ฒ„๋ณ„๋กœ `servers/<guildId>.json` ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
269
+ Configuration is stored under `~/.discord-agent-bridge/` (token file permissions 600). Per-server roles and defaults are stored in `servers/<guildId>.json`.
97
270
 
98
271
  ---
99
272
 
100
- ## 3๋‹จ๊ณ„ โ€” Discord์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ
273
+ ## Step 3 โ€” Using it in Discord
101
274
 
102
- ๋ด‡์ด ์„œ๋ฒ„์— ๋“ค์–ด์˜ค๊ณ  ์‹คํ–‰ ์ค‘์ด๋ฉด (๊ถŒ์žฅ ์ˆœ์„œ: **์ดˆ๋Œ€ โ†’ `/init` โ†’ `/config` โ†’ `/agent start`**):
275
+ Once the bot joins a server, it **automatically creates a control channel (`#session-generator`), a sessions category, and a notifications channel (`#agent-status`)** (as long as it has the Manage Channels permission). From there, the flow is: **`/config` โ†’ `/agent start`**.
103
276
 
104
- 1. **`/init`** (๊ด€๋ฆฌ์ž) โ†’ ์ปจํŠธ๋กค ์ฑ„๋„(`#session-generator`)๊ณผ ์„ธ์…˜ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ๊ธฐ์กด ์ฑ„๋„์„ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(์ค‘๋ณต ์ƒ์„ฑ ์—†์Œ).
105
- 2. **`/config`** (๊ด€๋ฆฌ์ž) โ†’ ์—ญํ•  ํ‹ฐ์–ดยท๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. (์„œ๋ฒ„ ๊ด€๋ฆฌ์ž(Administrator)๋Š” ์—ญํ•  ์„ค์ • ์—†์ด๋„ ํ•ญ์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)
106
- 3. `#session-generator` ์—์„œ **`/agent start`** โ†’ **๋งˆ๋ฒ•์‚ฌ**๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค:
107
- **์ž‘์—… ํด๋” ์„ ํƒ โ†’ ๋ฐฑ์—”๋“œ(Claude / Codex) โ†’ ๋ชจ๋ธ โ†’ ๊ถŒํ•œ ๋ชจ๋“œ/ํ”„๋กœํ•„**. ํ™•์ธํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ํด๋” ์ด๋ฆ„์œผ๋กœ **์ „์šฉ ์„ธ์…˜ ์ฑ„๋„(`proj-<ํด๋”>`)์ด ์ƒˆ๋กœ ์ƒ์„ฑ**๋˜๊ณ  ๊ทธ ์ฑ„๋„์— ๋ฐ”์ธ๋”ฉ๋ฉ๋‹ˆ๋‹ค.
108
- 4. ๋งŒ๋“ค์–ด์ง„ ์„ธ์…˜ ์ฑ„๋„์—์„œ **๊ทธ๋ƒฅ ๋ฉ”์‹œ์ง€๋กœ ๋Œ€ํ™”**ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. Claude ๋ชจ๋“œ๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์ถœ๋ ฅยทํˆด ์‹คํ–‰ ์Šค๋ ˆ๋“œยท๊ถŒํ•œ ์Šน์ธ ๋ฒ„ํŠผ์ด ๋œน๋‹ˆ๋‹ค.
109
- 5. ํ•„์š”ํ•  ๋•Œ ๋ช…๋ น์–ด ์‚ฌ์šฉ.
277
+ 1. **(Automatic)** This channel structure is created when the bot starts or is invited to a server. An admin can also recreate it manually with **`/init`** (existing channels are reused โ€” no duplicates).
278
+ 2. **`/config`** (admin) โ†’ set role tiers and defaults. (Server Administrators can always use the bot, even without an assigned role.)
279
+ 3. In `#session-generator`, run **`/agent start`** โ†’ the **wizard** walks you through, in order:
280
+ **choose a working folder โ†’ backend (Claude / Codex) โ†’ model โ†’ reasoning effort โ†’ permission mode**. Each step advances with a **"Next" button**. The folder browser supports **navigating to parent/other volumes, creating new folders, and resuming a previous session**. Once confirmed, a **dedicated session channel (`proj-<folder>`) is created** and bound to it, named after the project folder.
281
+ 4. In the newly created session channel, **just chat with normal messages**. Claude mode shows streaming output, tool-execution threads, and permission approval buttons.
282
+ 5. Use the commands below whenever you need them.
110
283
 
111
- ### ์ฃผ์š” ๋ช…๋ น์–ด
112
- | ๋ช…๋ น์–ด | ์„ค๋ช… |
284
+ ### Key commands
285
+ | Command | Description |
113
286
  |---|---|
114
- | `/init` | (๊ด€๋ฆฌ์ž) ์ปจํŠธ๋กค ์ฑ„๋„ + ์„ธ์…˜ ์นดํ…Œ๊ณ ๋ฆฌ ์ƒ์„ฑ (์žฌ์‹คํ–‰ ์‹œ ์žฌ์‚ฌ์šฉ) |
115
- | `/agent start` | ์ƒˆ ์„ธ์…˜ ์‹œ์ž‘ โ€” ๋งˆ๋ฒ•์‚ฌ ํ™•์ธ ์‹œ ์ „์šฉ ์„ธ์…˜ ์ฑ„๋„์„ ์ƒˆ๋กœ ์ƒ์„ฑ |
116
- | `/agent resume` | ์ด์ „ ์„ธ์…˜ ์ด์–ดํ•˜๊ธฐ |
117
- | `/agent close` | ์„ธ์…˜ ์ข…๋ฃŒ + ์„ธ์…˜ ์ฑ„๋„ ์‚ญ์ œ |
118
- | `/mode <claude\|codex>` | ๋ฐฑ์—”๋“œ ์ „ํ™˜ (โš ๏ธ ์ƒˆ ๋Œ€ํ™”๋กœ ์‹œ์ž‘ โ€” ์ด์ „ ๋งฅ๋ฝ ๋ฏธ์Šน๊ณ„) |
119
- | `/mode perm <๋ชจ๋“œ\|ํ”„๋กœํ•„>` | ๊ถŒํ•œ ๋ชจ๋“œ/ํ”„๋กœํ•„ ์ „ํ™˜ (์„ธ์…˜ ์œ ์ง€) |
120
- | `/stop` | ํ˜„์žฌ ์„ธ์…˜ ์ฆ‰์‹œ ์ค‘๋‹จ (ํ‚ฌ ์Šค์œ„์น˜) |
121
- | `/stop-all` | (๊ด€๋ฆฌ์ž) ๋ชจ๋“  ์„ธ์…˜ ์ค‘๋‹จ |
122
- | `/config` | (๊ด€๋ฆฌ์ž) ์—ญํ•  ํ‹ฐ์–ด + ๊ธฐ๋ณธ๊ฐ’(๋ฐฑ์—”๋“œยท๋ชจ๋ธยท๊ถŒํ•œ ๋ชจ๋“œยท์–ธ์–ดยทCodex ๊ฒฝ๋กœ) ์„ค์ • โ€” ์—ญํ• ์€ **ํด๋ฆญ**, ๊ธฐ๋ณธ๊ฐ’์€ ๋“œ๋กญ๋‹ค์šด/๋ชจ๋‹ฌ์—์„œ ์ง€์ • |
123
-
124
- ### ๊ถŒํ•œ ๋ชจ๋“œ (์„ธ์…˜์ด ์–ผ๋งˆ๋‚˜ ์ž์œจ์ ์ธ์ง€)
125
- - `default` โ€” ๋„๊ตฌ ์‹คํ–‰ ์ „๋งˆ๋‹ค **Allow/Deny ๋ฒ„ํŠผ**์œผ๋กœ ํ™•์ธ (๊ฐ€์žฅ ์•ˆ์ „)
126
- - `acceptEdits` โ€” ํŒŒ์ผ ์ˆ˜์ •์€ ์ž๋™ ์ˆ˜๋ฝ
127
- - `plan` โ€” ๋จผ์ € ๊ณ„ํš๋งŒ ์„ธ์šฐ๊ณ  ์‹คํ–‰์€ ๋ณด๋ฅ˜
128
- - `bypassPermissions` โ€” ์ „๋ถ€ ์ž๋™ (์‹ ๋ขฐํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋งŒ)
129
-
130
- (Codex๋Š” CLI์˜ ์Šน์ธยท์ƒŒ๋“œ๋ฐ•์Šค ๋ชจ๋“œ๋กœ ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.)
287
+ | `/init` | (admin) Create the control channel + sessions category (reuses them if already present) |
288
+ | `/agent start` | Start a new session โ€” creates a dedicated session channel once the wizard is confirmed |
289
+ | `/agent resume` | Resume a previous session |
290
+ | `/agent close` | End the session and delete its session channel |
291
+ | `/agent stats` | View active sessions, session statistics, and Claude usage (visible only to you) |
292
+ | `/mode <claude\|codex>` | Switch backend (โš ๏ธ starts a new conversation โ€” prior context is not carried over) |
293
+ | `/mode perm <mode\|profile>` | Switch permission mode/profile (session context is preserved) |
294
+ | `/stop` | Immediately stop the current session (kill switch) |
295
+ | `/stop-all` | (admin) Stop all sessions |
296
+ | `/config` | (admin) Configure role tiers + defaults (backend, model, permission mode, language, Codex path) โ€” roles are set by **clicking**, defaults via dropdown/modal |
297
+
298
+ ### Permission modes (how autonomous a session is)
299
+ - `default` โ€” confirms every tool execution with **Allow/Deny buttons** (safest)
300
+ - `acceptEdits` โ€” file edits are accepted automatically
301
+ - `plan` โ€” only plans first, holds off on execution
302
+ - `bypassPermissions` โ€” fully automatic (only for projects you trust)
303
+
304
+ (Codex maps these to the CLI's own approval/sandbox modes.)
305
+
306
+ ### Event notifications (`#agent-status`)
307
+
308
+ Summarizes **completions and errors** from all your sessions into a single `#agent-status` channel. Toggle it on/off and change the target channel from `/config` โ†’ **๐Ÿ”” Notification Settings**.
131
309
 
132
310
  ---
133
311
 
134
- ## ๊ถŒํ•œ & ์—ญํ•  ์„ค์ • (์ค‘์š”)
312
+ ## Permissions & role setup (important)
135
313
 
136
- ์ด ๋ด‡์€ **๋‹น์‹  PC์—์„œ, ๋‹น์‹  ๊ณ„์ • ๊ถŒํ•œ์œผ๋กœ** ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ ๋ด‡์—๊ฒŒ ๋ช…๋ นํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์€ **๋‹น์‹  ์ปดํ“จํ„ฐ์—์„œ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ**์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์—ญํ•  ํ†ต์ œ๊ฐ€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.
314
+ This bot runs code **on your machine, with your account's permissions**. That means anyone who can command the bot is effectively **someone who can run commands on your computer** โ€” so role-based access control is essential.
137
315
 
138
- - **์—ญํ•  ํ‹ฐ์–ด 3๋‹จ๊ณ„** โ€” Discord์—์„œ **`/config`** ๋กœ ์—ญํ•  ์ด๋ฆ„์„ **ํด๋ฆญ**ํ•ด ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค(์—ญํ•  IDยท๊ฐœ๋ฐœ์ž ๋ชจ๋“œ ๋ถˆํ•„์š”). admin โЇ execute โЇ read-only:
139
- - **admin** โ€” ์„ค์ •/`stop-all`/`config` ๋“ฑ ๊ด€๋ฆฌ
140
- - **execute** โ€” ์„ธ์…˜ ์‹œ์ž‘ยท๋ช…๋ น ์‹คํ–‰
141
- - **read-only** โ€” ์ฝ๊ธฐ๋งŒ
142
- - > `/config` ๋Š” ์ฒ˜์Œ์—” **์„œ๋ฒ„ ๊ด€๋ฆฌ์ž(Administrator)** ๊ถŒํ•œ์ด ์žˆ๋Š” ์‚ฌ๋žŒ๋งŒ ์—ด ์ˆ˜ ์žˆ๊ณ (ํ—ˆ์šฉ ๋ชฉ๋ก์ด ๋น„์–ด ์žˆ์–ด๋„ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๊ฐ€๋Šฅ), ์ดํ›„์—” admin ํ‹ฐ์–ด๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
143
- - **๊ธฐ๋ณธ์€ ๊ฑฐ๋ถ€(deny-by-default)** โ€” ํ—ˆ์šฉ ๋ชฉ๋ก์— ์—†๋Š” ์‚ฌ๋žŒ์€ ์•„๋ฌด๊ฒƒ๋„ ๋ชป ํ•ฉ๋‹ˆ๋‹ค. `/config` ๋กœ ์ง€์ •ํ•˜๊ธฐ ์ „์—๋Š” ์•„๋ฌด๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
144
- - **ํ”„๋กœ์ ํŠธ๋ณ„ ์ ‘๊ทผ ์ œ์–ด(ACL)** โ€” ํŠน์ • ํ”„๋กœ์ ํŠธ๋ฅผ ์ง€์ •ํ•œ ์—ญํ• /์‚ฌ๋žŒ๋งŒ ์“ฐ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
145
- - **๊ฐ์‚ฌ ๋กœ๊ทธ** โ€” ๋ˆ„๊ฐ€ ์–ธ์ œ ๋ฌด์—‡์„ ํ–ˆ๋Š”์ง€ `~/.discord-agent-bridge/audit/` ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.
316
+ - **3 role tiers** โ€” assign them in Discord via **`/config`** by **clicking** a role name (no role ID or Developer Mode needed). admin โЇ execute โЇ read-only:
317
+ - **admin** โ€” manages settings/`stop-all`/`config`
318
+ - **execute** โ€” can start sessions and run commands
319
+ - **read-only** โ€” read access only
320
+ - > `/config` can initially only be opened by someone with **server Administrator** permission (bootstraps even with an empty allow-list); afterward, the admin tier can use it too.
321
+ - **Deny-by-default** โ€” anyone not on the allow-list can do nothing. Until you configure it via `/config`, no one can run anything.
322
+ - **Per-project access control (ACL)** โ€” restrict a specific project to only the roles/people you designate.
323
+ - **Audit log** โ€” who did what and when is recorded in `~/.discord-agent-bridge/audit/`.
146
324
 
147
- > โš ๏ธ **๋ณด์•ˆ ์ฃผ์˜:** ์‹ ๋ขฐํ•˜์ง€ ์•Š๋Š” ์„œ๋ฒ„์— ๋ด‡์„ ์ดˆ๋Œ€ํ•˜๊ฑฐ๋‚˜ execute ์—ญํ• ์„ ๋„ˆ๋ฌด ๋„“๊ฒŒ ์ฃผ์ง€ ๋งˆ์„ธ์š”. ์ž‘์—… ํด๋” ๋ฐ–(์˜ˆ: `~/.ssh`)์€ ๋ด‡์ด ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๊ธฐ๋ณธ ์ฐจ๋‹จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
325
+ > โš ๏ธ **Security note:** Don't invite the bot to servers you don't trust, and don't grant the execute role too broadly. Access outside the working folder (e.g. `~/.ssh`) is blocked by default.
148
326
 
149
327
  ---
150
328
 
151
- ## Claude ๋ชจ๋“œ vs Codex ๋ชจ๋“œ
329
+ ## Claude mode vs. Codex mode
152
330
 
153
- | | Claude ๋ชจ๋“œ | Codex ๋ชจ๋“œ |
331
+ | | Claude mode | Codex mode |
154
332
  |---|---|---|
155
- | ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ | โœ… | โŒ (์ตœ์ข… ๊ฒฐ๊ณผ ์œ„์ฃผ) |
156
- | ํˆด ์‹คํ–‰ ์Šค๋ ˆ๋“œ | โœ… | โŒ |
157
- | ๊ถŒํ•œ ์Šน์ธ ๋ฒ„ํŠผ | โœ… | โŒ (์Šน์ธ/์ƒŒ๋“œ๋ฐ•์Šค ๋ชจ๋“œ๋กœ ๋Œ€์ฒด) |
158
- | ์„ธ์…˜ ์ด์–ดํ•˜๊ธฐ | โœ… | โœ… |
159
- | **์‚ฌ์šฉ๋Ÿ‰/ํ•œ๋„ ํ‘œ์‹œ** | โœ… (5์‹œ๊ฐ„ยท์ฃผ๊ฐ„ยท์ปจํ…์ŠคํŠธ) | โŒ (Codex CLI ์ œ์•ฝ) |
333
+ | Real-time streaming | โœ… | โŒ (final result only) |
334
+ | Tool-execution threads | โœ… | โŒ |
335
+ | Permission approval buttons | โœ… | โŒ (replaced by approval/sandbox modes) |
336
+ | Session resume | โœ… | โœ… |
337
+ | **Usage/limits display** | โœ… (5-hour ยท weekly ยท context) | โŒ (Codex CLI limitation) |
338
+
339
+ ### Is this the same as using the terminal?
340
+
341
+ - **Claude mode** โ€” uses the **same engine** as the `claude` terminal (the official Claude Agent SDK). It reads the project's `.claude/` configuration as-is, so **subagents, skills, hooks, and MCP all behave identically**. The only difference is the **presentation**: input comes from Discord messages, output renders as embeds/threads. (TUI-only slash commands you'd type in the interactive terminal are handled through the SDK's mechanism rather than the TUI's own.)
342
+ - **Codex mode** โ€” runs via `codex exec` (non-interactive). It loads the same Codex engine with your config/MCP, and we've **empirically confirmed hooks (SessionStart/UserPromptSubmit/Stop, etc.) fire correctly in non-interactive mode too**. Approval flow is mapped differently than interactive mode, though (see Permission modes above).
160
343
 
161
- ### ํ„ฐ๋ฏธ๋„์—์„œ ์“ฐ๋˜ ๊ฑฐ๋ž‘ ๋˜‘๊ฐ™๋‚˜์š”?
344
+ ### Custom slash commands / skills / plugin commands
162
345
 
163
- - **Claude ๋ชจ๋“œ** โ€” ํ„ฐ๋ฏธ๋„์˜ `claude`์™€ **๊ฐ™์€ ์—”์ง„**(๊ณต์‹ Claude Agent SDK)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ `.claude/` ์„ค์ •์„ ๊ทธ๋Œ€๋กœ ์ฝ์–ด **์„œ๋ธŒ์—์ด์ „ํŠธยท์Šคํ‚ฌยทํ›…ยทMCP๊ฐ€ ๋™์ผํ•˜๊ฒŒ** ๋™์ž‘ํ•˜๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‹ฌ๋ผ์ง€๋Š” ๊ฑด ์ž…๋ ฅ์ด Discord ๋ฉ”์‹œ์ง€, ์ถœ๋ ฅ์ด ์ž„๋ฒ ๋“œ/์Šค๋ ˆ๋“œ๋ผ๋Š” **ํ‘œํ˜„ ๋ฐฉ์‹**๋ฟ์ž…๋‹ˆ๋‹ค. (ํ„ฐ๋ฏธ๋„์—์„œ ํƒ€์ดํ•‘ํ•˜๋Š” TUI ์ „์šฉ ์Šฌ๋ž˜์‹œ ๋ช…๋ น์€ ๊ทธ๋Œ€๋กœ ์น˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ SDK ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.)
164
- - **Codex ๋ชจ๋“œ** โ€” `codex exec`(๋น„๋Œ€ํ™”ํ˜•)๋กœ ๊ตฌ๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ Codex ์—”์ง„์— ์„ค์ •/MCP๋ฅผ ๋กœ๋“œํ•˜์ง€๋งŒ, **๋น„๋Œ€ํ™”ํ˜• ๋ชจ๋“œ๊ฐ€ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋ชจ๋“œ์™€ ์ผ๋ถ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์–ด**(์Šน์ธ ๋ฐฉ์‹ยทํŠน์ • ๊ธฐ๋Šฅ ๋“ฑ) **์„œ๋ธŒ์—์ด์ „ํŠธยท์Šคํ‚ฌยทMCP๊ฐ€ ๊ทธ๋Œ€๋กœ ๋˜๋Š”์ง€๋Š” Phase 2์—์„œ ์‹ค์ œ `codex` CLI๋กœ ๊ฒ€์ฆ**ํ•œ ๋’ค ํ™•์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์ฆ ์ „๊นŒ์ง€๋Š” ์™„์ „ ๋™์ผํ•˜๋‹ค๊ณ  ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
346
+ Messages you send in a session channel are forwarded to Claude/Codex verbatim, so **commands/skills defined under `.claude/commands/`, `.claude/skills/` (Claude) or `.codex/skills/` (Codex), as well as commands installed by plugins**, work exactly as they do in the terminal โ€” just type `/name` as-is (verified against the real Claude/Codex CLIs). This doesn't conflict with the bot's own Discord slash commands (`/agent`, `/config`, etc.) since it's just a plain text message in a session channel.
165
347
 
166
348
  ---
167
349
 
168
- ## ์„ค์ • ํŒŒ์ผ ์œ„์น˜
350
+ ## Configuration file locations
169
351
 
170
352
  ```
171
353
  ~/.discord-agent-bridge/
172
- โ”œโ”€ config.json # ๋ด‡ ํ† ํฐยทClient IDยท๊ธฐ๋ณธ๊ฐ’ยทํ•œ๋„ (๊ถŒํ•œ 600)
173
- โ”œโ”€ servers/<guildId>.json # ์„œ๋ฒ„๋ณ„ ์—ญํ•  ํ‹ฐ์–ดยท๊ธฐ๋ณธ๊ฐ’ + /init ์ฑ„๋„ ๊ตฌ์กฐ(control/sessions) ID (๊ถŒํ•œ 600)
174
- โ”œโ”€ state.json # ์ฑ„๋„โ†”์„ธ์…˜ ๋ฐ”์ธ๋”ฉ (์žฌ์‹œ์ž‘ ํ›„ ์ž๋™ ๋ณต๊ตฌ)
175
- โ””โ”€ audit/audit.jsonl # ๊ฐ์‚ฌ ๋กœ๊ทธ
354
+ โ”œโ”€ config.json # bot token ยท Client ID ยท defaults ยท limits (permissions 600)
355
+ โ”œโ”€ servers/<guildId>.json # per-server role tiers ยท defaults ยท channel structure (control/sessions/status) IDs ยท notification settings (permissions 600)
356
+ โ”œโ”€ state.json # channelโ†”session bindings (auto-restored after restart)
357
+ โ””โ”€ audit/audit.jsonl # audit log
176
358
  ```
177
- ์„ค์ •์€ **์ „์—ญ โ†’ ์„œ๋ฒ„ โ†’ ํ”„๋กœ์ ํŠธ** ์ˆœ์œผ๋กœ ๋ฎ์–ด์จ์ง‘๋‹ˆ๋‹ค.
359
+ Configuration is overridden in the order **global โ†’ server โ†’ project**.
178
360
 
179
361
  ---
180
362
 
181
- ## ๋ฌธ์ œ ํ•ด๊ฒฐ
363
+ ## Troubleshooting
182
364
 
183
- - **๋ด‡์ด ๋ฉ”์‹œ์ง€์— ๋ฐ˜์‘ํ•˜์ง€ ์•Š์•„์š”** โ†’ Developer Portal์—์„œ **Message Content Intent**๊ฐ€ ์ผœ์ ธ ์žˆ๋Š”์ง€ ํ™•์ธ.
184
- - **์Šฌ๋ž˜์‹œ ๋ช…๋ น์ด ์•ˆ ๋ณด์—ฌ์š”** โ†’ ์ดˆ๋Œ€ ์‹œ `applications.commands` ์Šค์ฝ”ํ”„๋ฅผ ํฌํ•จํ–ˆ๋Š”์ง€ ํ™•์ธ(๋“ฑ๋ก์— ๋ช‡ ๋ถ„ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Œ).
185
- - **๊ถŒํ•œ ์˜ค๋ฅ˜๋กœ ์ฑ„๋„ ์ƒ์„ฑ ์‹คํŒจ** โ†’ ๋ด‡์—๊ฒŒ `Manage Channels` ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํ™•์ธ.
186
- - **์‚ฌ์šฉ๋Ÿ‰ ํŒจ๋„์ด ์•ˆ ๋– ์š”** โ†’ Claude Pro/Max **๊ตฌ๋… ๋กœ๊ทธ์ธ**(`~/.claude`) ์ƒํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. API ํ‚ค๋งŒ ์“ฐ๋ฉด ์ด ํŒจ๋„์€ ์ˆจ๊ฒจ์ง‘๋‹ˆ๋‹ค(์ •์ƒ).
365
+ - **The bot doesn't respond to messages** โ†’ Check that **Message Content Intent** is enabled in the Developer Portal.
366
+ - **Slash commands don't show up** โ†’ Check that you included the `applications.commands` scope when inviting the bot (registration can take a few minutes).
367
+ - **Channel creation fails with a permission error** โ†’ Check that the bot has the `Manage Channels` permission.
368
+ - **The usage panel doesn't appear** โ†’ You need to be **logged in with a Claude Pro/Max subscription** (`~/.claude`). This panel is hidden (as expected) if you're only using an API key.
369
+ - **"No authorized role for this actor (fail-secure)."** โ†’ The account you signed in with has no role on the allow-list. This is deny-by-default. Fix it with one of these:
370
+ 1. **Simplest** โ€” give that account Discord's **server Administrator** permission. Administrators are unconditionally treated as the admin tier and bypass the allow-list.
371
+ 2. **Assign a listed role** โ€” in the Discord server's member list, give the account one of the roles that's already tied to a tier under `/config`.
372
+ 3. **Add the role to a tier** โ€” from an admin account, open `/config` โ†’ **Role tiers** and click the account's role into the tier you want (admin/execute/read-only).
187
373
 
188
374
  ---
189
375
 
190
- ## ๊ฐœ๋ฐœ
376
+ ## Development
191
377
 
192
378
  ```bash
193
379
  npm install
194
- npm run dev # tsx watch (๊ฐœ๋ฐœ ๋ชจ๋“œ)
195
- npm run typecheck # ํƒ€์ž… ๊ฒ€์‚ฌ
196
- npm run test # ํ…Œ์ŠคํŠธ (vitest)
380
+ npm run dev # tsx watch (dev mode)
381
+ npm run typecheck # type checking
382
+ npm run test # tests (vitest)
197
383
  ```
198
384
 
199
- ## ๋ผ์ด์„ ์Šค
385
+ ## License
200
386
 
201
387
  MIT
package/dist/app.js CHANGED
@@ -13,7 +13,7 @@ import { SessionOrchestrator } from './core/sessionOrchestrator.js';
13
13
  import { createLogger } from './core/logger.js';
14
14
  import { ClaudeMode } from './modes/claude/index.js';
15
15
  import { CodexMode } from './modes/codex/index.js';
16
- import { getClaudeModels, getClaudeModelsCachedOrFallback, getCodexModels } from './core/providerCatalog.js';
16
+ import { getClaudeModels, getCodexModels } from './core/providerCatalog.js';
17
17
  import { MessageRouter } from './discord/messageRouter.js';
18
18
  import { InteractionRouter } from './discord/interactionRouter.js';
19
19
  import { SessionWiring } from './discord/wiring.js';
@@ -126,12 +126,13 @@ export function createApp(deps) {
126
126
  // Per-backend model options from the central provider catalog (ยง providerCatalog).
127
127
  // Codex: a documented static default list (Codex has no model-list API; -m is
128
128
  // free-form), with config.defaults.codexModel offered first when set. Claude:
129
- // the SDK's supportedModels(), fetched once after login and CACHED โ€” this render
130
- // returns the cached English list if present, else the alias fallback while the
131
- // async fetch warms the cache for the next render (never blocks the ack).
132
- modelsFor: (backend) => backend === 'codex'
129
+ // the SDK's supportedModels(), probed live on EVERY /config or /agent start open
130
+ // (no cross-invocation cache) so a model added or removed on the account is
131
+ // reflected immediately. A short in-tick de-dupe still shares one probe across
132
+ // concurrent callers. On failure/timeout falls back to the alias list.
133
+ modelsFor: async (backend) => backend === 'codex'
133
134
  ? getCodexModels(config.defaults.codexModel)
134
- : getClaudeModelsCachedOrFallback({ logger }),
135
+ : await getClaudeModels({ logger }),
135
136
  });
136
137
  const discord = new DiscordClient({
137
138
  clientId: config.discord.clientId,
@@ -148,10 +149,6 @@ export function createApp(deps) {
148
149
  for (const binding of channelRegistry.list().filter((b) => !b.archived)) {
149
150
  await wiring.attach(binding.guildId, binding.channelId, binding.mode);
150
151
  }
151
- // Warm the Claude model cache now that auth is available (fire-and-forget): the
152
- // SDK's supportedModels() is fetched once and cached so the first /config or
153
- // /agent start shows the real, current model list instead of the alias fallback.
154
- void getClaudeModels({ logger });
155
152
  logger.info('boot complete', { guilds: client.guilds.cache.size });
156
153
  },
157
154
  // Auto-provision each guild's channel structure on ready / guild-join so /init is
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}