opencode-tbot 0.1.33 → 0.1.34

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/README.ja.md CHANGED
@@ -1,29 +1,31 @@
1
1
  # opencode-tbot
2
2
 
3
- チャットから [OpenCode](https://opencode.ai) を操作するための Telegram プラグインです。
3
+ Telegram から [OpenCode](https://opencode.ai) を操作するためのプラグインです。
4
4
 
5
5
  [English](./README.md) | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md)
6
6
 
7
- > このプロジェクトは OpenCode チームによって開発されたものではなく、公式な関連もありません。
7
+ > このプロジェクトは OpenCode チームによって開発されたものではなく、公式プロジェクトでもありません。
8
8
 
9
9
  ## 概要
10
10
 
11
- `opencode-tbot` を使うと、Telegram から OpenCode を操作できます。
11
+ `opencode-tbot` を使うと、Telegram から OpenCode を操作でき、チャットごとに 1 つのバインド状態を維持できます。
12
12
 
13
- - テキストメッセージは現在アクティブな OpenCode セッションに転送されます。
13
+ - プレーンテキストメッセージは現在の OpenCode セッションに転送されます。
14
14
  - Telegram の写真と画像ドキュメントは OpenCode のファイルパートとしてアップロードされます。
15
- - Telegram の音声メッセージは明示的に拒否され、ローカライズされた返信を返します。
15
+ - 画像を含むターンは一時的に fork したセッションで実行されるため、後続のテキスト専用プロンプトに画像コンテキストが残りません。
16
16
  - OpenCode が発行した権限リクエストは、Telegram のインラインボタンから承認または拒否できます。
17
17
  - セッションエラーイベントは、紐付けられた Telegram チャットへ通知できます。
18
- - チャットの紐付け状態は JSON の state ファイルに保存されます。
18
+ - 音声メッセージは明示的に拒否され、ローカライズされた案内を返します。
19
+ - チャットのバインドとセッション選択状態は JSON の state ファイルに保存されます。
19
20
 
20
21
  ## 前提条件
21
22
 
22
- - このプラグインを読み込む OpenCode ホストプロセスが動作していること。
23
+ - このプラグインを読み込む OpenCode Host プロセスが動作していること。
23
24
  - Telegram bot token を用意していること。
24
- - CLI とローカル開発には Node.js `>=22.12.0` が必要です。
25
+ - CLI とローカル開発のために Node.js `>=22.12.0` が必要です。
26
+ - リポジトリ開発には `pnpm` が必要です。
25
27
 
26
- ## インストール
28
+ ## インストールと更新
27
29
 
28
30
  推奨インストール方法:
29
31
 
@@ -31,9 +33,14 @@
31
33
  npm exec --package opencode-tbot@latest opencode-tbot -- install
32
34
  ```
33
35
 
34
- インストーラーはプラグインをグローバルに登録し、実際に使われる OpenCode のグローバル設定ファイルを更新し、デフォルトのランタイム設定を書き込みます。あわせて OpenCode 設定パス、プラグイン設定パス、既定のログディレクトリを表示します。
36
+ インストーラーは次を行います。
35
37
 
36
- `~/.config/opencode/opencode.jsonc` が既に存在する場合はそのファイルを優先して更新し、存在しない場合は `~/.config/opencode/opencode.json` を使います。
38
+ - グローバル OpenCode プラグイン一覧に `opencode-tbot@latest` を登録
39
+ - 実際に使われる OpenCode グローバル設定ファイルを更新
40
+ - グローバルのプラグイン実行設定を作成またはマージ
41
+ - OpenCode 設定パス、プラグイン設定パス、既定のプラグインログディレクトリを表示
42
+
43
+ `~/.config/opencode/opencode.jsonc` がすでに存在する場合はそのファイルを優先して更新し、存在しない場合は `~/.config/opencode/opencode.json` を使います。
37
44
 
38
45
  インストール済み CLI のバージョン確認:
39
46
 
@@ -41,12 +48,18 @@ npm exec --package opencode-tbot@latest opencode-tbot -- install
41
48
  npm exec --package opencode-tbot@latest opencode-tbot -- --version
42
49
  ```
43
50
 
44
- OpenCode に登録済みの npm プラグイン spec を更新:
51
+ bot token を変更せず、OpenCode に登録された npm プラグイン spec だけを更新:
45
52
 
46
53
  ```bash
47
54
  npm exec --package opencode-tbot@latest opencode-tbot -- update
48
55
  ```
49
56
 
57
+ `install` は既定コマンドです。たとえば、非対話インストールでは次の形でも実行できます。
58
+
59
+ ```bash
60
+ npm exec --package opencode-tbot@latest opencode-tbot -- --bot-token <token>
61
+ ```
62
+
50
63
  ### CLI オプション
51
64
 
52
65
  `install` で利用可能:
@@ -64,15 +77,23 @@ npm exec --package opencode-tbot@latest opencode-tbot -- update
64
77
 
65
78
  ## 設定
66
79
 
67
- ランタイム設定は `~/.config/opencode/opencode-tbot/config.json` からのみ読み込まれます。
80
+ ランタイム設定は次のパスからのみ読み込まれます。
81
+
82
+ - `~/.config/opencode/opencode-tbot/config.json`
68
83
 
69
- OpenCode のプラグイン登録はグローバル OpenCode 設定に保存されます。`~/.config/opencode/opencode.jsonc` がある場合はそれを使い、なければ `~/.config/opencode/opencode.json` を使います。
84
+ OpenCode のプラグイン登録情報はグローバル OpenCode 設定に保存されます。
70
85
 
71
- 古い `<worktree>/tbot.config.json` はランタイムでは無視されます。検出された場合は、値をグローバル設定へ移行できるように警告ログを出します。
86
+ - 存在する場合は `~/.config/opencode/opencode.jsonc`
87
+ - なければ `~/.config/opencode/opencode.json`
72
88
 
73
- 古い `openrouter` 音声転写設定はランタイムでは無視され、インストーラーが設定を書き直す際にも削除されます。
89
+ このプラグインは `.env` からランタイム設定を読み込みません。グローバル JSON 設定を使ってください。
74
90
 
75
- ### グローバル `config.json` の例
91
+ レガシー挙動:
92
+
93
+ - `<worktree>/tbot.config.json` はランタイムで無視されます。見つかった場合は移行用の警告ログが出ます
94
+ - 古い `openrouter` 音声文字起こし設定はランタイムで無視され、インストーラーが設定を書き直す際にも削除されます
95
+
96
+ ### `config.json` の例
76
97
 
77
98
  ```json
78
99
  {
@@ -89,55 +110,100 @@ OpenCode のプラグイン登録はグローバル OpenCode 設定に保存さ
89
110
  "pollRequestTimeoutMs": 15000,
90
111
  "recoveryInactivityTimeoutMs": 120000
91
112
  },
113
+ "logging": {
114
+ "level": "info",
115
+ "sinks": {
116
+ "host": true,
117
+ "file": true
118
+ },
119
+ "file": {
120
+ "dir": "C:/Users/your-user/.local/share/opencode/log/plugins/opencode-tbot",
121
+ "retention": {
122
+ "maxFiles": 30,
123
+ "maxTotalBytes": 314572800
124
+ }
125
+ }
126
+ },
92
127
  "logLevel": "info"
93
128
  }
94
129
  ```
95
130
 
96
- ### フィールド
131
+ ### 設定項目
97
132
 
98
- | フィールド | 必須 | デフォルト | 説明 |
133
+ | 項目 | 必須 | 既定値 | 説明 |
99
134
  | --- | --- | --- | --- |
100
- | `telegram.botToken` | はい | - | Telegram bot token。通常はインストーラーがグローバルプラグイン設定へ書き込みます。 |
101
- | `telegram.allowedChatIds` | いいえ | `[]` | 許可する Telegram chat ID の配列。空の場合はすべての chat を受け付けます。 |
102
- | `telegram.apiRoot` | いいえ | `https://api.telegram.org` | Telegram Bot API のベース URL。テストやセルフホストのゲートウェイ向けです。 |
135
+ | `telegram.botToken` | はい | - | Telegram bot token。通常はインストーラーがグローバル設定に書き込みます。 |
136
+ | `telegram.allowedChatIds` | いいえ | `[]` | 許可する Telegram chat ID。一覧が空なら任意の chat を受け付けます。 |
137
+ | `telegram.apiRoot` | いいえ | `https://api.telegram.org` | Telegram Bot API のベース URL。テストやセルフホスト環境向けです。 |
103
138
  | `state.path` | いいえ | `./data/opencode-tbot.state.json` | JSON state ファイルのパス。現在の OpenCode worktree からの相対パスとして解決されます。 |
104
- | `logLevel` | いいえ | `info` | プラグインのログレベル。ログは `client.app.log()` 経由で出力されます。 |
139
+ | `prompt.waitTimeoutMs` | いいえ | `1800000` | 1 回の非同期 prompt ライフサイクル全体に対する待機上限。 |
140
+ | `prompt.pollRequestTimeoutMs` | いいえ | `15000` | OpenCode への各 recovery poll リクエストのタイムアウト。 |
141
+ | `prompt.recoveryInactivityTimeoutMs` | いいえ | `120000` | 進捗が止まった場合にのみ適用される recovery タイムアウト。 |
142
+ | `logging.level` | いいえ | `info` | host/file 両方に使う構造化ログレベル。`debug`、`info`、`warn`、`error` に正規化されます。 |
143
+ | `logging.sinks.host` | いいえ | `true` | `client.app.log({ body: ... })` 経由で OpenCode Host ログへ書き込むかどうか。 |
144
+ | `logging.sinks.file` | いいえ | `true` | プラグイン独自の JSONL ファイルログを有効にするかどうか。 |
145
+ | `logging.file.dir` | いいえ | `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot` | プラグイン JSONL ログのディレクトリ。相対パスは現在の OpenCode worktree 基準で解決されます。 |
146
+ | `logging.file.retention.maxFiles` | いいえ | `30` | 保持するプラグインログファイル数の上限。 |
147
+ | `logging.file.retention.maxTotalBytes` | いいえ | `314572800` | 保持するプラグインログ合計サイズの上限。 |
148
+ | `logLevel` | いいえ | `info` | `logging.level` の互換エイリアス。後方互換のため引き続き利用できます。 |
105
149
 
106
150
  ### 補足
107
151
 
108
152
  - `state.path` は現在の OpenCode worktree からの相対パスとして解決されます。
153
+ - `logging.file.dir` が相対パスの場合も現在の worktree から解決されます。
154
+ - Telegram の prompt 処理は async-first です。プラグインは `session.promptAsync()` を送信し、その後メッセージとセッション状態から最終応答を回収します。
109
155
  - `telegram.allowedChatIds` を空のままにすると、bot は任意の chat からのメッセージを受け付けます。本番では制限を設定してください。
110
- - 権限承認とセッションエラー通知はプラグインの hook で処理されます。
111
- - `/language` は現在 English、简体中文、日本語 をサポートしています。
156
+ - 権限承認とセッションエラー通知はプラグイン hook で処理されます。
157
+ - `/language` は現在 English、简体中文、日本語 をサポートし、その chat 用の Telegram コマンド説明も同期します。
158
+ - ファイルログは既定でメタデータのみを記録し、prompt 本文、添付内容、生の URL、secret は書き込みません。
112
159
 
113
160
  ## クイックスタート
114
161
 
115
- 1. `npm exec --package opencode-tbot@latest opencode-tbot -- install` でプラグインをインストールします。
116
- 2. 特定の chat のみ許可したい場合は、`~/.config/opencode/opencode-tbot/config.json` `telegram.allowedChatIds` を設定します。
117
- 3. 対象の worktree で OpenCode を起動し、プラグインランタイムを読み込ませます。
118
- 4. Telegram で `/status` を実行し、接続を確認します。
119
- 5. `/new [title]` を実行するか、テキストメッセージを直接送信して使い始めます。
162
+ 1. `npm exec --package opencode-tbot@latest opencode-tbot -- install` を実行します。
163
+ 2. 特定の chat だけに制限したい場合は `~/.config/opencode/opencode-tbot/config.json` `telegram.allowedChatIds` を設定します。
164
+ 3. 対象 worktree で OpenCode を起動し、プラグインランタイムを読み込ませます。
165
+ 4. Telegram で `/status` を実行して接続を確認します。
166
+ 5. `/new [title]` を実行するか、直接テキストメッセージを送信して使い始めます。
120
167
 
121
168
  ## コマンド
122
169
 
123
- - `/start` 短いウェルカムメッセージとクイックスタート手順を表示
124
- - `/status` OpenCode のヘルス、パス、プラグイン、LSP、MCP の状態をまとめて表示
125
- - `/new [title]` 新しい OpenCode セッションを作成
126
- - `/agents` または `/agent` 利用可能な agent を一覧表示し、アクティブな agent を切り替え
127
- - `/sessions` 利用可能なセッションを一覧表示し、アクティブなセッションを切り替え
128
- - `/cancel` セッション名の変更をキャンセルするか、現在のセッションで実行中のリクエストを中止
129
- - `/model` または `/models` 利用可能なモデルを一覧表示し、アクティブなモデルを切り替え
130
- - `/language` bot の表示言語を切り替え
170
+ | コマンド | 内容 |
171
+ | --- | --- |
172
+ | `/start` | ウェルカムメッセージとクイックスタートを表示します。 |
173
+ | `/status` | OpenCode のヘルス、バージョン、ワークスペースパス、プラグイン一覧、LSP、MCP の状態をまとめて表示します。 |
174
+ | `/new [title]` | 現在のプロジェクトで新しい OpenCode セッションを作成します。 |
175
+ | `/agents` または `/agent` | 利用可能なエージェントを表示し、現在のエージェントを切り替えます。 |
176
+ | `/sessions` | 利用可能なセッションを表示し、切り替えやリネーム操作を提供します。 |
177
+ | `/cancel` | 保留中のセッション名変更入力をキャンセルするか、現在のセッションで動作中のリクエストを中止します。 |
178
+ | `/model` または `/models` | 利用可能なモデルを表示し、切り替えや推論レベル選択を行います。 |
179
+ | `/language` | 現在の chat に対する bot 表示言語を切り替えます。 |
131
180
 
132
- メッセージ処理:
181
+ ### メッセージ動作
133
182
 
134
- - コマンド以外のテキストは prompt として扱われ、OpenCode に送信されます。
183
+ - コマンド以外のテキストは prompt として OpenCode に送信されます。
135
184
  - Telegram の写真と画像ドキュメントは OpenCode のファイルパートとして転送されます。
185
+ - 画像添付は現在のセッションの一時 fork 内で処理されるため、後続のテキスト専用コンテキストを汚しません。
186
+ - `/cancel` は OpenCode セッション側の処理と Telegram 側の待機状態を同時に中止し、次の prompt をすぐ開始できるようにします。
136
187
  - Telegram の音声メッセージは未対応で、ローカライズされた拒否メッセージを返します。
137
188
 
189
+ ## ロギング
190
+
191
+ - OpenCode Host ログディレクトリ: `%USERPROFILE%/.local/share/opencode/log`
192
+ - プラグインログディレクトリ: `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot`
193
+ - ファイル形式: 追記型 JSONL、1 行 1 イベント
194
+ - 代表的な相関フィールド: `runtimeId`, `operationId`, `correlationId`, `updateId`, `chatId`, `sessionId`, `projectId`
195
+ - よく出るコンポーネント: `runtime`, `telegram`, `opencode`, `prompt`, `plugin-event`, `storage`
196
+ - 既定の保持ポリシー: 新しい 30 ファイルまで、合計 300 MB まで
197
+
138
198
  ## 開発
139
199
 
140
- プラグインバンドルをビルド:
200
+ 依存関係のインストール:
201
+
202
+ ```bash
203
+ pnpm install
204
+ ```
205
+
206
+ ビルド:
141
207
 
142
208
  ```bash
143
209
  pnpm build
@@ -149,13 +215,27 @@ pnpm build
149
215
  pnpm typecheck
150
216
  ```
151
217
 
152
- テスト実行:
218
+ 通常テストの実行:
153
219
 
154
220
  ```bash
155
221
  pnpm test
156
222
  ```
157
223
 
158
- 通常の利用では、グローバルにインストールした npm プラグインとグローバル OpenCode 設定を使ってください。このリポジトリには既定の `.opencode/plugins` bridge は含めていません。
224
+ CI に最も近い統合経路の実行:
225
+
226
+ ```bash
227
+ npm install -g opencode-ai
228
+ OPENCODE_HOST_E2E=1 pnpm test
229
+ ```
230
+
231
+ PowerShell の場合:
232
+
233
+ ```powershell
234
+ npm install -g opencode-ai
235
+ $env:OPENCODE_HOST_E2E="1"; pnpm test
236
+ ```
237
+
238
+ 通常利用では、グローバルにインストールした npm プラグインとグローバル OpenCode 設定を使ってください。このリポジトリは既定の `.opencode/plugins` bridge を含みません。
159
239
 
160
240
  このリポジトリでソースベースのローカル読み込みを行いたい場合は、`.opencode/plugins/opencode-tbot.ts` を手動で作成してください。
161
241
 
@@ -169,7 +249,11 @@ export { default } from "../../src/plugin.ts";
169
249
 
170
250
  ### 実行中の OpenCode インスタンスは必要ですか?
171
251
 
172
- はい。このリポジトリが提供するのは Telegram 連携レイヤーであり、プラグインを読み込む OpenCode ホストプロセスに依存します。
252
+ はい。このリポジトリは Telegram 連携レイヤーのみを提供しており、プラグインを読み込む OpenCode Host プロセスに依存します。
253
+
254
+ ### なぜ OpenCode に `file:///.../node_modules/...` 形式のプラグインパスが表示されるのですか?
255
+
256
+ 通常は、どこかのローカルプロジェクトに `opencode-tbot` が `node_modules` として入っていることを意味します。CLI はその状態を検出すると警告します。そのプロジェクトで `npm uninstall opencode-tbot` を実行してローカル依存を外し、推奨の `npm exec --package ...` インストールフローを使ってください。
173
257
 
174
258
  ### これは OpenCode の公式プロジェクトですか?
175
259
 
package/README.md CHANGED
@@ -8,23 +8,24 @@ A Telegram plugin for driving [OpenCode](https://opencode.ai) from chat.
8
8
 
9
9
  ## Overview
10
10
 
11
- `opencode-tbot` lets you operate OpenCode from Telegram.
11
+ `opencode-tbot` lets you operate OpenCode from Telegram with a single bot binding per chat.
12
12
 
13
- - Text messages are forwarded to the active OpenCode session.
13
+ - Plain text messages are forwarded to the current OpenCode session.
14
14
  - Telegram photos and image documents are uploaded as OpenCode file parts.
15
15
  - Image turns run in a temporary forked session, so later text-only prompts do not inherit image context.
16
- - Telegram voice messages are explicitly rejected with a localized reply.
17
16
  - Permission requests raised by OpenCode can be approved or rejected from Telegram inline buttons.
18
17
  - Session error events can be reported back to the bound Telegram chat.
19
- - Chat bindings are stored in a JSON state file.
18
+ - Voice messages are explicitly rejected with a localized reply.
19
+ - Chat bindings and session selections are stored in a JSON state file.
20
20
 
21
21
  ## Requirements
22
22
 
23
23
  - A running OpenCode host process that loads the plugin.
24
24
  - A Telegram bot token.
25
25
  - Node.js `>=22.12.0` for the CLI and local development workflow.
26
+ - `pnpm` for repository development.
26
27
 
27
- ## Install
28
+ ## Install And Update
28
29
 
29
30
  Recommended install:
30
31
 
@@ -32,7 +33,12 @@ Recommended install:
32
33
  npm exec --package opencode-tbot@latest opencode-tbot -- install
33
34
  ```
34
35
 
35
- The installer registers the plugin globally, updates the resolved OpenCode config file, writes the default runtime config, and prints the OpenCode config path, plugin config path, and default plugin log directory.
36
+ The installer:
37
+
38
+ - registers `opencode-tbot@latest` in the global OpenCode plugin list
39
+ - updates the resolved OpenCode config file
40
+ - writes or merges the global plugin runtime config
41
+ - prints the OpenCode config path, plugin config path, and default plugin log directory
36
42
 
37
43
  If `~/.config/opencode/opencode.jsonc` already exists, the installer updates that file. Otherwise it uses `~/.config/opencode/opencode.json`.
38
44
 
@@ -42,12 +48,18 @@ Check the installed CLI version:
42
48
  npm exec --package opencode-tbot@latest opencode-tbot -- --version
43
49
  ```
44
50
 
45
- Update the registered npm plugin spec in OpenCode:
51
+ Update the registered npm plugin spec in OpenCode without touching your bot token:
46
52
 
47
53
  ```bash
48
54
  npm exec --package opencode-tbot@latest opencode-tbot -- update
49
55
  ```
50
56
 
57
+ `install` is the default command. For example, this also works for a non-interactive install:
58
+
59
+ ```bash
60
+ npm exec --package opencode-tbot@latest opencode-tbot -- --bot-token <token>
61
+ ```
62
+
51
63
  ### CLI Options
52
64
 
53
65
  `install` supports:
@@ -65,15 +77,23 @@ npm exec --package opencode-tbot@latest opencode-tbot -- update
65
77
 
66
78
  ## Configuration
67
79
 
68
- Runtime config is loaded from `~/.config/opencode/opencode-tbot/config.json`.
80
+ Runtime config is loaded only from:
69
81
 
70
- OpenCode plugin registration is stored in the global OpenCode config (`~/.config/opencode/opencode.jsonc` when present, otherwise `~/.config/opencode/opencode.json`).
82
+ - `~/.config/opencode/opencode-tbot/config.json`
71
83
 
72
- Legacy `<worktree>/tbot.config.json` files are ignored at runtime. If one is present, the plugin logs a warning so you can migrate its values into the global config.
84
+ OpenCode plugin registration is stored in the global OpenCode config:
73
85
 
74
- Legacy `openrouter` voice-transcription settings are ignored at runtime. When the installer rewrites the config, it removes them.
86
+ - `~/.config/opencode/opencode.jsonc` when present
87
+ - otherwise `~/.config/opencode/opencode.json`
75
88
 
76
- ### Example Global `config.json`
89
+ This plugin does not read runtime settings from `.env`. Use the global JSON config instead.
90
+
91
+ Legacy behavior:
92
+
93
+ - `<worktree>/tbot.config.json` is ignored at runtime. If one is present, the plugin logs a warning so you can migrate it.
94
+ - legacy `openrouter` voice-transcription settings are ignored at runtime and removed when the installer rewrites the config
95
+
96
+ ### Example `config.json`
77
97
 
78
98
  ```json
79
99
  {
@@ -119,10 +139,10 @@ Legacy `openrouter` voice-transcription settings are ignored at runtime. When th
119
139
  | `prompt.waitTimeoutMs` | No | `1800000` | Maximum total wait for one async prompt lifecycle before the plugin stops waiting for OpenCode recovery. |
120
140
  | `prompt.pollRequestTimeoutMs` | No | `15000` | Timeout for each individual recovery poll request to OpenCode. |
121
141
  | `prompt.recoveryInactivityTimeoutMs` | No | `120000` | Recovery timeout that only applies when prompt progress stops advancing. |
122
- | `logging.level` | No | `info` | Structured log level for both host and file sinks. |
142
+ | `logging.level` | No | `info` | Structured log level for host and file sinks. Accepted values normalize to `debug`, `info`, `warn`, or `error`. |
123
143
  | `logging.sinks.host` | No | `true` | Enable OpenCode host logging through `client.app.log({ body: ... })`. |
124
144
  | `logging.sinks.file` | No | `true` | Enable plugin-owned JSONL file logs. |
125
- | `logging.file.dir` | No | `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot` | Plugin JSONL log directory. |
145
+ | `logging.file.dir` | No | `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot` | Plugin JSONL log directory. Relative paths are resolved from the current OpenCode worktree. |
126
146
  | `logging.file.retention.maxFiles` | No | `30` | Maximum number of retained plugin log files. |
127
147
  | `logging.file.retention.maxTotalBytes` | No | `314572800` | Maximum total size of retained plugin log files. |
128
148
  | `logLevel` | No | `info` | Legacy alias for `logging.level`. Still accepted for compatibility. |
@@ -130,25 +150,13 @@ Legacy `openrouter` voice-transcription settings are ignored at runtime. When th
130
150
  ### Notes
131
151
 
132
152
  - `state.path` is resolved relative to the current OpenCode worktree.
153
+ - Relative `logging.file.dir` values are also resolved from the current worktree.
133
154
  - Telegram prompt handling is async-first: the plugin submits `session.promptAsync()` and then recovers the reply from session messages and session status.
134
- - `prompt.waitTimeoutMs` is the total safety cap; `prompt.recoveryInactivityTimeoutMs` only applies when OpenCode stops making progress.
135
155
  - If `telegram.allowedChatIds` is left empty, the bot accepts messages from any chat. Restrict it in production.
136
156
  - Permission approvals and session error notifications are handled through plugin hooks.
137
- - `/language` currently supports English, Simplified Chinese, and Japanese.
138
- - Plugin logs are dual-written by default: OpenCode host logs through `client.app.log({ body: ... })`, plus plugin JSONL files.
139
- - OpenCode host logs live under `%USERPROFILE%/.local/share/opencode/log`.
140
- - The default plugin JSONL log directory is `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot`.
157
+ - `/language` currently supports English, Simplified Chinese, and Japanese, and syncs localized Telegram command descriptions for that chat.
141
158
  - File logs are metadata-only by default. Prompt bodies, attachment contents, raw URLs, and secrets are not written.
142
159
 
143
- ## Logging
144
-
145
- - Host log directory: `%USERPROFILE%/.local/share/opencode/log`
146
- - Plugin log directory: `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot`
147
- - File format: append-only JSONL, one structured event per line
148
- - Correlation fields: `runtimeId`, `operationId`, `correlationId`, `updateId`, `chatId`, `sessionId`, `projectId`
149
- - Common components: `runtime`, `telegram`, `opencode`, `prompt`, `plugin-event`, `storage`
150
- - Retention: keep the newest 30 files and at most 300 MB by default
151
-
152
160
  ## Quick Start
153
161
 
154
162
  1. Install the plugin with `npm exec --package opencode-tbot@latest opencode-tbot -- install`.
@@ -159,26 +167,43 @@ Legacy `openrouter` voice-transcription settings are ignored at runtime. When th
159
167
 
160
168
  ## Commands
161
169
 
162
- - `/start` show a short welcome message and quick-start steps
163
- - `/status` show aggregated OpenCode health, path, plugin, LSP, and MCP status
164
- - `/new [title]` create a new OpenCode session
165
- - `/agents` or `/agent` list available agents and switch the active one
166
- - `/sessions` list available sessions and switch the active one
167
- - `/cancel` cancel session rename or abort the running request for the current session, including the local Telegram wait state
168
- - `/model` or `/models` list available models and switch the active one
169
- - `/language` switch the bot display language
170
+ | Command | What it does |
171
+ | --- | --- |
172
+ | `/start` | Show a short welcome message and quick-start steps. |
173
+ | `/status` | Show aggregated OpenCode health, version, workspace paths, plugin list, LSP status, and MCP status. |
174
+ | `/new [title]` | Create a new OpenCode session in the current project. |
175
+ | `/agents` or `/agent` | List available agents and switch the active one. |
176
+ | `/sessions` | List available sessions, switch the active one, and offer rename actions. |
177
+ | `/cancel` | Cancel pending session rename input or abort the running request for the current session. |
178
+ | `/model` or `/models` | List available models, switch the active one, and choose a reasoning level when available. |
179
+ | `/language` | Switch the bot display language for the current chat. |
170
180
 
171
- Message handling:
181
+ ### Message Behavior
172
182
 
173
183
  - Non-command text is treated as a prompt and sent to OpenCode.
174
184
  - Telegram photos and image documents are forwarded as OpenCode file parts.
175
185
  - Image attachments are processed in a temporary fork of the active session so later text-only prompts stay clean.
176
- - `/cancel` aborts both the OpenCode session and the local Telegram wait, so the next prompt can start immediately.
186
+ - `/cancel` aborts both the OpenCode session and the local Telegram wait state, so the next prompt can start immediately.
177
187
  - Telegram voice messages are not supported and receive a localized rejection reply.
178
188
 
189
+ ## Logging
190
+
191
+ - Host log directory: `%USERPROFILE%/.local/share/opencode/log`
192
+ - Plugin log directory: `%USERPROFILE%/.local/share/opencode/log/plugins/opencode-tbot`
193
+ - File format: append-only JSONL, one structured event per line
194
+ - Correlation fields: `runtimeId`, `operationId`, `correlationId`, `updateId`, `chatId`, `sessionId`, `projectId`
195
+ - Common components: `runtime`, `telegram`, `opencode`, `prompt`, `plugin-event`, `storage`
196
+ - Default retention: newest 30 files and at most 300 MB total
197
+
179
198
  ## Development
180
199
 
181
- Build the plugin bundle:
200
+ Install dependencies:
201
+
202
+ ```bash
203
+ pnpm install
204
+ ```
205
+
206
+ Build the bundle:
182
207
 
183
208
  ```bash
184
209
  pnpm build
@@ -190,13 +215,27 @@ Type-check:
190
215
  pnpm typecheck
191
216
  ```
192
217
 
193
- Run tests:
218
+ Run the normal test suite:
194
219
 
195
220
  ```bash
196
221
  pnpm test
197
222
  ```
198
223
 
199
- Normal usage should rely on the globally installed npm plugin plus the global OpenCode config. This repository no longer ships a default `.opencode/plugins` bridge.
224
+ Run the integration path closest to CI:
225
+
226
+ ```bash
227
+ npm install -g opencode-ai
228
+ OPENCODE_HOST_E2E=1 pnpm test
229
+ ```
230
+
231
+ PowerShell:
232
+
233
+ ```powershell
234
+ npm install -g opencode-ai
235
+ $env:OPENCODE_HOST_E2E="1"; pnpm test
236
+ ```
237
+
238
+ Normal usage should rely on the globally installed npm plugin plus the global OpenCode config. This repository does not ship a default `.opencode/plugins` bridge.
200
239
 
201
240
  If you need source-based local loading while developing in this repository, create `.opencode/plugins/opencode-tbot.ts` manually:
202
241
 
@@ -212,6 +251,10 @@ Keep only one loading path enabled at a time: either the manual local bridge or
212
251
 
213
252
  Yes. This repository provides a Telegram integration layer and depends on the OpenCode host process that loads the plugin.
214
253
 
254
+ ### Why does OpenCode show the plugin as `file:///.../node_modules/...`?
255
+
256
+ That usually means a local project has `opencode-tbot` installed in its own `node_modules`. The CLI warns when it detects that layout. Remove the local package with `npm uninstall opencode-tbot` in that project and use the recommended `npm exec --package ...` install flow instead.
257
+
215
258
  ### Is this an official OpenCode project?
216
259
 
217
260
  No. It integrates with OpenCode, but it is not built by the OpenCode team.