discord-bridge 0.1.2 → 0.1.4

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.
package/AGENTS.md ADDED
@@ -0,0 +1,28 @@
1
+ # AGENTS.md
2
+
3
+ ## プロジェクト概要
4
+
5
+ discord-bridge - Claude Code と Discord の双方向通信ブリッジ(npm パッケージ)
6
+
7
+ ## 技術スタック
8
+
9
+ - Node.js (ESM)
10
+ - discord.js v14
11
+ - Express v5
12
+
13
+ ## プロジェクト構成
14
+
15
+ - `bin/` - CLI エントリーポイント
16
+ - `server/` - HTTP API サーバー・Discord Bot
17
+ - `plugin/` - Claude Code プラグイン(`discord-bridge install` で配置されるファイル群)
18
+
19
+ ## バージョニング
20
+
21
+ - 変更を加えたら `package.json` の `version` を更新する
22
+ - 毎回 patch バージョンを上げる(例: `0.1.2` → `0.1.3`)
23
+ - npm publish は手動で行うため、バージョン更新のみ行えばよい
24
+
25
+ ## コーディング規約
26
+
27
+ - 作業・コメント・PR は日本語で記載する
28
+ - コミットメッセージは日本語で簡潔に
package/README.md CHANGED
@@ -10,7 +10,7 @@ Claude Code と Discord の双方向通信ブリッジ。スマホから Claude
10
10
  - **メッセージ取得** - ユーザーからの指示を取得
11
11
  - **リアルタイム待機** - SSE 接続で次の指示を待機
12
12
  - **離席モード** - ターミナルを離れても Discord 経由で操作
13
- - **Hooks** - 通知・停止イベントを自動で Discord に転送
13
+ - **Claude Code / Codex 対応** - どちらのプラットフォームにもスキルをインストール可能
14
14
 
15
15
  ## インストール
16
16
 
@@ -37,6 +37,7 @@ Discord の設定 → 詳細設定 → **開発者モード** を有効化して
37
37
 
38
38
  - **チャンネル ID**: チャンネル名を右クリック → "チャンネル ID をコピー"
39
39
  - **ユーザー ID**: 自分の名前を右クリック → "ユーザー ID をコピー"
40
+ - Bot に指示を出すユーザー(自分自身)の ID です。Bot があなたからのメッセージだけを処理するために使います
40
41
 
41
42
  ### 3. 環境変数の設定
42
43
 
@@ -47,7 +48,7 @@ export DISCORD_BRIDGE_TOKEN="your_bot_token_here"
47
48
  export DISCORD_BRIDGE_USER_ID="your_user_id_here"
48
49
  ```
49
50
 
50
- 設定後: `source ~/.zshrc`
51
+ 設定後、現在のターミナルに反映するには `source ~/.zshrc` を実行してください(新しいターミナルを開く場合は不要です)。
51
52
 
52
53
  ### 4. プロジェクト設定
53
54
 
@@ -59,31 +60,66 @@ Claude Code を使うプロジェクトのルートに `.discord-bridge.json`
59
60
  }
60
61
  ```
61
62
 
62
- ### 5. Claude Code プラグインのインストール
63
+ > **Note**: チャンネル ID は秘密情報ではありませんが、プロジェクト固有の設定です。チームで共有する場合はそのままコミットし、個人用の場合は `.gitignore` に追加してください。
64
+
65
+ ### 5. スキルのインストール
66
+
67
+ プラットフォームを指定してインストールします:
63
68
 
64
69
  ```bash
65
- discord-bridge install
70
+ # Claude Code の場合(プロジェクトローカル)
71
+ discord-bridge install claude
72
+
73
+ # Codex の場合(プロジェクトローカル)
74
+ discord-bridge install codex
66
75
  ```
67
76
 
68
- Claude Code を再起動してプラグインを読み込みます。
77
+ `--user` を付けるとホームディレクトリにインストールされ、全プロジェクトで利用できます:
69
78
 
70
- ## 使い方
79
+ ```bash
80
+ # Claude Code(ユーザー全体)
81
+ discord-bridge install claude --user
71
82
 
72
- ### サーバーの起動
83
+ # Codex(ユーザー全体)
84
+ discord-bridge install codex --user
85
+ ```
86
+
87
+ | コマンド | インストール先 |
88
+ |---|---|
89
+ | `install claude` | `.claude/skills/discord-comm/` |
90
+ | `install claude --user` | `~/.claude/skills/discord-comm/` |
91
+ | `install codex` | `.agents/skills/discord-comm/` |
92
+ | `install codex --user` | `~/.agents/skills/discord-comm/` |
93
+
94
+ インストール後、エージェントを再起動してスキルを読み込みます。
95
+
96
+ ### 6. 動作確認
97
+
98
+ サーバーを起動して接続を確認します:
73
99
 
74
100
  ```bash
75
101
  discord-bridge start
76
102
  ```
77
103
 
78
- ### ヘルスチェック
104
+ 別のターミナルでヘルスチェック:
79
105
 
