# dsh-line-bot

<p align="center"><img src="icon.svg" width="96" height="96" alt="dsh-line-bot"></p>

**言語 / Languages:** [繁體中文](README.md) · [简体中文](README.zh-CN.md) · [English](README.en.md) · [日本語](README.ja.md) · [한국어](README.ko.md)

LINE 公式アカウント（Messaging API）を DeepSeek Harness につなぐプラグインです。返信は DSH の Agent が**同じプロセス内**で生成するため、LINE 上で自分の DSH アシスタントと会話している感覚になります。ペルソナは、大肥魚（`dsh-persona-dafeiyu`）がインストールされていればそのペルソナをそのまま選べますし、どのペルソナプラグインもなしでプラグイン内蔵のカスタムペルソナだけを使うこともできます。

内蔵機能：

- **Webhook サーバー**：ローカルの `127.0.0.1` に HTTP サーバーを開き、LINE の `X-Line-Signature` 検証、イベントの重複排除、ユーザーごとのキューを処理します。
- **Cloudflare Tunnel**：ワンクリックの quick tunnel（`*.trycloudflare.com`、Cloudflare アカウント不要）、または Cloudflare API トークンを貼り付けて名前付きトンネル＋DNS を作成し固定 URL を取得します。URL が取得できたら webhook エンドポイントを LINE に書き戻し、`webhook/test` を実行します。
- **LINE 認証情報**：Channel ID と Channel Secret を入力すれば access token を自動発行（`/v2/oauth/accessToken`、約 30 日、期限が近づくと自動更新）。既存の Channel Access Token を貼り付けることもできます。
- **大肥魚プラグインがない場合**：プラグイン内蔵の繁体字中国語版（大肥魚／阿茶／聽瀾）に自動で切り替わります。同じ `personas.json` に保存され、カスタムペルソナと同じように編集できます。大肥魚を入れ直すと自動でそちらに戻ります。
- **自発メッセージ**：プラグイン内蔵のスケジューラー（launchd 不要）。ユーザーごとに独立したランダムなカウントダウン（最短～最長間隔）を持ち、時間が来て相手の沈黙が十分長いときだけ話しかけます。最短／最長間隔、1 日／1 か月の上限、最低間隔、静かな時間帯、idle、連続未返信の上限（上限に達したら一時停止、相手が返信したらリセット）、対象ユーザー、プロンプトを設定できます。Agent が「今は違う」と判断したら `SKIP` を返して見送れます。
- **連続メッセージの結合**：モデルが前の返信を処理している間に追加のメッセージが届いた場合、キューに入れておき、そのターンが終わってからまとめて一度に返信します。
- **分割返信**：返信を空行（段落）または改行ごとに最大 5 つの LINE メッセージに分割できます。1 つの長い吹き出しに詰め込まずに送れます。パネルで方式の切り替えやオフも可能です。
- **充実した設定パネル**：設定はすべて「設定 → LINE Bot」にあり、`<DSH_HOME>/line-bot/config.json`（モード 600）に保存されます。

