dsh-line-bot 0.1.0 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ - 新增「DeepSeek 餘額」:每輪把錢包餘額放進角色背景資訊;低於門檻時由角色用自己的語氣主動提醒儲值(冷卻、靜音時段、可在面板調整)。
6
+
7
+ - 貼吧動態:每次回覆前把「剛剛有沒有刷貼吧/今天幾場/日報狀態」注入 system prompt,角色可照實回答;面板「進階設定」可關閉。
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  第一個公開版本。
package/README.en.md ADDED
@@ -0,0 +1,172 @@
1
+ # dsh-line-bot
2
+
3
+ <p align="center"><img src="icon.svg" width="96" height="96" alt="dsh-line-bot"></p>
4
+
5
+ **Languages / 語言:** [繁體中文](README.md) · [简体中文](README.zh-CN.md) · [English](README.en.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
6
+
7
+ A plugin that connects a LINE Official Account (Messaging API) to DeepSeek Harness. Replies are produced by the DSH Agent **in the same process** — essentially chatting with your DSH assistant on LINE. Personas can come from the dafeiyu plugin (`dsh-persona-dafeiyu`) when it is installed, or from the plugin's own custom personas (no persona plugin required).
8
+
9
+ Built in:
10
+
11
+ - **Webhook server**: opens a local HTTP server on `127.0.0.1`, handling LINE's `X-Line-Signature` verification, event deduplication, and a separate queue per user.
12
+ - **Cloudflare Tunnel**: one click opens a quick tunnel (`*.trycloudflare.com`, no Cloudflare account needed), or paste a Cloudflare API token to create a named tunnel + DNS for a fixed URL; once the URL is ready it writes the webhook endpoint back to LINE and runs `webhook/test`.
13
+ - **LINE credentials**: fill in Channel ID + Channel Secret and it issues an access token automatically (`/v2/oauth/accessToken`, about 30 days, auto-renewed near expiry); you can also paste an existing Channel Access Token.
14
+ - **Personas**: pick any built-in or custom persona from the dafeiyu plugin in the panel, or use the plugin's own custom personas (stored in `<DSH_HOME>/line-bot/personas.json`, add/edit/import). Persona selection is per-session and does not affect other conversations in the GUI.
15
+ - **Proactive messages**: a scheduler built into the plugin (no launchd), with configurable probability, interval, daily/monthly caps, minimum gap, quiet hours, how long the user must have been idle, target users and prompt. The Agent can reply `SKIP` when it is not a good moment.
16
+ - **Full settings panel**: every setting lives under Settings → LINE Bot and is stored in `<DSH_HOME>/line-bot/config.json` (mode 600).
17
+
18
+ > About "log in with LINE Business ID and have the panel create the bot": since 2024-09 LINE only allows creating a Messaging API channel manually in [LINE Official Account Manager](https://manager.line.biz/), with no public API; LINE Login only authenticates identity and cannot grant management rights over an Official Account. So the panel does not create the bot, but it gives you the correct entry links and automates everything after "you have the Channel ID / Secret" (issuing the token, setting the webhook, testing it).
19
+
20
+ ## Installation
21
+
22
+ Requirements: DeepSeek Harness **≥ 0.2.0-rc.1**, Node.js **≥ 22**. The persona plugin (dafeiyu, `dsh-persona-dafeiyu`) is **optional** — the plugin's built-in custom personas work without it.
23
+
24
+ ### Option 1: Install from the panel (recommended)
25
+
26
+ In DSH: **Settings → Plugins → Install bundle**, enter `dsh-line-bot` and install, then refresh the page. A **LINE Bot** page appears in Settings.
27
+
28
+ ### Option 2: One-line npx install
29
+
30
+ First quit DSH completely (on the desktop app, close the window and make sure no process is left), then run:
31
+
32
+ ```bash
33
+ npx dsh-line-bot install
34
+ ```
35
+
36
+ It detects which profile to install into (defaults to `desktop`; use `--profile <name>` to choose), installs the package with DSH's bundled pnpm, adds the bundle to the profile, and reminds you to restart DSH.
37
+
38
+ ```bash
39
+ npx dsh-line-bot status # which profile it is installed in, and whether it is enabled
40
+ npx dsh-line-bot uninstall # remove it (settings and credentials are kept)
41
+ ```
42
+
43
+ ### Option 3: Manual
44
+
45
+ ```bash
46
+ dsh plugin --profile desktop add dsh-line-bot
47
+ ```
48
+
49
+ Then add `dsh-line-bot` to the `dsh.profile.bundles` array in `~/.dsh/profiles/desktop/package.json` (see what `npx dsh-line-bot install` does), or install from the panel instead.
50
+
51
+ > If it is not on npm yet, you can install directly from GitHub:
52
+ >
53
+ > ```bash
54
+ > npx github:Hanson0901/dsh-line-bot install --spec github:Hanson0901/dsh-line-bot
55
+ > ```
56
+ >
57
+ > Or from source: `git clone https://github.com/Hanson0901/dsh-line-bot.git`, then choose that folder in the DSH panel's "Install bundle", or run `dsh plugin --profile desktop add /path/to/dsh-line-bot`.
58
+
59
+ ## First run (5 steps)
60
+
61
+ 1. **Create / obtain credentials**: go to [LINE Official Account Manager](https://manager.line.biz/) and create an Official Account → [LINE Developers Console](https://developers.line.biz/console/) and create (or pick) a Messaging API channel → open the **Use webhook** toggle on the "Messaging API" tab → copy the **Channel ID** and **Channel secret**.
62
+ 2. **Fill in the panel**: under "LINE Bot → LINE credentials", paste the Channel ID and Channel Secret, click "Save changes" → "Verify and read bot info". On success you will see the bot's name and Basic ID.
63
+ 3. **Start the webhook server**: on "Overview", click "Start all", or "Start" to bring up both the webhook server and the tunnel (auto-start is on by default).
64
+ 4. **Open the tunnel**: for a quick tunnel just click "Start tunnel"; for a fixed URL, paste an API token under "Cloudflare Tunnel" → "Verify API token" → "Create/update tunnel and DNS" (token permissions: Account → Cloudflare Tunnel → Edit, Zone → DNS → Edit, Zone → Zone → Read). A quick tunnel's URL changes on every restart (the plugin writes the new URL back to the LINE webhook automatically); a named tunnel's URL is fixed.
65
+ 5. **Auto-configure the webhook**: once the tunnel is ready the endpoint is PUT to LINE automatically; if that fails, click "Apply tunnel URL to webhook" and then "Test webhook". After that, add the bot as a friend in LINE and send it a message.
66
+
67
+ ## Panel sections
68
+
69
+ At the top of the panel is a **sticky save bar**: "Save changes / Refresh" stays visible wherever you scroll. Below it is a quick navigation menu; clicking an item jumps to that section (the current section is highlighted while scrolling).
70
+
71
+ | Section | Contents |
72
+ | --- | --- |
73
+ | Overview | Green-light status for webhook server / tunnel / LINE / persona / proactive messages, public URL, one-click bring-up and start/stop |
74
+ | LINE credentials | Channel ID, Channel Secret, Access Token, auto-issue, loading animation, bot info, webhook apply/test, allow-list |
75
+ | Cloudflare Tunnel | quick / API token modes, token, hostname, tunnel name, Account/Zone ID, download cloudflared, start/stop, auto-configure webhook, bring your own public URL |
76
+ | Reply persona | Choose a persona (dafeiyu or a plugin custom one), add/edit/delete custom personas, copy the current persona into a custom one, enforce, allow users to switch personas, switch dafeiyu to session mode, test an Agent reply |
77
+ | Proactive messages | Toggle, probability, interval, daily/monthly caps, minimum gap, quiet hours, idle, target users, prompt, send a test now, statistics |
78
+ | Users | The DSH session each LINE user maps to, their own workspace folder, their current persona (editable), message count, last interaction, clear memory / reset session |
79
+ | Advanced | Port, Agent provider/model/effort/cwd/timeout, one workspace per user (and its root), welcome/error/empty replies, logs, reload host modules (dev) |
80
+
81
+ ## Configuration files
82
+
83
+ - `<DSH_HOME>/line-bot/config.json`: all settings, including the LINE secret and Cloudflare token (mode 600; plaintext is never returned to the panel).
84
+ - `<DSH_HOME>/line-bot/state.json`: LINE user ↔ DSH session mapping, message counts, proactive-message counters, webhook state.
85
+ - `<DSH_HOME>/line-bot/logs/YYYY-MM-DD.log`: daily logs (the panel also shows the last 400 lines).
86
+
87
+ `DSH_HOME` defaults to `~/.dsh`.
88
+
89
+ ## How it works
90
+
91
+ 1. LINE POSTs a message to the Cloudflare tunnel → the plugin's webhook server (after signature verification it returns 200 immediately).
92
+ 2. It finds (or creates) the DSH session and workspace folder for that `userId`, then decides the session's persona: for dafeiyu it sets the session persona through dafeiyu's HTTP bridge; for a plugin custom persona it first asks dafeiyu to step aside in that session (`none`), then injects the custom persona into the system prompt.
93
+ 3. It creates/resumes the Agent in the same DSH process with `agents.create` / `agents.resume`, sends one user message with `followup`, and waits for the turn to end, subagents to settle, and the session to flush.
94
+ 4. It takes the last assistant text from the session events and replies with LINE reply; if the reply token has expired it falls back to push.
95
+ 5. The proactive-message scheduler checks once a minute (interval, quiet hours, caps, probability); when conditions are met it asks the Agent to say something on its own and pushes it.
96
+
97
+ ## Persona sources
98
+
99
+ - **dafeiyu (optional)**: when `dsh-persona-dafeiyu` is installed, the panel lists its personas (built-in + your own); LINE selects them per session, without changing other GUI conversations. It must be in `session` mode; the panel tells you and offers a one-click switch.
100
+ - **Plugin custom personas**: no persona plugin required. In "Reply persona → Custom personas" you can add/edit/delete them; data lives in `<DSH_HOME>/line-bot/personas.json` (0600). When a custom persona is selected, the plugin asks dafeiyu to opt out in that session (if it is installed), then injects the custom persona into that agent's system prompt.
101
+ - Both kinds appear in the same dropdown. The same applies when a user switches with a LINE command (`人設`, `人設 2`, `人設 <name>`).
102
+
103
+ ## Per-user memory and personas
104
+
105
+ - **Memory is not shared**: every LINE user gets their own DSH session and their own Agent workspace folder `<DSH_HOME>/line-bot/users/<LINE userId>/`. The files the Agent sees, `AGENTS.md`, and workspace memory are specific to that user; nobody reads anyone else's.
106
+ You can turn this off under "Advanced → One workspace per user" (off means everyone shares `agent.cwd`, i.e. the old behaviour); you can also point `agent.workspaceRoot` at another root.
107
+ - **Users can choose their persona**: when "Reply persona → Allow users to switch personas" is on, LINE users can send:
108
+ - `人設` (or `人格` / `persona`) → lists available personas and the current one.
109
+ - `人設 2` → switch by list index; `人設 阿茶` → switch by name; `人設 預設` → back to the panel default.
110
+ The switch only affects that user and applies from the next reply; an admin can also change it from the persona dropdown in the "Users" table.
111
+ - **Clear memory**: "Clear memory" in the Users table deletes that user's session and their workspace folder (including files), starting from a clean slate; "Reset session" only keeps the folder.
112
+
113
+ ## Tieba learning auto-sync
114
+
115
+ The "dive into Tieba" plugin evolves its own tone at most once a day (stored in `<DSH_HOME>/tieba-duty/persona.json`), and that is a separate system from the dafeiyu persona LINE uses (`<DSH_HOME>/storages/dsh-persona-dafeiyu/personas.json`). This plugin can bridge them:
116
+
117
+ - In the panel, "Reply persona → Tieba learning sync" lets you set the toggle, the target persona (dafeiyu personas only; off by default, pick one first), the check interval (default 60 minutes), whether to sync personality numbers, and whether to reload the dafeiyu plugin after writing. This feature requires the dafeiyu plugin.
118
+ - Each check compares the Tieba persona version; it only acts on a new version. It replaces only the `## 貼吧學來的口氣` section of the target persona text (appending it if missing) and never overwrites other hand-written content; the personality numbers (gentle / sharp / abstract / talkative / image bias) can be updated too.
119
+ - Before writing it backs up to `<DSH_HOME>/line-bot/persona-backups/personas-<time>.json`.
120
+ - After writing it restarts `dsh-persona-dafeiyu` through the Cordis loader so it re-reads the store; a failed restart is only a warning — the text is already written and takes effect on the next plugin reload.
121
+ - If the Tieba plugin is not running or the Tieba persona does not exist, the check is skipped (`pending` shows why it has not synced yet).
122
+
123
+ ## Tieba activity awareness
124
+
125
+ With **Advanced → Let the agent know about Tieba activity** enabled (default), each reply is preceded by a small block of background facts injected into the system prompt, built from the Tieba plugin's records:
126
+
127
+ - when the character last browsed Tieba (e.g. "yesterday 22:41, 5 hours ago")
128
+ - which sessions already ran today (noon / night)
129
+ - whether today's Tieba report exists
130
+ - the Tieba persona version and the last reply time
131
+
132
+ So when someone asks "did you just browse Tieba?" or "have you been on today?", the character answers from the real timestamps instead of making things up. It only reads files under `<DSH_HOME>/tieba-duty/`; the Tieba plugin does not need to be running, and nothing is written. If no records exist, nothing is injected.
133
+
134
+ ## DeepSeek balance
135
+
136
+ The **DeepSeek balance** card reads the wallet balance of the DeepSeek account DSH is signed in with (read-only; it never tops up):
137
+
138
+ - Every reply includes the current balance in the persona's background context, so you can just ask "how much do I have left?".
139
+ - When it drops below the threshold (default ¥10, adjustable in the panel), the persona sends you a message **in its own words** asking you to top up. The wording is generated on the spot, not a fixed template.
140
+ - Reminders have a cooldown (default 12 hours) and reuse the proactive-messaging quiet hours and target-user settings.
141
+ - Requires DSH to be signed in to a DeepSeek account (deepseek-account). If it is not, the card explains why and everything else keeps working.
142
+ - The threshold is money, not tokens: Platform shows a wallet balance, and token conversion varies by model and cache hits.
143
+
144
+ ## Troubleshooting
145
+
146
+ - **The panel says "cannot connect to the LINE Bot runtime"**: webServer may not be ready yet; refresh. If it still fails, look for `[line-bot]` messages in the DSH logs.
147
+ - **Webhook test fails**: make sure `Use webhook` is on in the LINE console, the tunnel URL is https, and the local webhook server is running (green in the panel).
148
+ - **Changes to `lib/*.mjs` do not take effect**: click "Advanced → Reload host modules (dev)"; you do not need to reinstall the plugin.
149
+ - **Tieba sync does nothing**: check `lastError` in the panel's sync status; confirm the Tieba persona file exists and the target persona id is correct. "Preview diff" compares the current section with what is about to be written.
150
+ - **cloudflared not found**: click "Download cloudflared" and the plugin fetches the official release into `<DSH_HOME>/line-bot/bin/`; you can also place your own copy and set `tunnel.binaryPath`.
151
+ - **Agent replies with 403 (model only available to Codex)**: under "Advanced → Agent model", change provider/model to `deepseek-account` / `deepseek-flash` (already the local default), save, and test again.
152
+ - **Persona not applied**: with dafeiyu selected it must be in `session` mode; the panel tells you and offers "Switch dafeiyu to session mode" (an officially supported setting; it only decides whether personas can be picked per session). Plugin custom personas are not affected.
153
+ - **Cloudflare returns 530 / error code 1016**: the DNS CNAME target of a named tunnel must be `<tunnel-id>.cfargotunnel.com` (not `.cfd.tunnel`); also, if the subdomain is simultaneously taken by an A record, the edge answers from that host — make sure DNS has only the CNAME.
154
+
155
+ ## Privacy
156
+
157
+ - The plugin talks to no third-party server other than the Cloudflare API and LINE API you configure. No telemetry, no account.
158
+ - All settings and credentials live only on this machine in `<DSH_HOME>/line-bot/config.json` (mode 600); the panel only shows masked values.
159
+ - LINE users' sessions, workspace folders and persona choices are stored locally and never uploaded.
160
+ - The repository and the npm package contain no credentials, LINE userIds, Cloudflare accounts or domains.
161
+
162
+ ## Security notes
163
+
164
+ - This is equivalent to attaching the DSH Agent to a public LINE account: anyone who has the bot can make the Agent use tools on your computer. It is recommended to fill in your own LINE userId under "Allow-listed user IDs" so only you can use it.
165
+ - All credentials are stored locally in `config.json` (600); the panel only shows masked values; the API only listens on the DSH webServer at `127.0.0.1`.
166
+ - Give the Cloudflare API token only the permissions it needs, and revoke it when you no longer use it.
167
+
168
+ ## Development
169
+
170
+ - Host logic: `lib/*.mjs` (`util` / `config` / `line-api` / `persona` / `agent-runner` / `webhook-server` / `cloudflare` / `tunnel` / `nudge` / `tieba-sync` / `host`).
171
+ - Panel: `client.js` (registers `settings.section` via `window.__ModuleLoader__`).
172
+ - Entry point: `index.js` (mounts `/api/line-bot`, dev reload, cleanup on unload).
package/README.ja.md ADDED
@@ -0,0 +1,172 @@
1
+ # dsh-line-bot
2
+
3
+ <p align="center"><img src="icon.svg" width="96" height="96" alt="dsh-line-bot"></p>
4
+
5
+ **言語 / Languages:** [繁體中文](README.md) · [简体中文](README.zh-CN.md) · [English](README.en.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
6
+
7
+ LINE 公式アカウント(Messaging API)を DeepSeek Harness につなぐプラグインです。返信は DSH の Agent が**同じプロセス内**で生成するため、LINE 上で自分の DSH アシスタントと会話している感覚になります。ペルソナは、大肥魚(`dsh-persona-dafeiyu`)がインストールされていればそのペルソナをそのまま選べますし、どのペルソナプラグインもなしでプラグイン内蔵のカスタムペルソナだけを使うこともできます。
8
+
9
+ 内蔵機能:
10
+
11
+ - **Webhook サーバー**:ローカルの `127.0.0.1` に HTTP サーバーを開き、LINE の `X-Line-Signature` 検証、イベントの重複排除、ユーザーごとのキューを処理します。
12
+ - **Cloudflare Tunnel**:ワンクリックの quick tunnel(`*.trycloudflare.com`、Cloudflare アカウント不要)、または Cloudflare API トークンを貼り付けて名前付きトンネル+DNS を作成し固定 URL を取得します。URL が取得できたら webhook エンドポイントを LINE に書き戻し、`webhook/test` を実行します。
13
+ - **LINE 認証情報**:Channel ID と Channel Secret を入力すれば access token を自動発行(`/v2/oauth/accessToken`、約 30 日、期限が近づくと自動更新)。既存の Channel Access Token を貼り付けることもできます。
14
+ - **ペルソナ**:パネルから大肥魚プラグインの内蔵/カスタムペルソナを選べるほか、プラグイン内蔵のカスタムペルソナ(`<DSH_HOME>/line-bot/personas.json`、追加・編集・インポート可)も使えます。ペルソナはセッション単位で指定され、GUI の他の会話には影響しません。
15
+ - **自発メッセージ**:プラグイン内蔵のスケジューラー(launchd 不要)。確率・間隔・1 日/1 か月の上限・最短間隔・静かな時間帯・相手がどれだけ沈黙していたら話しかけるか・対象ユーザー・プロンプトを設定できます。Agent が「今は違う」と判断したら `SKIP` を返して見送れます。
16
+ - **充実した設定パネル**:設定はすべて「設定 → LINE Bot」にあり、`<DSH_HOME>/line-bot/config.json`(モード 600)に保存されます。
17
+
18
+ > 「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 設定、テスト)を自動化します。
19
+
20
+ ## インストール
21
+
22
+ 要件:DeepSeek Harness **≥ 0.2.0-rc.1**、Node.js **≥ 22**。ペルソナプラグイン(大肥魚 `dsh-persona-dafeiyu`)は**任意**です — インストールしなくてもプラグイン内蔵のカスタムペルソナが使えます。
23
+
24
+ ### 方法 1:パネルからインストール(推奨)
25
+
26
+ DSH → **設定 → プラグイン → bundle をインストール** で `dsh-line-bot` を入力してインストールし、ページを再読み込みします。設定の左側に **LINE Bot** が追加されます。
27
+
28
+ ### 方法 2:npx でワンコマンドインストール
29
+
30
+ まず DSH を完全に終了します(デスクトップ版ならウィンドウを閉じ、メニューバー/プロセスが残っていないことを確認)。その後に実行します。
31
+
32
+ ```bash
33
+ npx dsh-line-bot install
34
+ ```
35
+
36
+ どの profile に入れるかを自動判定し(既定は `desktop`、`--profile <名前>` で指定可)、DSH 内蔵の pnpm でパッケージをインストールし、bundle を profile に追加して、DSH の再起動を促します。
37
+
38
+ ```bash
39
+ npx dsh-line-bot status # どの profile に入っているか、有効かどうか
40
+ npx dsh-line-bot uninstall # 削除(設定と認証情報は残ります)
41
+ ```
42
+
43
+ ### 方法 3:手動
44
+
45
+ ```bash
46
+ dsh plugin --profile desktop add dsh-line-bot
47
+ ```
48
+
49
+ その後 `~/.dsh/profiles/desktop/package.json` の `dsh.profile.bundles` 配列に `dsh-line-bot` を追加します(`npx dsh-line-bot install` の動作を参考にしてください)。パネルからのインストールでも構いません。
50
+
51
+ > まだ npm に公開していない場合は、GitHub から直接インストールできます。
52
+ >
53
+ > ```bash
54
+ > npx github:Hanson0901/dsh-line-bot install --spec github:Hanson0901/dsh-line-bot
55
+ > ```
56
+ >
57
+ > ソースからなら:`git clone https://github.com/Hanson0901/dsh-line-bot.git` して、DSH パネルの「bundle をインストール」でそのフォルダを選ぶか、`dsh plugin --profile desktop add /path/to/dsh-line-bot` を実行します。
58
+
59
+ ## 初回セットアップ(5 ステップ)
60
+
61
+ 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** をコピーします。
62
+ 2. **パネルに入力**:「LINE Bot → LINE 認証情報」に Channel ID と Channel Secret を貼り、「変更を保存」→「検証して bot 情報を取得」を押します。成功すると bot 名と Basic ID が表示されます。
63
+ 3. **webhook サーバーを起動**:「概要」で「すべて起動」を押すか、「起動」を押して webhook サーバーとトンネルを両方立ち上げます(既定で自動起動します)。
64
+ 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 は固定です。
65
+ 5. **webhook を自動設定**:トンネルの準備ができると自動で LINE に PUT します。失敗したら「トンネル URL を webhook に適用」→「webhook をテスト」を押します。あとは LINE で bot を友だち追加してメッセージを送るだけです。
66
+
67
+ ## パネルの各セクション
68
+
69
+ パネル上部には**固定(sticky)保存バー**があり、どこまでスクロールしても「変更を保存/再読み込み」が見えます。その下にはクイックナビがあり、押すと該当セクションへジャンプします(スクロール中は現在のセクションが自動でハイライトされます)。
70
+
71
+ | セクション | 内容 |
72
+ | --- | --- |
73
+ | 概要 | webhook サーバー/トンネル/LINE/ペルソナ/自発メッセージの状態、公開 URL、ワンクリック起動と停止 |
74
+ | LINE 認証情報 | Channel ID、Channel Secret、Access Token、自動発行、ローディング表示、bot 情報、webhook の適用/テスト、許可リスト |
75
+ | Cloudflare Tunnel | quick/API トークンモード、トークン、hostname、トンネル名、Account/Zone ID、cloudflared のダウンロード、起動/停止、webhook 自動設定、独自の公開 URL |
76
+ | 返信ペルソナ | ペルソナ選択(大肥魚またはプラグインのカスタム)、カスタムペルソナの追加・編集・削除、現在のペルソナをカスタムに複製、強制適用、ユーザーによる切り替え許可、大肥魚を session モードに切り替え、Agent 返信のテスト |
77
+ | 自発メッセージ | オン/オフ、確率、間隔、1 日/1 か月の上限、最短間隔、静かな時間帯、idle、対象ユーザー、プロンプト、今すぐ試送、統計 |
78
+ | ユーザー | LINE ユーザーごとに対応する DSH セッション、専用ワークスペース、現在のペルソナ(直接変更可)、メッセージ数、最終やりとり、メモリ消去/セッション再作成 |
79
+ | 詳細設定 | ポート、Agent の provider/model/effort/cwd/タイムアウト、ユーザーごとのワークスペース(ルート含む)、ウェルカム/エラー/空返信、ログ、開発用 host リロード |
80
+
81
+ ## 設定ファイル
82
+
83
+ - `<DSH_HOME>/line-bot/config.json`:すべての設定。LINE secret と Cloudflare トークンを含みます(モード 600、平文はパネルに返しません)。
84
+ - `<DSH_HOME>/line-bot/state.json`:LINE ユーザー ↔ DSH セッションの対応、メッセージ数、自発メッセージのカウント、webhook 状態。
85
+ - `<DSH_HOME>/line-bot/logs/YYYY-MM-DD.log`:日次ログ(パネルにも直近 400 行を表示)。
86
+
87
+ `DSH_HOME` の既定は `~/.dsh` です。
88
+
89
+ ## 動作の仕組み
90
+
91
+ 1. LINE がメッセージを Cloudflare トンネルに POST → プラグインの webhook サーバー(署名検証後すぐに 200 を返す)。
92
+ 2. `userId` から対応する DSH セッションとワークスペースを探し(なければ作成)、そのセッションのペルソナを決めます。大肥魚を選んだ場合は大肥魚の HTTP bridge 経由でセッションペルソナを指定し、プラグインのカスタムペルソナを選んだ場合はまず大肥魚にそのセッションで退いてもらい(`none`)、プラグインがカスタムペルソナを system prompt に注入します。
93
+ 3. `agents.create`/`agents.resume` で同じ DSH プロセス内に Agent を作成/再開し、`followup` でユーザーメッセージを 1 件送り、ターン終了・サブエージェントの収束・セッションの flush を待ちます。
94
+ 4. セッションイベントから最後の assistant テキストを取り出し、LINE の reply で返信します。reply token が切れていたら自動で push に切り替えます。
95
+ 5. 自発メッセージのスケジューラーが 1 分ごとに確認し(間隔、静かな時間帯、上限、確率)、条件を満たせば Agent に一言話してもらって push します。
96
+
97
+ ## ペルソナのソース
98
+
99
+ - **大肥魚(任意)**:`dsh-persona-dafeiyu` がインストールされていると、パネルにそのペルソナ(内蔵+自作)が表示されます。LINE ではセッション単位で指定され、GUI の他の会話には影響しません。`session` モードである必要があり、パネルが案内してワンクリックで切り替えられます。
100
+ - **プラグイン内蔵のカスタムペルソナ**:ペルソナプラグインは不要です。「返信ペルソナ → カスタムペルソナ」で追加・編集・削除でき、データは `<DSH_HOME>/line-bot/personas.json`(0600)に保存されます。カスタムペルソナを選ぶと、プラグインは(インストールされていれば)大肥魚にそのセッションでの停止を依頼し、カスタムペルソナをその agent の system prompt に注入します。
101
+ - どちらも同じドロップダウンから選べます。ユーザーが LINE コマンドで切り替える場合も同じです(`人設`、`人設 2`、`人設 名前`)。
102
+
103
+ ## ユーザーごとのメモリとペルソナ
104
+
105
+ - **メモリは共有されません**:LINE ユーザーごとに専用の DSH セッションと、専用の Agent ワークスペース `<DSH_HOME>/line-bot/users/<LINE userId>/` を持ちます。Agent が見るファイル、`AGENTS.md`、ワークスペースメモリはそのユーザー専用で、他人のものは読みません。
106
+ 「詳細設定 → ユーザーごとのフォルダ」でオフにできます(オフにすると全員が `agent.cwd` を共有し、以前の動作に戻ります)。`agent.workspaceRoot` でルートを指定することもできます。
107
+ - **ペルソナを自分で選べる**:「返信ペルソナ → ユーザーによるペルソナ切り替えを許可」がオンのとき、LINE ユーザーは次を送れます。
108
+ - `人設`(または `人格`/`persona`)→ 利用可能なペルソナと現在のペルソナを一覧表示。
109
+ - `人設 2` → 一覧番号で切り替え。`人設 阿茶` → 名前で切り替え。`人設 預設` → パネルの既定に戻す。
110
+ 切り替えはそのユーザーだけに適用され、次の返信から反映されます。管理者が「ユーザー」表のペルソナドロップダウンから変更することもできます。
111
+ - **メモリを消去**:「ユーザー」表の「メモリを消去」は、そのユーザーのセッションと専用ワークスペース(中のファイル含む)を削除し、空の状態からやり直します。「セッションを再作成」だけならフォルダは残ります。
112
+
113
+ ## 貼吧(Tieba)学習の自動同期
114
+
115
+ 「刷貼吧」プラグインは 1 日最大 1 回、自分の口調を進化させます(`<DSH_HOME>/tieba-duty/persona.json`)。これは LINE が使う大肥魚ペルソナ(`<DSH_HOME>/storages/dsh-persona-dafeiyu/personas.json`)とは別系統で、もともと連動していません。このプラグインは両者をつなげます。
116
+
117
+ - パネルの「返信ペルソナ → 貼吧学習の同期」で、オン/オフ、同期先ペルソナ(大肥魚のペルソナのみ。既定はオフなので先に 1 つ選んでください)、確認間隔(既定 60 分)、性格値も同期するか、書き込み後に大肥魚プラグインを再読み込みするかを設定できます。この機能には大肥魚プラグインが必要です。
118
+ - 確認のたびに貼吧ペルソナのバージョンを比べ、新しい版のときだけ動作します。書き込み時は対象ペルソナ本文の `## 貼吧學來的口氣` セクションだけを置き換え(なければ追記)、他の手書き内容は上書きしません。性格値(温柔/毒舌/抽象/話癆/発図傾向)も同時に更新できます。
119
+ - 書き込み前に `<DSH_HOME>/line-bot/persona-backups/personas-<時刻>.json` へバックアップします。
120
+ - 書き込み後は Cordis loader 経由で `dsh-persona-dafeiyu` を再起動し、store を読み直させます。再起動に失敗しても警告だけで、本文は既に書き込まれており、次回のプラグイン再読み込みで反映されます。
121
+ - 貼吧プラグインが動いていない、または貼吧ペルソナが存在しない場合はスキップします(`pending` に未同期の理由が出ます)。
122
+
123
+ ## 貼吧の活動状況
124
+
125
+ パネルの「詳細設定 → Agent に貼吧の活動を知らせる」(既定でオン)を有効にすると、返信のたびに「刷貼吧」プラグインの記録から作った短い背景情報を system prompt に注入します:
126
+
127
+ - 最後に貼吧を見た時刻(例「昨日 22:41、5 時間前」)
128
+ - 今日すでに回った枠(昼/夜)
129
+ - 今日の貼吧レポートが生成済みか
130
+ - 貼吧ペルソナのバージョンと最後の返信時刻
131
+
132
+ 「さっき貼吧見た?」「今日はもう見た?」と聞かれたとき、キャラクターは実際の時刻に基づいて答え、作り話をしません。読むのは `<DSH_HOME>/tieba-duty/` 配下のファイルだけで、貼吧プラグインが起動中である必要はなく、書き込みも行いません。記録がなければ何も注入しません。
133
+
134
+ ## DeepSeek 残高
135
+
136
+ **DeepSeek 残高**カードは、DSH がログインしている DeepSeek アカウントのウォレット残高を読み取ります(読み取りのみ、チャージはしません):
137
+
138
+ - 毎回の返信で現在の残高がペルソナの背景情報に入るので、「あと残りいくら?」と聞けます。
139
+ - しきい値(既定 ¥10、パネルで変更可)を下回ると、ペルソナが**自分の言葉で**チャージを促すメッセージを送ります。文言は固定テンプレートではなく、その場で生成されます。
140
+ - リマインダーにはクールダウン(既定 12 時間)があり、「主動傳訊」の静音時間帯と対象ユーザー設定を引き継ぎます。
141
+ - DSH が DeepSeek アカウントにログインしている必要があります。未ログインの場合はカードに理由が表示され、他の機能はそのまま使えます。
142
+ - しきい値は金額であって token 数ではありません。
143
+
144
+ ## トラブルシューティング
145
+
146
+ - **パネルに「LINE Bot ランタイムに接続できません」と出る**:webServer がまだ準備できていない可能性があります。再読み込みしてください。それでも失敗する場合は DSH ログの `[line-bot]` を確認します。
147
+ - **webhook テストが失敗する**:LINE コンソールで `Use webhook` がオンか、トンネル URL が https か、ローカルの webhook サーバーが動いているか(パネルが緑か)を確認します。
148
+ - **`lib/*.mjs` の変更が反映されない**:「詳細設定 → host モジュールを再読み込み(開発用)」を押します。プラグインの再インストールは不要です。
149
+ - **貼吧同期が動かない**:パネルの同期状態の `lastError` を確認し、貼吧プラグインのペルソナファイルがあるか、対象ペルソナ id が正しいかを確かめます。「差分をプレビュー」で現在のセクションと書き込まれる内容を比較できます。
150
+ - **cloudflared が見つからない**:「cloudflared をダウンロード」を押すと、公式リリースを `<DSH_HOME>/line-bot/bin/` に取得します。自分で置いて `tunnel.binaryPath` に指定することもできます。
151
+ - **Agent が 403 を返す(モデルが Codex 専用)**:「詳細設定 → Agent モデル」で provider/model を `deepseek-account` / `deepseek-flash` に変更し(ローカルの既定は既にこの設定)、保存して再テストします。
152
+ - **ペルソナが適用されない**:大肥魚を選んだ場合は `session` モードである必要があります。パネルに案内が出るので「大肥魚を session モードに切り替え」を押します(公式にサポートされた設定で、「セッションごとにペルソナを指定できるか」だけに影響します)。プラグインのカスタムペルソナはこの制限を受けません。
153
+ - **Cloudflare が 530 / error code 1016 を返す**:名前付きトンネルの DNS CNAME の向き先は `<tunnel-id>.cfargotunnel.com`(`.cfd.tunnel` ではない)である必要があります。また、そのサブドメインが A レコードと重複しているとエッジがそちらのホストを返すので、DNS には CNAME だけを残してください。
154
+
155
+ ## プライバシー
156
+
157
+ - このプラグインは、あなたが設定した Cloudflare API と LINE API 以外の第三者サーバーには接続しません。テレメトリもアカウントもありません。
158
+ - 設定と認証情報はすべてこのマシンの `<DSH_HOME>/line-bot/config.json`(モード 600)にのみ保存され、パネルにはマスクされた値だけが表示されます。
159
+ - LINE ユーザーのセッション、ワークスペース、ペルソナ選択はローカルに保存され、アップロードされません。
160
+ - リポジトリと npm パッケージには、誰の認証情報・LINE userId・Cloudflare アカウント・ドメインも含まれていません。
161
+
162
+ ## セキュリティ上の注意
163
+
164
+ - これは DSH Agent を公開された LINE アカウントにつなぐのと同じです。bot を知っている人は、あなたのコンピューター上のツールを Agent に使わせられます。「許可リストのユーザー ID」に自分の LINE userId を入れて、自分だけが使えるようにすることをおすすめします。
165
+ - 認証情報はすべてローカルの `config.json`(600)に保存され、パネルにはマスクされた値だけが表示されます。API は `127.0.0.1` の DSH webServer にのみ公開されます。
166
+ - Cloudflare API トークンは必要最小限の権限にし、使わなくなったら取り消してください。
167
+
168
+ ## 開発
169
+
170
+ - host ロジック:`lib/*.mjs`(`util`/`config`/`line-api`/`persona`/`agent-runner`/`webhook-server`/`cloudflare`/`tunnel`/`nudge`/`tieba-sync`/`host`)。
171
+ - パネル:`client.js`(`window.__ModuleLoader__` で `settings.section` を登録)。
172
+ - エントリーポイント:`index.js`(`/api/line-bot` のマウント、dev reload、アンロード時のクリーンアップ)。
package/README.ko.md ADDED
@@ -0,0 +1,172 @@
1
+ # dsh-line-bot
2
+
3
+ <p align="center"><img src="icon.svg" width="96" height="96" alt="dsh-line-bot"></p>
4
+
5
+ **언어 / Languages:** [繁體中文](README.md) · [简体中文](README.zh-CN.md) · [English](README.en.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
6
+
7
+ LINE 공식 계정(Messaging API)을 DeepSeek Harness에 연결하는 플러그인입니다. 답장은 DSH Agent가 **같은 프로세스 안에서** 생성하므로, LINE에서 내 DSH 어시스턴트와 대화하는 것과 같습니다. 페르소나는 大肥魚(`dsh-persona-dafeiyu`)가 설치되어 있으면 그 페르소나를 그대로 고를 수 있고, 페르소나 플러그인 없이 플러그인 내장 커스텀 페르소나만 사용할 수도 있습니다.
8
+
9
+ 내장 기능:
10
+
11
+ - **Webhook 서버**: 로컬 `127.0.0.1`에 HTTP 서버를 열고 LINE의 `X-Line-Signature` 검증, 이벤트 중복 제거, 사용자별 큐를 처리합니다.
12
+ - **Cloudflare Tunnel**: 원클릭 quick tunnel(`*.trycloudflare.com`, Cloudflare 계정 불필요) 또는 Cloudflare API 토큰을 붙여 넣어 이름 있는 터널+DNS를 만들고 고정 URL을 얻습니다. URL이 준비되면 webhook 엔드포인트를 LINE에 다시 쓰고 `webhook/test`를 실행합니다.
13
+ - **LINE 자격 증명**: Channel ID와 Channel Secret을 입력하면 access token을 자동 발급합니다(`/v2/oauth/accessToken`, 약 30일, 만료 전 자동 갱신). 기존 Channel Access Token을 붙여 넣어도 됩니다.
14
+ - **페르소나**: 패널에서 大肥魚 플러그인의 내장/커스텀 페르소나를 고르거나, 플러그인 내장 커스텀 페르소나(`<DSH_HOME>/line-bot/personas.json`, 추가/편집/가져오기)를 쓸 수 있습니다. 페르소나는 세션 단위로 지정되며 GUI의 다른 대화에는 영향을 주지 않습니다.
15
+ - **능동 메시지**: 플러그인 내장 스케줄러(launchd 불필요). 확률, 간격, 일일/월간 상한, 최소 간격, 조용한 시간대, 상대가 얼마나 조용했을 때 말을 걸지, 대상 사용자, 프롬프트를 설정할 수 있습니다. Agent가 지금은 아니라고 판단하면 `SKIP`을 반환해 건너뜁니다.
16
+ - **전체 설정 패널**: 모든 설정이 "설정 → LINE Bot"에 있으며 `<DSH_HOME>/line-bot/config.json`(모드 600)에 저장됩니다.
17
+
18
+ > "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 설정, 테스트)를 자동화합니다.
19
+
20
+ ## 설치
21
+
22
+ 요구 사항: DeepSeek Harness **≥ 0.2.0-rc.1**, Node.js **≥ 22**. 페르소나 플러그인(大肥魚 `dsh-persona-dafeiyu`)은 **선택**입니다 — 설치하지 않아도 플러그인 내장 커스텀 페르소나를 쓸 수 있습니다.
23
+
24
+ ### 방법 1: 패널에서 설치(권장)
25
+
26
+ DSH → **설정 → 플러그인 → bundle 설치**에서 `dsh-line-bot`을 입력해 설치하고 페이지를 새로 고칩니다. 설정 왼쪽에 **LINE Bot**이 생깁니다.
27
+
28
+ ### 방법 2: npx 원라인 설치
29
+
30
+ 먼저 DSH를 완전히 종료합니다(데스크톱 앱은 창을 닫고 메뉴 막대/프로세스가 남아 있지 않은지 확인). 그다음 실행합니다.
31
+
32
+ ```bash
33
+ npx dsh-line-bot install
34
+ ```
35
+
36
+ 어느 profile에 설치할지 자동으로 판단하고(기본 `desktop`, `--profile <이름>`으로 지정 가능), DSH 내장 pnpm으로 패키지를 설치한 뒤 bundle을 profile에 추가하고 DSH 재시작을 안내합니다.
37
+
38
+ ```bash
39
+ npx dsh-line-bot status # 어느 profile에 설치되어 있고 활성화되어 있는지
40
+ npx dsh-line-bot uninstall # 제거(설정과 자격 증명은 유지)
41
+ ```
42
+
43
+ ### 방법 3: 수동
44
+
45
+ ```bash
46
+ dsh plugin --profile desktop add dsh-line-bot
47
+ ```
48
+
49
+ 그다음 `~/.dsh/profiles/desktop/package.json`의 `dsh.profile.bundles` 배열에 `dsh-line-bot`을 추가합니다(`npx dsh-line-bot install`이 하는 일 참고). 패널 설치를 써도 됩니다.
50
+
51
+ > 아직 npm에 배포하지 않았다면 GitHub에서 바로 설치할 수 있습니다.
52
+ >
53
+ > ```bash
54
+ > npx github:Hanson0901/dsh-line-bot install --spec github:Hanson0901/dsh-line-bot
55
+ > ```
56
+ >
57
+ > 소스에서 설치하려면 `git clone https://github.com/Hanson0901/dsh-line-bot.git` 후 DSH 패널의 "bundle 설치"에서 그 폴더를 선택하거나 `dsh plugin --profile desktop add /path/to/dsh-line-bot`을 실행합니다.
58
+
59
+ ## 첫 구동(5단계)
60
+
61
+ 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** 복사.
62
+ 2. **패널에 입력**: "LINE Bot → LINE 자격 증명"에 Channel ID와 Channel Secret을 붙여 넣고 "변경 저장" → "검증하고 bot 정보 읽기"를 누릅니다. 성공하면 bot 이름과 Basic ID가 표시됩니다.
63
+ 3. **webhook 서버 시작**: "개요"에서 "모두 시작"을 누르거나 "시작"을 눌러 webhook 서버와 터널을 함께 올립니다(기본값은 자동 시작).
64
+ 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은 고정입니다.
65
+ 5. **webhook 자동 설정**: 터널이 준비되면 자동으로 LINE에 PUT합니다. 실패하면 "터널 URL을 webhook에 적용" → "webhook 테스트"를 누릅니다. 그다음 LINE에서 bot을 친구 추가하고 메시지를 보내면 됩니다.
66
+
67
+ ## 패널 구성
68
+
69
+ 패널 맨 위에는 **고정(sticky) 저장 바**가 있어 어디까지 스크롤해도 "변경 저장/새로 고침"이 보입니다. 그 아래에는 빠른 이동 메뉴가 있으며 누르면 해당 섹션으로 이동합니다(스크롤 중에는 현재 섹션이 자동으로 강조됩니다).
70
+
71
+ | 섹션 | 내용 |
72
+ | --- | --- |
73
+ | 개요 | webhook 서버/터널/LINE/페르소나/능동 메시지 상태, 공개 URL, 원클릭 기동과 시작/중지 |
74
+ | LINE 자격 증명 | Channel ID, Channel Secret, Access Token, 자동 발급, 로딩 표시, bot 정보, webhook 적용/테스트, 허용 목록 |
75
+ | Cloudflare Tunnel | quick/API 토큰 모드, 토큰, hostname, 터널 이름, Account/Zone ID, cloudflared 다운로드, 시작/중지, webhook 자동 설정, 직접 제공하는 공개 URL |
76
+ | 답장 페르소나 | 페르소나 선택(大肥魚 또는 플러그인 커스텀), 커스텀 페르소나 추가/편집/삭제, 현재 페르소나를 커스텀으로 복사, 강제 적용, 사용자 직접 전환 허용, 大肥魚를 session 모드로 전환, Agent 답장 테스트 |
77
+ | 능동 메시지 | 켜기/끄기, 확률, 간격, 일일/월간 상한, 최소 간격, 조용한 시간대, idle, 대상 사용자, 프롬프트, 지금 시험 발송, 통계 |
78
+ | 사용자 | LINE 사용자별 DSH 세션, 전용 작업 폴더, 현재 페르소나(직접 변경 가능), 메시지 수, 마지막 상호작용, 기억 지우기/세션 재설정 |
79
+ | 고급 설정 | 포트, Agent provider/model/effort/cwd/타임아웃, 사용자별 작업 폴더(루트 포함), 환영/오류/빈 답장, 로그, 개발용 host 리로드 |
80
+
81
+ ## 설정 파일
82
+
83
+ - `<DSH_HOME>/line-bot/config.json`: 모든 설정. LINE secret과 Cloudflare 토큰 포함(모드 600, 평문은 패널에 반환하지 않음).
84
+ - `<DSH_HOME>/line-bot/state.json`: LINE 사용자 ↔ DSH 세션 매핑, 메시지 수, 능동 메시지 카운터, webhook 상태.
85
+ - `<DSH_HOME>/line-bot/logs/YYYY-MM-DD.log`: 일별 로그(패널에도 최근 400줄 표시).
86
+
87
+ `DSH_HOME`의 기본값은 `~/.dsh`입니다.
88
+
89
+ ## 동작 방식
90
+
91
+ 1. LINE이 메시지를 Cloudflare 터널로 POST → 플러그인 webhook 서버(서명 검증 후 즉시 200 반환).
92
+ 2. `userId`로 해당 DSH 세션과 작업 폴더를 찾거나 만들고, 그 세션의 페르소나를 정합니다. 大肥魚를 고르면 大肥魚의 HTTP bridge로 세션 페르소나를 지정하고, 플러그인 커스텀 페르소나를 고르면 먼저 大肥魚에게 그 세션에서 물러나 달라고 한 뒤(`none`) 플러그인이 커스텀 페르소나를 system prompt에 주입합니다.
93
+ 3. `agents.create`/`agents.resume`로 같은 DSH 프로세스 안에서 Agent를 만들거나 이어 받고, `followup`으로 사용자 메시지 하나를 보낸 뒤 turn 종료, 하위 에이전트 수렴, 세션 flush를 기다립니다.
94
+ 4. 세션 이벤트에서 마지막 assistant 텍스트를 꺼내 LINE reply로 답장합니다. reply token이 만료되었으면 자동으로 push로 전환합니다.
95
+ 5. 능동 메시지 스케줄러가 1분마다 확인하고(간격, 조용한 시간대, 상한, 확률) 조건을 만족하면 Agent에게 한마디 하게 한 뒤 push합니다.
96
+
97
+ ## 페르소나 출처
98
+
99
+ - **大肥魚(선택)**: `dsh-persona-dafeiyu`가 설치되어 있으면 패널에 그 페르소나(내장+직접 만든 것)가 나옵니다. LINE에서는 세션 단위로 지정되며 GUI의 다른 대화는 바뀌지 않습니다. `session` 모드여야 하며, 패널이 안내하고 원클릭으로 전환할 수 있습니다.
100
+ - **플러그인 내장 커스텀 페르소나**: 페르소나 플러그인이 필요 없습니다. "답장 페르소나 → 커스텀 페르소나"에서 추가/편집/삭제할 수 있고 데이터는 `<DSH_HOME>/line-bot/personas.json`(0600)에 저장됩니다. 커스텀 페르소나를 고르면 플러그인은 (설치되어 있다면) 大肥魚에게 그 세션에서 중지해 달라고 한 뒤 커스텀 페르소나를 해당 agent의 system prompt에 주입합니다.
101
+ - 두 종류 모두 같은 드롭다운에서 선택할 수 있습니다. 사용자가 LINE 명령으로 바꾸는 경우도 같습니다(`人設`, `人設 2`, `人設 이름`).
102
+
103
+ ## 사용자별 기억과 페르소나
104
+
105
+ - **기억은 공유되지 않습니다**: LINE 사용자마다 자신의 DSH 세션과 전용 Agent 작업 폴더 `<DSH_HOME>/line-bot/users/<LINE userId>/`가 있습니다. Agent가 보는 파일, `AGENTS.md`, 작업 공간 기억은 그 사용자 전용이며 다른 사람의 것은 읽지 않습니다.
106
+ "고급 설정 → 사용자별 폴더"에서 끌 수 있습니다(끄면 모두 `agent.cwd`를 공유해 예전 동작으로 돌아갑니다). `agent.workspaceRoot`로 루트를 지정할 수도 있습니다.
107
+ - **사용자가 페르소나를 직접 선택 가능**: "답장 페르소나 → 사용자 직접 전환 허용"이 켜져 있으면 LINE 사용자는 다음을 보낼 수 있습니다.
108
+ - `人設`(또는 `人格`/`persona`) → 사용 가능한 페르소나와 현재 페르소나 목록.
109
+ - `人設 2` → 목록 번호로 전환. `人設 阿茶` → 이름으로 전환. `人設 預設` → 패널 기본값으로 복귀.
110
+ 전환은 그 사용자에게만 적용되며 다음 답장부터 반영됩니다. 관리자가 "사용자" 표의 페르소나 드롭다운에서 바꿀 수도 있습니다.
111
+ - **기억 지우기**: "사용자" 표에서 "기억 지우기"를 누르면 그 사용자의 세션과 전용 작업 폴더(안의 파일 포함)가 삭제되어 빈 상태에서 다시 시작합니다. "세션 재설정"만 누르면 폴더는 유지됩니다.
112
+
113
+ ## 貼吧(Tieba) 학습 자동 동기화
114
+
115
+ "刷貼吧" 플러그인은 하루에 최대 한 번 자신의 말투를 진화시킵니다(`<DSH_HOME>/tieba-duty/persona.json`). 이것은 LINE이 쓰는 大肥魚 페르소나(`<DSH_HOME>/storages/dsh-persona-dafeiyu/personas.json`)와 별개 계통이라 원래 서로 연결되지 않습니다. 이 플러그인이 둘을 이어 줍니다.
116
+
117
+ - 패널의 "답장 페르소나 → 貼吧 학습 동기화"에서 켜기/끄기, 동기화 대상 페르소나(大肥魚 페르소나만; 기본은 꺼져 있으니 먼저 하나 고르세요), 확인 간격(기본 60분), 성격 수치 동기화 여부, 기록 후 大肥魚 플러그인 리로드 여부를 설정할 수 있습니다. 이 기능에는 大肥魚 플러그인이 필요합니다.
118
+ - 확인할 때마다 貼吧 페르소나 버전을 비교해 새 버전일 때만 동작합니다. 기록할 때는 대상 페르소나 본문의 `## 貼吧學來的口氣` 섹션만 바꾸고(없으면 덧붙임) 다른 직접 쓴 내용은 덮어쓰지 않습니다. 성격 수치(温柔/毒舌/抽象/話癆/發図傾向)도 함께 갱신할 수 있습니다.
119
+ - 기록 전 `<DSH_HOME>/line-bot/persona-backups/personas-<시간>.json`으로 백업합니다.
120
+ - 기록 후 기본적으로 Cordis loader를 통해 `dsh-persona-dafeiyu`를 재시작해 store를 다시 읽게 합니다. 재시작 실패는 경고만 남기고, 본문은 이미 기록되어 다음 플러그인 리로드 때 반영됩니다.
121
+ - 貼吧 플러그인이 실행 중이 아니거나 貼吧 페르소나가 없으면 확인을 건너뜁니다(`pending`에 미동기화 이유 표시).
122
+
123
+ ## 貼吧 활동 인지
124
+
125
+ 패널의 "고급 설정 → Agent가 貼吧 활동을 알도록 함"(기본 켜짐)을 켜면, 답장 전마다 "刷貼吧" 플러그인의 기록에서 만든 짧은 배경 정보를 system prompt에 주입합니다:
126
+
127
+ - 마지막으로 貼吧를 본 시각(예: "어제 22:41, 5시간 전")
128
+ - 오늘 이미 돈 회차(점심/저녁)
129
+ - 오늘 貼吧 리포트 생성 여부
130
+ - 貼吧 페르소나 버전과 마지막 답글 시각
131
+
132
+ "방금 貼吧 봤어?" "오늘 봤어?"라고 물으면 캐릭터는 실제 시각대로 답하고 지어내지 않습니다. 이 기능은 `<DSH_HOME>/tieba-duty/` 아래 파일만 읽으며, 貼吧 플러그인이 실행 중일 필요도 없고 아무것도 쓰지 않습니다. 기록이 없으면 주입하지 않습니다.
133
+
134
+ ## DeepSeek 잔액
135
+
136
+ **DeepSeek 잔액** 카드는 DSH에 로그인된 DeepSeek 계정의 지갑 잔액을 읽습니다(읽기 전용, 충전하지 않음):
137
+
138
+ - 매 답변마다 현재 잔액이 페르소나의 배경 정보에 포함되어 "얼마 남았어?"라고 바로 물을 수 있습니다.
139
+ - 기준값(기본 ¥10, 패널에서 조정 가능)보다 낮아지면 페르소나가 **자기 말투로** 충전을 권하는 메시지를 보냅니다. 문구는 고정 템플릿이 아니라 그때 만듭니다.
140
+ - 알림에는 쿨다운(기본 12시간)이 있고, "主動傳訊"의 조용한 시간대와 대상 사용자 설정을 따릅니다.
141
+ - DSH가 DeepSeek 계정(deepseek-account)에 로그인되어 있어야 합니다. 아니면 카드에 이유가 표시되며 다른 기능은 그대로 동작합니다.
142
+ - 기준값은 금액이며 token 수가 아닙니다.
143
+
144
+ ## 문제 해결
145
+
146
+ - **패널에 "LINE Bot 런타임에 연결할 수 없습니다"**: webServer가 아직 준비되지 않았을 수 있습니다. 새로 고침하세요. 그래도 실패하면 DSH 로그의 `[line-bot]` 메시지를 확인합니다.
147
+ - **webhook 테스트 실패**: LINE 콘솔에서 `Use webhook`이 켜져 있는지, 터널 URL이 https인지, 로컬 webhook 서버가 실행 중인지(패널이 초록인지) 확인합니다.
148
+ - **`lib/*.mjs` 수정이 반영되지 않음**: "고급 설정 → host 모듈 리로드(개발용)"를 누르세요. 플러그인을 다시 설치할 필요는 없습니다.
149
+ - **貼吧 동기화가 동작하지 않음**: 패널 동기화 상태의 `lastError`를 보고, 貼吧 플러그인의 페르소나 파일이 있는지, 대상 페르소나 id가 맞는지 확인합니다. "차이 미리 보기"로 현재 섹션과 기록될 내용을 비교할 수 있습니다.
150
+ - **cloudflared를 찾을 수 없음**: "cloudflared 다운로드"를 누르면 공식 릴리스를 `<DSH_HOME>/line-bot/bin/`에 받습니다. 직접 넣고 `tunnel.binaryPath`로 지정해도 됩니다.
151
+ - **Agent가 403 반환(모델이 Codex 전용)**: "고급 설정 → Agent 모델"에서 provider/model을 `deepseek-account` / `deepseek-flash`로 바꾸고(로컬 기본값은 이미 이렇게 설정됨) 저장한 뒤 다시 테스트합니다.
152
+ - **페르소나가 적용되지 않음**: 大肥魚를 고른 경우 `session` 모드여야 합니다. 패널이 안내하며 "大肥魚를 session 모드로 전환"을 누르면 됩니다(공식 지원 설정이며 "세션별 페르소나 지정 가능 여부"에만 영향을 줍니다). 플러그인 커스텀 페르소나는 이 제한을 받지 않습니다.
153
+ - **Cloudflare가 530 / error code 1016 반환**: 이름 있는 터널의 DNS CNAME 대상은 `<tunnel-id>.cfargotunnel.com`이어야 합니다(`.cfd.tunnel` 아님). 또한 그 하위 도메인이 A 레코드와 겹치면 엣지가 그 호스트로 먼저 응답하므로 DNS에 CNAME 하나만 남기세요.
154
+
155
+ ## 개인정보
156
+
157
+ - 이 플러그인은 사용자가 설정한 Cloudflare API와 LINE API 외에는 어떤 제3자 서버에도 연결하지 않습니다. 텔레메트리도 계정도 없습니다.
158
+ - 모든 설정과 자격 증명은 이 컴퓨터의 `<DSH_HOME>/line-bot/config.json`(모드 600)에만 저장되며, 패널에는 마스킹된 값만 표시됩니다.
159
+ - LINE 사용자의 세션, 작업 폴더, 페르소나 선택은 로컬에 저장되며 업로드되지 않습니다.
160
+ - 저장소와 npm 패키지에는 누구의 자격 증명, LINE userId, Cloudflare 계정, 도메인도 포함되어 있지 않습니다.
161
+
162
+ ## 보안 안내
163
+
164
+ - 이는 DSH Agent를 공개된 LINE 계정에 연결하는 것과 같습니다. bot을 아는 사람은 당신의 컴퓨터에 있는 도구를 Agent가 사용하게 할 수 있습니다. "허용 목록 사용자 ID"에 자신의 LINE userId를 넣어 자신만 사용하도록 하는 것을 권장합니다.
165
+ - 모든 자격 증명은 로컬 `config.json`(600)에 저장되고 패널에는 마스킹된 값만 보입니다. API는 `127.0.0.1`의 DSH webServer에만 열립니다.
166
+ - Cloudflare API 토큰은 필요한 권한만 주고, 사용하지 않을 때는 폐기하세요.
167
+
168
+ ## 개발
169
+
170
+ - host 로직: `lib/*.mjs`(`util`/`config`/`line-api`/`persona`/`agent-runner`/`webhook-server`/`cloudflare`/`tunnel`/`nudge`/`tieba-sync`/`host`).
171
+ - 패널: `client.js`(`window.__ModuleLoader__`로 `settings.section` 등록).
172
+ - 진입점: `index.js`(`/api/line-bot` 마운트, dev reload, 언로드 정리).
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # dsh-line-bot
2
2
 
3
+ <p align="center"><img src="icon.svg" width="96" height="96" alt="dsh-line-bot"></p>
4
+
5
+ **語言 / Languages:** **繁體中文** · [简体中文](README.zh-CN.md) · [English](README.en.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
6
+
3
7
  把 LINE 官方帳號(Messaging API)接進 DeepSeek Harness 的插件。回覆由 DSH 的 Agent 在**同一個行程內**產生,等於在 LINE 上跟你的 DSH 助理聊天;人設有兩種來源:有安裝大肥魚(`dsh-persona-dafeiyu`)時可以直接選它的人設;也可以只用插件內建的自訂人設(不需要任何個性外掛)。
4
8
 
5
9
  內建:
@@ -116,6 +120,27 @@ dsh plugin --profile desktop add dsh-line-bot
116
120
  - 寫入後預設會透過 Cordis loader 重啟 `dsh-persona-dafeiyu`,讓它重新讀取 store;重啟失敗只會記警告,人設文字仍已寫入,下次外掛重載時生效。
117
121
  - 貼吧外掛若沒在跑、或貼吧人設不存在,檢查會跳過(`pending` 顯示尚未同步的原因)。
118
122
 
123
+ ## 貼吧動態(讓角色知道自己剛刷過)
124
+
125
+ 面板「進階設定 → 讓 Agent 知道貼吧動態」(預設開)會在每次回覆前,把「刷貼吧」外掛留下的紀錄整理成一小段背景事實注入 system prompt:
126
+
127
+ - 最近一次刷貼吧的時間(例如「昨天 22:41,5 小時前」)
128
+ - 今天已刷的場次(中午/晚上)
129
+ - 今天的貼吧日報有沒有產生
130
+ - 貼吧人設版本與最後一次回覆時間
131
+
132
+ 使用者問「你剛剛有刷貼吧嗎?」「今天刷過了嗎?」時,角色會照實際時間回答,不會編造。這個功能只讀 `<DSH_HOME>/tieba-duty/` 的檔案,不需要貼吧外掛正在跑,也不會寫入任何東西;讀不到紀錄時就不注入。
133
+
134
+ ## DeepSeek 餘額
135
+
136
+ 面板的「DeepSeek 餘額」卡會讀取 DSH 目前登入的 DeepSeek 帳號錢包餘額(只讀,不會儲值):
137
+
138
+ - 每輪回覆都會把目前餘額放進角色的背景資訊,所以可以直接問它「我還剩多少」。
139
+ - 低於門檻(預設 ¥10,可在面板調整)時,它會用**自己的語氣**傳一則訊息提醒你儲值;內文不是固定模板,是角色當場想的。
140
+ - 提醒有冷卻時間(預設 12 小時),並沿用「主動傳訊」的靜音時段與目標使用者設定。
141
+ - 需要 DSH 已登入 DeepSeek 帳號(deepseek-account)。沒登入或該 profile 沒掛這個服務時,卡片會顯示原因,其餘功能不受影響。
142
+ - 門檻用的是錢包金額,不是 token 數:DeepSeek 平台顯示的是金額,token 換算會隨模型與快取變動。
143
+
119
144
  ## 疑難排解
120
145
 
121
146
  - **面板顯示「無法連線到 LINE Bot 執行期」**:webServer 可能還沒就緒,重新整理即可;仍失敗就看 DSH 日誌裡 `[line-bot]` 的訊息。