# 【サポート依頼】9. 配管をつなぐ(xangi) あなたは、これから下の手順を**自分の手で通す人**のサポート役です。 相手は Linux もサーバも初めてで、手元の PC は Windows です。 ## 守ってほしいこと 1. 相手は下の手順書を**上から順に**やっています。**先回りして別のやり方を勧めないでください。** どうしても別の手が要ると判断したときは、**そう判断した理由を1行**添えてください。 2. 詰まった画面のスクリーンショットや、エラーの文言が送られてきます。 **まず「下の手順書のどこで止まっているか」を特定**してから答えてください。 3. **一度に1つだけ**指示してください。結果を聞いてから次に進みます。 4. 専門用語は、初めて出たときに**かっこ書きで言い換え**を付けてください。 5. 分からないことは「**分かりません**」と答えてください。**推測でコマンドを出さないでください。** 6. この工程の「**終わりの印**」が出るまでは、次の工程の話をしないでください。 ## 絶対にしないこと - **Discord の Bot トークン・パスワード・SSH の秘密鍵**を、送るよう求めないでください。 - 相手がうっかり貼ってしまったら、**その場で作り直すよう伝えてください**(どれも作り直せます)。 ## 最初にお願いすること この工程で何をするのかを、**3行**で教えてください。 そのあと、私が「はじめます」と言ったら、**最初の1手だけ**を教えてください。 --- # 手順書(この工程の全文) # 9. 配管をつなぐ(xangi) xangi は Discord と Claude Code または Codex をつなぐ配管です。この章は Windows から SSH で進めます。pm2(プログラムを常駐させる道具)方式を使います。SSH 越しでも対話画面が要りません。動いていない原因は `pm2 logs` で追えます。 ## 1. xangi を取る ```bash cd && git clone https://github.com/karaage0703/xangi ``` ```bash cd ~/xangi cp .env.example .env ``` ## 2. `.env` を書く `.env` は、xangi の設定を書くファイルです。先に全体の地図を見ます。 - `.env.example` は **783行**あります。 - そのうち、値が入っている行は **3行だけ**です。 - 残りはすべて `#` で始まる説明文です。 - `#` で始まる行はメモ書きです。コメントとも言います。xangi は読みません。 **書き換えるのは、次の4か所だけです。**(下の表の上から順に説明します) | 行 | いまの中身 | どうするか | |---:|---|---| | **96行目** | `# WORKSPACE_PATH=...` | **先頭の `#` を消して、右腕の机の場所を書きます**(下で説明します) | | **4行目** | `DISCORD_TOKEN=your_discord_bot_token_here` | **右側を、4章で取ったトークンに書き換えます** | | **10行目** | `DISCORD_ALLOWED_USER=your_discord_user_id_here` | **右側を、自分の Discord ユーザーID に書き換えます。`*` にしません** | | **22行目** | `AGENT_BACKEND=codex` | **Codex を使うならそのままです。Claude Code を使うなら `claude-code` に書き換えます** | `=` の前後に空白は入れません。8章でログインできた方を選びます。片方だけでも進めます。 !!! tip "行番号が合わないときは" `.env.example` は更新されることがあるので、**行番号がずれることがあります。** そのときは行番号ではなく、**`Ctrl` + `W` で `DISCORD_TOKEN` などの名前を探して**ください(下の nano の説明にあります)。 ### 🔵 入口を Slack にする場合は、書き換える行が違います [4b章](04b_slack.md)で Slack を選んだ方は、上の表の代わりに**こちら**を書き換えます。 `.env.example` は Slack の設定も**全部 `#` で無効にしてある**ので、`#` を消すところが増えます。 | 行 | いまの中身 | どうするか | |---:|---|---| | **4行目** | `DISCORD_TOKEN=your_discord_bot_token_here` | 🔴 **行の先頭に `#` を付けて無効にします**(Discord を使わないため) | | **10行目** | `DISCORD_ALLOWED_USER=your_discord_user_id_here` | 🔴 同じく**先頭に `#` を付けます** | | **15行目** | `# SLACK_ALLOWED_USER=your_slack_user_id_here` | **`#` を消して**、自分の Slack ユーザーID(`U` で始まる)に | | **22行目** | `AGENT_BACKEND=codex` | 8章でログインできた方(`codex` または `claude-code`) | | **96行目** | `# WORKSPACE_PATH=...` | **`#` を消して** `/home/<ユーザー名>/workspace` に(下で説明します) | | **232行目** | `# SLACK_BOT_TOKEN=xoxb-your-bot-token` | **`#` を消して**、`xoxb-` のトークンに | | **233行目** | `# SLACK_APP_TOKEN=xapp-your-app-token` | **`#` を消して**、`xapp-` のトークンに | !!! tip "232行目まで一気に行くには" `nano` の中で **`Ctrl` + `W`** を押し、**`SLACK_BOT_TOKEN`** と入力して `Enter` を押します。 行番号を数える必要はありません。 ??? note "📄 `.env.example` の229〜233行目(実物・Slack のところ)" ここも**全部 `#` で無効**になっています。232行目と233行目の `#` を消して、右側を書き換えます。 ```text # ======================================== # Slack設定(Slack使う場合) # ======================================== # SLACK_BOT_TOKEN=xoxb-your-bot-token # SLACK_APP_TOKEN=xapp-your-app-token ``` !!! success "書けたら、有効な行はこの5行になります(Slack 版)" ```bash SLACK_ALLOWED_USER=U01234567 AGENT_BACKEND=claude-code WORKSPACE_PATH=/home/<ユーザー名>/workspace SLACK_BOT_TOKEN=xoxb-(4b章で取った長い文字列) SLACK_APP_TOKEN=xapp-(4b章で取った長い文字列) ``` **順番はバラバラで構いません。**ファイルの中では 15 / 22 / 96 / 232 / 233 行目に散っています。 🔴 **`DISCORD_TOKEN` と `DISCORD_ALLOWED_USER` の2行は、先頭に `#` が付いている**こと。 !!! danger "🔴 見本の文字を消し切ってください(2026-09-09 に実際に踏みました)" `# SLACK_BOT_TOKEN=xoxb-your-bot-token` の **`#` だけ消して、右側を消し忘れる**間違いが起きます。 `your-bot-token` のような文字が残っていると、Slack は **`invalid_auth`(その鍵は無効)**と返し、返事が来ません。 **`=` の右側は、まるごと消してから貼ってください。** 🔴 **`#` を消したあとに、行頭の空白を残さないこと。**` SLACK_BOT_TOKEN=...` のように 先頭に空白があると、確認のコマンドが拾えません。 !!! success "手で打たずに入れる方法(画面にトークンは出ません)" ```bash read -rsp "xoxb- で始まる Bot Token を貼って Enter: " BT; echo read -rsp "xapp- で始まる App Token を貼って Enter: " AT; echo sed -i -E -e "s|^[[:space:]]*#?[[:space:]]*SLACK_BOT_TOKEN=.*|SLACK_BOT_TOKEN=$BT|" \ -e "s|^[[:space:]]*#?[[:space:]]*SLACK_APP_TOKEN=.*|SLACK_APP_TOKEN=$AT|" \ -e "s|^DISCORD_TOKEN=|#DISCORD_TOKEN=|" \ -e "s|^DISCORD_ALLOWED_USER=|#DISCORD_ALLOWED_USER=|" ~/xangi/.env ``` そのあと、こう出れば正解です(**行頭に空白が無いこと**・`xoxb-` と `xapp-` で始まること)。 ```bash grep -nE "^(SLACK|AGENT_BACKEND|WORKSPACE_PATH)" ~/xangi/.env | sed -E 's/=(.{9}).*/=\1…/' ``` 書けたかの確認は、Slack の場合 **5行**出れば正解です。 ```bash grep -n -v "^#" ~/xangi/.env | grep -v "^$" # ← SLACK_ALLOWED_USER / AGENT_BACKEND / WORKSPACE_PATH / SLACK_BOT_TOKEN / SLACK_APP_TOKEN の5行 ``` ### もう1か所だけ、行の先頭の `#` を消します(96行目) **96行目は、いま `#` が付いていて効いていません。**ここだけは `#` を消して書き換えます。 ```bash # WORKSPACE_PATH=/path/to/your/workspace ← いまの状態(先頭に # がある) WORKSPACE_PATH=/home/<ユーザー名>/workspace ← こう直す(# を消して、右側を書き換える) ``` !!! danger "🔴 `/path/to/` を残さないでください(2026-09-09 に実際に踏みました)" 見本が `/path/to/your/workspace` なので、**`your` だけを自分の名前に替えて `/path/to/jsc-ai/workspace` にしてしまう**間違いが起きます。 **`/path/to/` ごと消して、`/home/` から書き直してください。** こうなると xangi は**起動した直後に落ちます**。pm2 が何度も起動し直すので、 一見動いているように見えますが、**チャットには一切返事が来ません。** !!! success "手で書かずに、この1行で入れるのが確実です" `nano` を使わずに、正しい値を入れられます。`$HOME` は「自分のホームフォルダ」に置き換わります。 ```bash sed -i "s|^#\? *WORKSPACE_PATH=.*|WORKSPACE_PATH=$HOME/workspace|" ~/xangi/.env grep -n "^WORKSPACE_PATH" ~/xangi/.env # ← /home/あなたの名前/workspace になっていること ``` **右腕の机を、道具の置き場と分けるため**です。ここを `#` のままにすると、 **xangi のプログラムが入っているフォルダが、そのまま机になります。** そこへ成果物が混ざると、あとで xangi を新しくするときにぶつかります。 机になるフォルダは、先に作っておきます。 ```bash mkdir -p ~/workspace ``` !!! note "こちらは触りません" **503行目の `# SKIP_PERMISSIONS=false` は触りません。** `#` が付いているため未設定です。未設定では、既定の `true` が効きます。`true` にするために何か書く必要はありません。 !!! danger "既定の SKIP_PERMISSIONS=true の意味" ファイル操作もコマンド実行も、毎回の確認なしで走ります。**この用途専用の隔離された機械**で使います。本業データの入った共用 PC では使いません。 ??? note "📄 `.env.example` の1〜30行目(実物)" 4行目、10行目、22行目が、上の表と対応します。 ```text # ======================================== # Discord設定(Discord使う場合) # ======================================== DISCORD_TOKEN=your_discord_bot_token_here # ======================================== # 許可ユーザー設定(必須) # ======================================== # Discord用(カンマ区切りで複数指定可、"*" で全員許可) DISCORD_ALLOWED_USER=your_discord_user_id_here # 複数ユーザー例: DISCORD_ALLOWED_USER=123456789,987654321 # 全員許可: DISCORD_ALLOWED_USER=* # Slack用(カンマ区切りで複数指定可、"*" で全員許可) # SLACK_ALLOWED_USER=your_slack_user_id_here # ======================================== # AIエージェント設定 # ======================================== # Agent backend: a built-in backend or an ID declared by a linked extension # This example recommends codex; the runtime fallback when omitted is claude-code. AGENT_BACKEND=codex # Optional: Model to use (backend-specific) # AGENT_MODEL= # Claude Code backend (AGENT_BACKEND=claude-code) # ANTHROPIC_API_KEY is passed only to the Claude Code child process. # Set CLAUDE_CODE_BARE=true to force Anthropic API-key auth instead of OAuth/keychain. # CLAUDE_CODE_MAX_BUDGET_USD limits API spend per Claude Code print-mode run. ``` ファイルを開きます。 ```bash nano .env ``` ??? note "✏️ nano の使い方(これだけ覚えれば足ります)" `nano` は、端末の中で文章を書き換える道具です。マウスでは動かせません。矢印キーを使います。 | やりたいこと | キー | |---|---| | 書き換える | 矢印キーでカーソルを動かして、そのまま打つ | | **保存する** | **`Ctrl` + `O` → `Enter`** | | **終わる** | **`Ctrl` + `X`** | | 保存せずに終わる | `Ctrl` + `X` → `N` | | 行を探す | `Ctrl` + `W` → 文字を入れて `Enter` | | 🔴 **貼り付ける**(トークンなど) | **`Ctrl` + `Shift` + `V`**、または**右クリック**。**`Ctrl` + `V` は効きません** | 画面の下に出る `^O` は、`Ctrl` + `O` の意味です。`^` が `Ctrl` を表します。 🔴 **トークンを貼るときは `Ctrl` + `V` ではなく `Ctrl` + `Shift` + `V`** です(3回目の注意です)。 貼れないときは**右クリック**を試してください。 ### 🔴 直すときは「行を丸ごと打ち直す」 **一部だけ書き換えようとすると、見本の文字が残ります。**2026-09-09 に2回踏みました。 次の順で、**行ごと消してから打ち直して**ください。 | | 操作 | |---|---| | 1 | **`Ctrl` + `W`** → 行の名前(例 `SLACK_BOT_TOKEN`)を打って `Enter` | | 2 | **`Ctrl` + `A`** … 行の先頭へ | | 3 | ⚠️ **`Ctrl` + `K`** … **その行を丸ごと切り取る**(飛んだ先が目的の行か、目で見てから) | | 4 | `SLACK_BOT_TOKEN=` と**手で打つ** | | 5 | **`Ctrl` + `Shift` + `V`** … 値を貼る | **行を止めたいだけ**のとき(`DISCORD_TOKEN` など)は、`Ctrl` + `W` で探して **`Ctrl` + `A` のあと `#` を1文字打つ**だけです。 4行目へ速く行くには、`Ctrl` + `W` で `DISCORD_TOKEN` を探します。同じ方法で `DISCORD_ALLOWED_USER` と `AGENT_BACKEND` を探すのが確実です。 保存して閉じたら、トークンを Windows のメモ帳から消します。書けた内容を確かめ、ファイルを本人だけが読める状態にします。 !!! danger "🔴 この確認の画面は、スクリーンショットに撮らないでください" 次のコマンドは、**トークンをそのまま画面に表示します。** サポート役のチャットAIに貼ると、**トークンを渡してしまうことになります。** 詰まってこの画面を見せたいときは、**トークンの部分を消してから**貼ってください。 うっかり送ってしまったら、[4章](04_discord_bot.md)の `Reset Token` で**作り直せます。** !!! success "書けたら、有効な行はこの4行になります(Discord 版)" ```bash DISCORD_TOKEN=(4章で取った長い文字列) DISCORD_ALLOWED_USER=123456789012345678 AGENT_BACKEND=claude-code WORKSPACE_PATH=/home/<ユーザー名>/workspace ``` **順番はバラバラで構いません。**ファイルの中では 4 / 10 / 22 / 96 行目に散っています。 ```bash grep -n -v "^#" ~/xangi/.env | grep -v "^$" # ← 4行だけ出て、右側が自分の値になっていれば OK chmod 600 ~/xangi/.env ``` ## 3. ビルドして常駐させる ```bash cd ~/xangi npm install # ← 3〜10分かかります ``` ```bash npm run build ``` ```bash npm install -g pm2 pm2 start "npm start" --name xangi pm2 logs xangi # ← 起動エラーが無いか。Ctrl+Cで表示だけ抜けます ``` ## 4. 再起動後も立ち上げる ```bash pm2 save pm2 startup # ← 表示されたコマンドを、そのまま実行する ``` `pm2 startup` 自体で終わりではありません。画面に「このコマンドを実行してください」と出た別のコマンドをコピーし、実行します。その後で保存します。 ```bash pm2 save sudo loginctl enable-linger $USER ``` 最後の1行は、SSH を切った後もユーザーのサービスを保つ設定です。 ## 別の道 xangi には公式インストーラもあります。この手順では扱いません。公式インストーラは対話画面で設定を進めます。SSH 越しでは画面がうまく出ないことがあります。ここでは pm2 方式にそろえます。 ## ✅ ここまで出来たら `pm2 logs xangi` に起動を止めるエラーがなく、Discord の Bot がオンラインになれば合格です。会話の判定は10章で行います。 ## 詰まったら | 症状 | まず見るところ | |---|---| | Bot がオフライン | `pm2 logs xangi`。トークン前後の空白も確認します | | backend が見つからない | 22行目が `AGENT_BACKEND=codex` または `AGENT_BACKEND=claude-code` か確認します | | 許可されていない | `DISCORD_ALLOWED_USER` が自分のIDか確認します | | `.env` を書いたのに反映されない | `grep -n -v "^#" ~/xangi/.env \| grep -v "^$"` で、有効な4行を確認します | | 右腕が机を見つけられない | 96行目の `WORKSPACE_PATH` の `#` を消したか、`mkdir -p ~/workspace` をしたか | | ビルドでエラー | `node -v` が v22 以降か確認します | | 🔴 **直したのに、ログに同じエラーが出続ける** | **古いエラーが残っているだけかもしれません。**`pm2 flush xangi` でログを空にしてから、`pm2 restart xangi --update-env` → 25秒待って見直します(2026-09-09 にこれで2回誤診しました) | | 🔴 **返事が全く来ない/`pm2 list` の ↺ が増え続ける** | `pm2 logs xangi --lines 40 --nostream` を見ます。`EACCES ... mkdir '/path/to/...'` なら **96行目に `/path/to/` が残っています**(上の1行で直せます) | | `.env` を書き換えたのに変わらない | 🔴 **`pm2 restart xangi --update-env`** をします。pm2 は起動時の設定を持ったままです | | 再起動後に止まる | `pm2 startup` が表示したコマンドと、`loginctl enable-linger` を実行したか確認します | **8章で Claude Code または Codex を入れてあります。** サーバの中で `claude` または `codex` と打てば、この機械の中を実際に見て直してくれます。とくに自動起動の設定は手で写すと間違えやすいため、頼むのが早いです。次をそのまま貼れます。 ```text このサーバで pm2 で動かしている xangi が、再起動したあとに自動で立ち上がるようにしてください。 いまの状態を確認してから、必要な操作だけを実行してください。 実行したコマンドと、その結果を最後に報告してください。 うまくいかない場合は、工夫して先へ進まず、そこで止めて状況を教えてください。 ``` !!! warning "AI が実行した内容を目で確認します" この機械は、確認なしでコマンドが走る設定です。何をしたかを最後に報告させて、必ず目で見てください。 次は [10. 第1関門](10_first_talk.md) です。