80
106
  ```bash
81
107
  discord-bridge status
82
108
  ```
83
109
 
84
- ### Claude Code での利用
110
+ `{"status":"ok","bot":"BotName#1234",...}` のようなレスポンスが返れば成功です。
111
+
112
+ ## 使い方
113
+
114
+ ### サーバーの起動
115
+
116
+ ```bash
117
+ discord-bridge start
118
+ ```
119
+
120
+ ### エージェントでの利用
85
121
 
86
- Claude Code で以下のように話しかけてください:
122
+ Claude Code や Codex で以下のように話しかけてください:
87
123
 
88
124
  - 「Discord にテスト通知を送って」 - 通知テスト
89
125
  - 「離席する」 - 離席モード(Discord 経由で操作)
package/bin/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { fileURLToPath } from "url";
4
- import { dirname, join } from "path";
4
+ import { dirname, join, resolve } from "path";
5
5
  import { spawn } from "child_process";
6
- import { cpSync, existsSync, mkdirSync } from "fs";
6
+ import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
7
 
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = dirname(__filename);
@@ -23,24 +23,66 @@ switch (command) {
23
23
  }
24
24
 
25
25
  case "install": {
26
+ const platform = process.argv[3];
27
+ const hasUserFlag = process.argv.includes("--user");
28
+
29
+ if (!platform || !["claude", "codex"].includes(platform)) {
30
+ console.error("Usage: discord-bridge install <claude|codex> [--user]");
31
+ console.error("");
32
+ console.error("Platforms:");
33
+ console.error(" claude Install skill for Claude Code (.claude/skills/)");
34
+ console.error(" codex Install skill for Codex (.agents/skills/)");
35
+ console.error("");
36
+ console.error("Options:");
37
+ console.error(" --user Install to home directory instead of project directory");
38
+ process.exit(1);
39
+ }
40
+
26
41
  const home = process.env.HOME;
27
42
  if (!home) {
28
43
  console.error("HOME environment variable is not set");
29
44
  process.exit(1);
30
45
  }
31
- const target = join(home, ".claude", "plugins", "discord-bridge");
32
- const source = join(packageRoot, "plugin");
46
+
47
+ const skillDirs = {
48
+ claude: ".claude/skills",
49
+ codex: ".agents/skills",
50
+ };
51
+
52
+ const base = hasUserFlag ? home : process.cwd();
53
+ const target = join(base, skillDirs[platform], "discord-comm");
54
+ const source = join(packageRoot, "plugin", "skills", "discord-comm");
33
55
 
34
56
  if (!existsSync(source)) {
35
- console.error("Plugin files not found");
57
+ console.error("Skill files not found");
36
58
  process.exit(1);
37
59
  }
38
60
 
39
61
  mkdirSync(target, { recursive: true });
40
62
  cpSync(source, target, { recursive: true });
41
- console.log(`Plugin installed to ${target}`);
63
+
64
+ // Replace script path placeholders in SKILL.md
65
+ const skillMdPath = join(target, "SKILL.md");
66
+ if (existsSync(skillMdPath)) {
67
+ const absoluteTarget = resolve(target);
68
+ let content = readFileSync(skillMdPath, "utf-8");
69
+ content = content.replaceAll(
70
+ "$CLAUDE_PLUGIN_ROOT/skills/discord-comm",
71
+ absoluteTarget
72
+ );
73
+ writeFileSync(skillMdPath, content);
74
+ }
75
+
76
+ const scope = hasUserFlag ? "user" : "project";
77
+ console.log(`Skill installed to ${target}`);
78
+ console.log(` Platform: ${platform}`);
79
+ console.log(` Scope: ${scope}`);
42
80
  console.log("");
43
- console.log("Restart Claude Code to load the plugin.");
81
+ if (platform === "claude") {
82
+ console.log("Restart Claude Code to load the skill.");
83
+ } else {
84
+ console.log("Restart Codex to load the skill.");
85
+ }
44
86
  break;
45
87
  }
46
88
 
@@ -58,13 +100,13 @@ switch (command) {
58
100
  }
59
101
 
60
102
  default:
61
- console.log("discord-bridge - Claude Code <-> Discord communication bridge");
103
+ console.log("discord-bridge - Claude Code / Codex <-> Discord communication bridge");
62
104
  console.log("");
63
105
  console.log("Usage: discord-bridge <command>");
64
106
  console.log("");
65
107
  console.log("Commands:");
66
- console.log(" start Start the Discord bridge server");
67
- console.log(" install Install Claude Code plugin to ~/.claude/plugins/");
68
- console.log(" status Check server health");
108
+ console.log(" start Start the Discord bridge server");
109
+ console.log(" install <claude|codex> [--user] Install skill for the specified platform");
110
+ console.log(" status Check server health");
69
111
  break;
70
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-bridge",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Claude Code <-> Discord bidirectional communication bridge",
5
5
  "type": "module",