> 「LINE Business ID でログインしてパネルから bot を作る」ことについて：LINE は 2024-09 以降、Messaging API チャネルの作成を [LINE Official Account Manager](https://manager.line.biz/) での手動操作のみに制限しており、公開 API はありません。LINE Login も本人確認だけで、公式アカウントの管理権限は取得できません。そのためパネルは bot を作成しませんが、正しい入口リンクを提示し、「Channel ID / Secret を取得した後」の作業（トークン発行、webhook 設定、テスト）を自動化します。

## インストール

要件：DeepSeek Harness **≥ 0.2.0-rc.1**、Node.js **≥ 22**。ペルソナプラグイン（大肥魚 `dsh-persona-dafeiyu`）は**任意**です — インストールしなくてもプラグイン内蔵のカスタムペルソナが使えます。

### 方法 1：パネルからインストール（推奨）

DSH → **設定 → プラグイン → bundle をインストール** で `dsh-line-bot` を入力してインストールし、ページを再読み込みします。設定の左側に **LINE Bot** が追加されます。

### 方法 2：npx でワンコマンドインストール

まず DSH を完全に終了します（デスクトップ版ならウィンドウを閉じ、メニューバー／プロセスが残っていないことを確認）。その後に実行します。

```bash
npx dsh-line-bot install
```

どの profile に入れるかを自動判定し（既定は `desktop`、`--profile <名前>` で指定可）、DSH 内蔵の pnpm でパッケージをインストールし、bundle を profile に追加して、DSH の再起動を促します。

```bash
npx dsh-line-bot status      # どの profile に入っているか、有効かどうか
npx dsh-line-bot uninstall   # 削除（設定と認証情報は残ります）
```

### 方法 3：手動

```bash
dsh plugin --profile desktop add dsh-line-bot
```

その後 `~/.dsh/profiles/desktop/package.json` の `dsh.profile.bundles` 配列に `dsh-line-bot` を追加します（`npx dsh-line-bot install` の動作を参考にしてください）。パネルからのインストールでも構いません。

> まだ npm に公開していない場合は、GitHub から直接インストールできます。
>
> ```bash
> npx github:Hanson0901/dsh-line-bot install --spec github:Hanson0901/dsh-line-bot
> ```
>
> ソースからなら：`git clone https://github.com/Hanson0901/dsh-line-bot.git` して、DSH パネルの「bundle をインストール」でそのフォルダを選ぶか、`dsh plugin --profile desktop add /path/to/dsh-line-bot` を実行します。

## 連携プラグイン（任意）

LINE Bot は単体でも動きます。以下を入れると機能が増えます：

| プラグイン | 追加される機能 | 推奨 |
| --- | --- | --- |
| `dsh-persona-dafeiyu` | ペルソナ一覧と貼吧同期 | 推奨 |
| `dsh-meme` | 画像／スタンプ返信 | 推奨 |
| `dsh-tieba-dive` | 貼吧学習同期の取得元 | 任意 |

インストール CLI は不足を検出して、一緒に入れるか確認します：

```bash
npx dsh-line-bot install --with-companions
npx dsh-line-bot install --no-companions
```

ない場合の影響：大肥魚なし → プラグイン内のペルソナのみ、dsh-meme なし → テキストのみ、貼吧プラグインなし → 貼吧同期は停止。

## 初回セットアップ（5 ステップ）

1. **認証情報を用意**：[LINE Official Account Manager](https://manager.line.biz/) で公式アカウントを作成 → [LINE Developers Console](https://developers.line.biz/console/) で Messaging API チャネルを作成（または選択）→ 「Messaging API」タブで **Use webhook** をオン → **Channel ID** と **Channel secret** をコピーします。
2. **パネルに入力**：「LINE Bot → LINE 認証情報」に Channel ID と Channel Secret を貼り、「変更を保存」→「検証して bot 情報を取得」を押します。成功すると bot 名と Basic ID が表示されます。
3. **webhook サーバーを起動**：「概要」で「すべて起動」を押すか、「起動」を押して webhook サーバーとトンネルを両方立ち上げます（既定で自動起動します）。
4. **トンネルを開く**：Quick tunnel なら「トンネルを起動」を押すだけ。固定 URL が必要なら「Cloudflare Tunnel」で API トークンを貼り →「API トークンを検証」→「トンネルと DNS を作成／更新」（トークン権限：Account → Cloudflare Tunnel → Edit、Zone → DNS → Edit、Zone → Zone → Read）。quick tunnel は再起動のたびに URL が変わります（プラグインが新しい URL を LINE webhook に自動で書き戻します）。名前付きトンネルの URL は固定です。
5. **webhook を自動設定**：トンネルの準備ができると自動で LINE に PUT します。失敗したら「トンネル URL を webhook に適用」→「webhook をテスト」を押します。あとは LINE で bot を友だち追加してメッセージを送ります。最初のメッセージは「承認待ち」に入るので、パネルの「ユーザー」で自分の userId を承認してください（許可リストは初期状態では空です）。

## パネルの各セクション

パネル上部には**固定（sticky）保存バー**があり、どこまでスクロールしても「変更を保存／再読み込み」が見えます。その下にはクイックナビがあり、押すと該当セクションへジャンプします（スクロール中は現在のセクションが自動でハイライトされます）。

| セクション | 内容 |
| --- | --- |
| 概要 | webhook サーバー／トンネル／LINE／ペルソナ／自発メッセージの状態、公開 URL、ワンクリック起動と停止 |
| LINE 認証情報 | Channel ID、Channel Secret、Access Token、自動発行、ローディング表示、分割返信、bot 情報、webhook の適用／テスト、許可リスト |
| Cloudflare Tunnel | quick／API トークンモード、トークン、hostname、トンネル名、Account／Zone ID、cloudflared のダウンロード、起動／停止、webhook 自動設定、独自の公開 URL |
| モデルとプロバイダー | LINE 返信で使う provider／モデルと推論強度を選択。deepseek-account 以外では DeepSeek 残高を自動で無効化 |
| 返信ペルソナ | ペルソナ選択（大肥魚またはプラグインのカスタム）、カスタムペルソナの追加・編集・削除、現在のペルソナをカスタムに複製、強制適用、ユーザーによる切り替え許可、大肥魚を session モードに切り替え、Agent 返信のテスト |
| 貼吧学習の同期 | 貼吧で学んだ口調をペルソナに書き戻す（内蔵ペルソナはオーバーレイ）、差分プレビュー、今すぐ同期 |
| ジョーク | テキストネタ集：内蔵シード、貼吧名台詞、wanjiqi 弾幕ネタ。ソース別の切り替え、ターンごとの注入数、追加／削除 |
| 個人メモリ | ユーザーごとの長期記憶、期限切れの自動削除、毎日の自己整理、手動削除 |
| 表情パック | dsh-meme の画像ライブラリで画像／スタンプを返信、オンオフ、1 回の上限、サンプル表示 |
| 音声返信 | CosyVoice3 による音声合成、オンオフ、参照音声アップロード、instruct、試聴 |
| スタンプ・画像理解 | LINE スタンプや通常の画像を受信したら取得してモデルに見せる。画像非対応モデルは modlens や別の視覚モデルで説明（オフ可） |
| DeepSeek 残高 | 現在の残高、毎ターンの注入、残高が少ないときの主動リマインド、しきい値とクールダウン（deepseek-account のみ） |
| 自発メッセージ | オン／オフ、ユーザーごとのカウントダウン、最短／最長間隔、連続未返信の上限、1 日／1 か月の上限、最低間隔、静かな時間帯、idle、対象ユーザー、プロンプト、今すぐ試送、統計（次回予定と一時停止中の人数） |
| ユーザー | LINE ユーザーごとに対応する DSH セッション、専用ワークスペース、現在のペルソナ（直接変更可）、メッセージ数、最終やりとり、メモリ消去／セッション再作成 |
| グループ | グループごとのセッション、ワークスペース、ペルソナ、メッセージ数；呼ばれていないときの返信確率；@／引用時は必ず返信；グループのメモリ消去 |
| 詳細設定 | ポート、Agent の provider/model/effort/cwd/タイムアウト、ユーザーごとのワークスペース（ルート含む）、ウェルカム／エラー／空返信、ログ、開発用 host リロード |

## 設定ファイル

- `<DSH_HOME>/line-bot/config.json`：すべての設定。LINE secret と Cloudflare トークンを含みます（モード 600、平文はパネルに返しません）。
- `<DSH_HOME>/line-bot/state.json`：LINE ユーザー ↔ DSH セッションの対応、メッセージ数、自発メッセージのカウント、webhook 状態。
- `<DSH_HOME>/line-bot/logs/YYYY-MM-DD.log`：日次ログ（パネルにも直近 400 行を表示）。

`DSH_HOME` の既定は `~/.dsh` です。

## 動作の仕組み

1. LINE がメッセージを Cloudflare トンネルに POST → プラグインの webhook サーバー（署名検証後すぐに 200 を返す）。
2. `userId` から対応する DSH セッションとワークスペースを探し（なければ作成）、そのセッションのペルソナを決めます。大肥魚を選んだ場合は大肥魚の HTTP bridge 経由でセッションペルソナを指定し、プラグインのカスタムペルソナを選んだ場合はまず大肥魚にそのセッションで退いてもらい（`none`）、プラグインがカスタムペルソナを system prompt に注入します。
3. `agents.create`／`agents.resume` で同じ DSH プロセス内に Agent を作成／再開し、`followup` でユーザーメッセージを 1 件送り、ターン終了・サブエージェントの収束・セッションの flush を待ちます。
4. セッションイベントから最後の assistant テキストを取り出し、LINE の reply で返信します。reply token が切れていたら自動で push に切り替えます。
5. スケジューラーは 1 分ごとに各ユーザーのカウントダウンを確認し、時間が来て相手の沈黙が十分長ければ Agent に一言話してもらって push します。連続未返信が上限に達したら一時停止し、相手が返信したら再びカウントダウンします。

## モデルとプロバイダー

「モデルとプロバイダー」カードは LINE 返信で使う provider／モデルを決めます：

- provider はこの DSH profile に登録されているもの、モデルはライブで取得し、provider を選ぶと最初のモデルが入ります。
- 「DSH のデフォルトに従う」は `agentDefaultModel` の provider／model をそのまま使います（実際の値はパネルに表示）。
- 推論強度は空欄なら provider のデフォルト。
- provider が `deepseek-account` のときだけ DeepSeek 残高と残高リマインドが動きます。他の provider ではカードがグレーアウトして無効になり、戻すと復帰します。

## ペルソナのソース

- **大肥魚（任意）**：`dsh-persona-dafeiyu` がインストールされていると、パネルにそのペルソナ（内蔵＋自作）が表示されます。LINE ではセッション単位で指定され、GUI の他の会話には影響しません。`session` モードである必要があり、パネルが案内してワンクリックで切り替えられます。
- **プラグイン内蔵のカスタムペルソナ**：ペルソナプラグインは不要です。「返信ペルソナ → カスタムペルソナ」で追加・編集・削除でき、データは `<DSH_HOME>/line-bot/personas.json`（0600）に保存されます。カスタムペルソナを選ぶと、プラグインは（インストールされていれば）大肥魚にそのセッションでの停止を依頼し、カスタムペルソナをその agent の system prompt に注入します。
- どちらも同じドロップダウンから選べます。ユーザーが LINE コマンドで切り替える場合も同じです（`人設`、`人設 2`、`人設 名前`）。

## グループと複数人チャット

Bot がグループ（または複数人のルーム）に追加されたとき：

- **@ で呼ばれたら必ず返信**、**引用（返信）されたら必ず返信**します。それ以外は「グループ返信確率」（既定 15%）の抽選に当たったときだけ返信します。
- グループごとに **DSH セッション・ワークスペース・ペルソナ・個人メモリ** を持ち、1 対 1 のチャットや他のグループとは分かれています。
- グループでも `人設` コマンドが使えます。パネルの「グループ」カードで返信確率・スイッチ・グループごとのペルソナ・メモリの消去を設定できます。
- グループ内でも**メンバーごとに別々の記憶**を持ちます。返信時は直近 4～6 件の他人のメッセージも参考にして話を拾います。
- グループに後から参加した場合は、パネルの「グループ」カードで **チャットを読み込む** を押し、LINE が書き出した `.txt` を選ぶと、グループ要約とメンバーごとの記憶ポイントを作ります（保存はローカルのみ）。
- 自発メッセージと DeepSeek 残高の通知は 1 対 1 の相手にだけ送られます。

## ユーザーごとのメモリとペルソナ

- **メモリは共有されません**：LINE ユーザーごとに専用の DSH セッションと、専用の Agent ワークスペース `<DSH_HOME>/line-bot/users/<LINE userId>/` を持ちます。Agent が見るファイル、`AGENTS.md`、ワークスペースメモリはそのユーザー専用で、他人のものは読みません。
  「詳細設定 → ユーザーごとのフォルダ」でオフにできます（オフにすると全員が `agent.cwd` を共有し、以前の動作に戻ります）。`agent.workspaceRoot` でルートを指定することもできます。
- **ペルソナを自分で選べる**：「返信ペルソナ → ユーザーによるペルソナ切り替えを許可」がオンのとき、LINE ユーザーは次を送れます。
  - `人設`（または `人格`／`persona`）→ 利用可能なペルソナと現在のペルソナを一覧表示。
  - `人設 2` → 一覧番号で切り替え。`人設 阿茶` → 名前で切り替え。`人設 預設` → パネルの既定に戻す。
  切り替えはそのユーザーだけに適用され、次の返信から反映されます。管理者が「ユーザー」表のペルソナドロップダウンから変更することもできます。
- **メモリを消去**：「ユーザー」表の「メモリを消去」は、そのユーザーのセッションと専用ワークスペース（中のファイル含む）を削除し、空の状態からやり直します。「セッションを再作成」だけならフォルダは残ります。

## 貼吧（Tieba）学習の自動同期

「刷貼吧」プラグインは 1 日最大 1 回、自分の口調を進化させます（`<DSH_HOME>/tieba-duty/persona.json`）。これは LINE が使う大肥魚ペルソナ（`<DSH_HOME>/storages/dsh-persona-dafeiyu/personas.json`）とは別系統で、もともと連動していません。このプラグインは両者をつなげます。

- パネルの「返信ペルソナ → 貼吧学習の同期」で、オン／オフ、同期先ペルソナ（大肥魚のペルソナ、内蔵も含む）、確認間隔（既定 60 分）、性格値も同期するか、書き込み後に大肥魚プラグインを再読み込みするかを設定できます。内蔵ペルソナは本文を編集できないため `<DSH_HOME>/line-bot/persona-overlays/<id>.md` に書き、毎ターン注入します（再読み込み不要）。カスタムペルソナは本文を直接編集します。
- 確認のたびに貼吧ペルソナのバージョンを比べ、新しい版のときだけ動作します。書き込み時は対象ペルソナ本文の `## 貼吧學來的口氣` セクションだけを置き換え（なければ追記）、他の手書き内容は上書きしません。性格値（温柔／毒舌／抽象／話癆／発図傾向）も同時に更新できます。
- 書き込み前に `<DSH_HOME>/line-bot/persona-backups/personas-<時刻>.json` へバックアップします。
- 書き込み後は Cordis loader 経由で `dsh-persona-dafeiyu` を再起動し、store を読み直させます。再起動に失敗しても警告だけで、本文は既に書き込まれており、次回のプラグイン再読み込みで反映されます。
- 貼吧プラグインが動いていない、または貼吧ペルソナが存在しない場合はスキップします（`pending` に未同期の理由が出ます）。

## ジョーク（言葉のネタ）

**ジョーク**パネルでは、ペルソナが自然に言葉のネタを使えるようになります。3 つのソースを個別に切り替えられます。

- **内蔵シード**：よくあるネットのネタ 10 個（使いどころ付き）。
- **貼吧の名台詞**：貼吧スタイルライブラリの高評価ショートコメントをインポート。
- **wanjiqi ネタ**：6657 配信室の弾幕ネタ（任意；クセが強いので既定はオフ）。

毎ターン数個だけプロンプトに入り、返信では最大 1 個。ネタの説明をしない、無理に使わない、真面目な話や落ち込んでいるときは使わない、というルール付きです。カード下の入力欄から自分で追加でき、保存先は `<DSH_HOME>/line-bot/jokes.json` です。

**「梗類貼吧を追加」**は弱智吧・抽象吧・搞笑吧・梗吧を貼吧プラグインの bars に追加します（設定はバックアップされます）。実際に学習させるには貼吧側で実行開始が必要です。

## 貼吧の活動状況

パネルの「詳細設定 → Agent に貼吧の活動を知らせる」（既定でオン）を有効にすると、返信のたびに「刷貼吧」プラグインの記録から作った短い背景情報を system prompt に注入します：

- 最後に貼吧を見た時刻（例「昨日 22:41、5 時間前」）
- 今日すでに回った枠（昼／夜）
- 今日の貼吧レポートが生成済みか
- 貼吧ペルソナのバージョンと最後の返信時刻

「さっき貼吧見た？」「今日はもう見た？」と聞かれたとき、キャラクターは実際の時刻に基づいて答え、作り話をしません。読むのは `<DSH_HOME>/tieba-duty/` 配下のファイルだけで、貼吧プラグインが起動中である必要はなく、書き込みも行いません。記録がなければ何も注入しません。

## DeepSeek 残高

**DeepSeek 残高**カードは、DSH がログインしている DeepSeek アカウントのウォレット残高を読み取ります（読み取りのみ、チャージはしません）：

- 毎回の返信で現在の残高がペルソナの背景情報に入るので、「あと残りいくら？」と聞けます。
- しきい値（既定 ¥10、パネルで変更可）を下回ると、ペルソナが**自分の言葉で**チャージを促すメッセージを送ります。文言は固定テンプレートではなく、その場で生成されます。
- リマインダーにはクールダウン（既定 12 時間）があり、「主動傳訊」の静音時間帯と対象ユーザー設定を引き継ぎます。
- DSH が DeepSeek アカウントにログインしている必要があります。未ログインの場合はカードに理由が表示され、他の機能はそのまま使えます。
- しきい値は金額であって token 数ではありません。

## 個人メモリ

キャラクターは自分用のメモリを `<DSH_HOME>/line-bot/memories.json` に持ち、ユーザーごとに分けて保存します：

- 好み、近況、約束、重要な出来事など、あとで必要になりそうな情報は `line_memory_add` で自分から記録します。
- 期限のあるもの（試験、旅行、短期の状況）は期限日を付けられ、期限が来ると自動で削除されます。「忘れて」と言えば削除します。
- 毎日（既定は午前 4 時、パネルで変更可）一度見直し、期限切れ・終わった一度きりの出来事・もう成り立たない内容を削除します。
- 毎ターンは直近 N 件（既定 20 件・2000 文字）だけを注入し、残りはファイルに残します。1 人あたりの上限は既定 120 件で、超えると古いものから消えます。
- パスワード、token、身分証番号などの機密情報は記録しません。
- パネルの「個人メモリ」カードで、記録内容の確認、手動削除、期限切れの一括削除、今すぐの見直しができます。
## 表情パック（dsh-meme）

- 送信した画像は `<DSH_HOME>/line-bot/media/` にコピーされ 90 日間保持されます。後からチャットを開いても LINE が取得できます。quick tunnel は再起動で URL が変わるため古い画像は表示できません。固定 URL が必要なら API Token の named tunnel を使ってください。


キャラクターはテキストの返信にスタンプ画像を添えたり、画像だけを返したりできます。画像はインストール済みの dsh-meme プラグインのライブラリ（内蔵「大肥魚」24 枚）から取得します。

- 毎ターン、ライブラリのサンプル（番号＋説明）を context に注入します。画像を添えたいときは返信の最後に `[[meme:#番号]]`（または説明）を付けます。プラグインが LINE の image message に変換します。
- 画像は現在の Cloudflare 公開 URL（`<URL>/media/<token>`）経由で LINE に渡されます。quick tunnel の再起動で URL が変わっても自動で追従します。
- パネルの「表情パック」カードでオンオフ、1 回あたりの上限（1〜3）、ライブラリのサンプル表示ができます。画像の追加や分類の変更は dsh-meme 側の設定で行います。
- LINE スタンプを受信すると、スタンプ画像を取得してモデルに見せます。画像対応モデルはそのまま読み、非対応ならまず modlens、次に別の視覚モデルで説明し、最後に LINE のキーワードを使います。「LINE 認証情報」カードの「スタンプを理解する」でオフにできます。
- 通常の画像も同じです。LINE content API でダウンロードしてモデルに添付し、画像非対応なら同じ modlens／視覚モデルの説明経路を使います。「LINE 認証情報」カードの「画像を理解する」でオフにできます。
- dsh-meme がインストールされていない場合、この機能は無効になりテキストのみ返します。
## 音声返信（CosyVoice3）

- ペルソナは返信の最後に `[[voice]]` を付けると、CosyVoice3-0.5B で音声合成し、LINE の音声メッセージ（m4a）として送信します。
- Apple Silicon の macOS では MLX でローカル合成します。Windows や MLX がない環境では CosyVoice GGUF（CrispASR）を使います。初回はパネルの「環境を一括セットアップ」を押してください（モデルを約 1–2GB ダウンロードします）。
- パネルの「音声返信」でオンオフ、音声使用権の確認、参照音声のアップロード（既定は指定音源の 12–16 秒）、instruct／zero-shot の選択、試聴ができます。
- 合成には約 20–40 秒かかります。reply token の期限が切れた場合は push に切り替わります。音声は `<DSH_HOME>/line-bot/media/` に保存され、tunnel の `/media/<token>` で配信されます。
- `ffmpeg` が必要です。MLX モードは Python 3.10+ が必要です。

- 自然言語の話し方（instruct）は CosyVoice GGUF を使用します。MLX はゼロショット専用で、指示が読み上げられるのを防ぎます。


## 診断
- パネルの「詳細設定 → 診断を実行」でサーバー、Tunnel、公開 URL、webhook、dsh-meme 図庫、画像変換ツール、モデル、最近のエラーを確認できます。「安全な修復」は tunnel 再接続と webhook 再設定だけを行います。
- CLI：`npx dsh-line-bot doctor`、`doctor --fix`、`doctor --json`。
- Agent 向け手順は `AGENTS.md`、症状別は `TROUBLESHOOTING.md`。

## トラブルシューティング

- **パネルに「LINE Bot ランタイムに接続できません」と出る**：webServer がまだ準備できていない可能性があります。再読み込みしてください。それでも失敗する場合は DSH ログの `[line-bot]` を確認します。
- **webhook テストが失敗する**：LINE コンソールで `Use webhook` がオンか、トンネル URL が https か、ローカルの webhook サーバーが動いているか（パネルが緑か）を確認します。
- **`lib/*.mjs` の変更が反映されない**：「詳細設定 → host モジュールを再読み込み（開発用）」を押します。プラグインの再インストールは不要です。
- **貼吧同期が動かない**：パネルの同期状態の `lastError` を確認し、貼吧プラグインのペルソナファイルがあるか、対象ペルソナ id が正しいかを確かめます。「差分をプレビュー」で現在のセクションと書き込まれる内容を比較できます。
- **cloudflared が見つからない**：「cloudflared をダウンロード」を押すと、公式リリースを `<DSH_HOME>/line-bot/bin/` に取得します。自分で置いて `tunnel.binaryPath` に指定することもできます。
- **Agent が 403 を返す（モデルが Codex 専用）**：「詳細設定 → Agent モデル」で provider／model を `deepseek-account` / `deepseek-flash` に変更し（ローカルの既定は既にこの設定）、保存して再テストします。
- **ペルソナが適用されない**：大肥魚を選んだ場合は `session` モードである必要があります。パネルに案内が出るので「大肥魚を session モードに切り替え」を押します（公式にサポートされた設定で、「セッションごとにペルソナを指定できるか」だけに影響します）。プラグインのカスタムペルソナはこの制限を受けません。
- **Cloudflare が 530 / error code 1016 を返す**：名前付きトンネルの DNS CNAME の向き先は `<tunnel-id>.cfargotunnel.com`（`.cfd.tunnel` ではない）である必要があります。また、そのサブドメインが A レコードと重複しているとエッジがそちらのホストを返すので、DNS には CNAME だけを残してください。

## プライバシー

- このプラグインは、あなたが設定した Cloudflare API と LINE API 以外の第三者サーバーには接続しません。テレメトリもアカウントもありません。
- 設定と認証情報はすべてこのマシンの `<DSH_HOME>/line-bot/config.json`（モード 600）にのみ保存され、パネルにはマスクされた値だけが表示されます。
- LINE ユーザーのセッション、ワークスペース、ペルソナ選択はローカルに保存され、アップロードされません。
- リポジトリと npm パッケージには、誰の認証情報・LINE userId・Cloudflare アカウント・ドメインも含まれていません。

## セキュリティ上の注意

- 許可リストは初期状態では空です。知らないユーザーのメッセージは承認待ちに入るだけで、セッションも作られず、ツールも呼ばれません。パネルの「ユーザー」で承認すると返信を始めます。
- これは DSH Agent を公開された LINE アカウントにつなぐのと同じです。bot を知っている人は、あなたのコンピューター上のツールを Agent に使わせられます。「許可リストのユーザー ID」に自分の LINE userId を入れて、自分だけが使えるようにすることをおすすめします。
- 認証情報はすべてローカルの `config.json`（600）に保存され、パネルにはマスクされた値だけが表示されます。API は `127.0.0.1` の DSH webServer にのみ公開されます。
- Cloudflare API トークンは必要最小限の権限にし、使わなくなったら取り消してください。

## 開発

- host ロジック：`lib/*.mjs`（`util`／`config`／`line-api`／`persona`／`agent-runner`／`webhook-server`／`cloudflare`／`tunnel`／`nudge`／`tieba-sync`／`host`）。
- パネル：`client.js`（`window.__ModuleLoader__` で `settings.section` を登録）。
- エントリーポイント：`index.js`（`/api/line-bot` のマウント、dev reload、アンロード時のクリーンアップ）。