6
6
  "bin": {
package/server/index.js CHANGED
@@ -141,7 +141,7 @@ async function initDiscord() {
141
141
  resolve();
142
142
  return;
143
143
  }
144
- discordClient.once("ready", resolve);
144
+ discordClient.once("clientReady", resolve);
145
145
  discordClient.once("error", reject);
146
146
  });
147
147
 
@@ -1,8 +0,0 @@
1
- {
2
- "name": "discord-bridge",
3
- "description": "Bidirectional communication bridge between Claude Code and Discord. Send questions, receive instructions, share files, and get progress updates through a dedicated Discord channel.",
4
- "version": "0.1.0",
5
- "author": {
6
- "name": "naichi"
7
- }
8
- }
package/plugin/README.md DELETED
@@ -1,17 +0,0 @@
1
- # Discord Bridge Plugin for Claude Code
2
-
3
- Claude Code と Discord の双方向通信ブリッジ。スマホから Claude Code を操作できます。
4
-
5
- ## セットアップ
6
-
7
- このプラグインは `discord-bridge install` コマンドで自動的にインストールされます。
8
-
9
- 詳しいセットアップ手順はリポジトリの README を参照してください:
10
- https://github.com/naichilab/discord-bridge-server
11
-
12
- ## 使い方
13
-
14
- Claude Code で以下のように話しかけてください:
15
-
16
- - 「Discord にテスト通知を送って」 - 通知テスト
17
- - 「離席する」 - 離席モード(Discord 経由で操作)
@@ -1,27 +0,0 @@
1
- {
2
- "description": "Discord bridge hooks for forwarding notifications and stop events",
3
- "hooks": {
4
- "Notification": [
5
- {
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/notify-discord.sh",
10
- "timeout": 15
11
- }
12
- ]
13
- }
14
- ],
15
- "Stop": [
16
- {
17
- "hooks": [
18
- {
19
- "type": "command",
20
- "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-hook.sh",
21
- "timeout": 10
22
- }
23
- ]
24
- }
25
- ]
26
- }
27
- }
@@ -1,36 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
-
4
- # Read hook input from stdin
5
- HOOK_INPUT=$(cat)
6
-
7
- DISCORD_TOKEN="${DISCORD_TOKEN:-}"
8
- DISCORD_CHANNEL_ID="${DISCORD_CHANNEL_ID:-}"
9
-
10
- if [[ -z "$DISCORD_TOKEN" ]] || [[ -z "$DISCORD_CHANNEL_ID" ]]; then
11
- exit 0
12
- fi
13
-
14
- # Extract notification message
15
- NOTIFICATION=$(echo "$HOOK_INPUT" | /usr/bin/python3 -c "
16
- import sys, json
17
- try:
18
- data = json.load(sys.stdin)
19
- print(data.get('notification', data.get('message', 'Claude Code notification')))
20
- except:
21
- print('Claude Code notification')
22
- " 2>/dev/null || echo "Claude Code notification")
23
-
24
- # Send via Discord REST API
25
- curl -s -X POST \
26
- "https://discord.com/api/v10/channels/${DISCORD_CHANNEL_ID}/messages" \
27
- -H "Authorization: Bot ${DISCORD_TOKEN}" \
28
- -H "Content-Type: application/json" \
29
- -d "$(/usr/bin/python3 -c "
30
- import json, sys
31
- msg = sys.argv[1]
32
- print(json.dumps({'embeds': [{'title': 'Notification', 'description': msg, 'color': 3447003}]}))
33
- " "$NOTIFICATION")" \
34
- > /dev/null 2>&1
35
-
36
- exit 0
@@ -1,35 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
-
4
- HOOK_INPUT=$(cat)
5
-
6
- DISCORD_TOKEN="${DISCORD_TOKEN:-}"
7
- DISCORD_CHANNEL_ID="${DISCORD_CHANNEL_ID:-}"
8
-
9
- if [[ -z "$DISCORD_TOKEN" ]] || [[ -z "$DISCORD_CHANNEL_ID" ]]; then
10
- exit 0
11
- fi
12
-
13
- # Extract stop reason
14
- REASON=$(echo "$HOOK_INPUT" | /usr/bin/python3 -c "
15
- import sys, json
16
- try:
17
- data = json.load(sys.stdin)
18
- print(data.get('reason', data.get('stopReason', 'Task completed')))
19
- except:
20
- print('Task completed')
21
- " 2>/dev/null || echo "Task completed")
22
-
23
- # Send stop notification
24
- curl -s -X POST \
25
- "https://discord.com/api/v10/channels/${DISCORD_CHANNEL_ID}/messages" \
26
- -H "Authorization: Bot ${DISCORD_TOKEN}" \
27
- -H "Content-Type: application/json" \
28
- -d "$(/usr/bin/python3 -c "
29
- import json, sys
30
- msg = sys.argv[1]
31
- print(json.dumps({'embeds': [{'title': 'Claude Code Stopped', 'description': msg, 'color': 15158332}]}))
32
- " "$REASON")" \
33
- > /dev/null 2>&1
34
-
35
- exit 0