opencode-telegram-connect 1.0.2 → 1.0.3

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.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Control a running OpenCode session from Telegram with your own bot. Messages are forwarded to OpenCode; answers, permission requests, and questions from the agent appear in Telegram. The plugin supports OpenCode on Windows, WSL, Linux, and macOS.
4
4
 
5
- **Telegram stays off when OpenCode starts.** The connection only begins when you ask your agent to connect and it calls `telegram_connect`. There is no Telegram command to turn it on; the former start command is ignored and never forwarded to the model.
5
+ **Telegram stays off when OpenCode starts.** The connection only begins when you ask your agent to connect and it calls `telegram_connect`. There is no Telegram command to turn it on; `/start` and `/help` show the connection guide while the bridge is active; they cannot start an inactive bridge.
6
6
 
7
7
  ## Features
8
8
 
@@ -10,7 +10,7 @@ Control a running OpenCode session from Telegram with your own bot. Messages are
10
10
  - **Allowlist security.** Only configured Telegram user IDs or chat IDs can control the session; everything else is rejected. One-time pairing codes are supported when no allowlist is configured.
11
11
  - **Full session control.** List, switch, create, and rename sessions; list and switch models; abort running work.
12
12
  - **Permissions and questions in chat.** Approve, always-allow, or deny tool permissions and answer agent questions directly from Telegram, including inline buttons.
13
- - **Local credentials only.** The bot token and your user ID live in a local env file; nothing is uploaded anywhere.
13
+ - **Local credentials only.** The bot token and your user ID live in a local env file; the token is sent only to Telegram for authentication. Prompts and responses pass through Telegram and the configured OpenCode model provider.
14
14
 
15
15
  ## System requirements
16
16
 
@@ -32,11 +32,11 @@ These are required only when building or testing this repository from source:
32
32
 
33
33
  ## Platform support
34
34
 
35
- The plugin uses only Node.js built-ins (`node:fs`, `node:os`, `node:path`, `node:http`) and the OpenCode plugin/SDK API. There is no platform-specific code:
35
+ The plugin uses only Node.js built-ins (`node:fs`, `node:os`, `node:path`, `node:crypto`) and the OpenCode plugin/SDK API. There is no platform-specific code:
36
36
 
37
37
  - The Telegram transport is plain HTTPS long polling, identical on Windows, WSL, Linux, and macOS.
38
38
  - The config file is resolved through `os.homedir()` (`~/.config/opencode/telegram.env`), so it is correct on every platform.
39
- - The bot poll lock lives under the per-user config directory and works on all supported platforms.
39
+ - The bot poll lock lives in the operating system temporary directory (`os.tmpdir()`) and works on all supported platforms.
40
40
 
41
41
  ## Install in native Windows OpenCode
42
42
 
@@ -50,7 +50,7 @@ notepad "$env:USERPROFILE\.config\opencode\opencode.json"
50
50
  ```json
51
51
  {
52
52
  "$schema": "https://opencode.ai/config.json",
53
- "plugin": ["opencode-telegram-connect@1.0.2"]
53
+ "plugin": ["opencode-telegram-connect@1.0.3"]
54
54
  }
55
55
  ```
56
56
 
@@ -59,7 +59,7 @@ Keep any other settings and plugins in the file. OpenCode downloads and installs
59
59
  Optionally install the package globally to get the `opencode-telegram-user-id` helper command:
60
60
 
61
61
  ```powershell
62
- npm install -g opencode-telegram-connect@1.0.2
62
+ npm install -g opencode-telegram-connect@1.0.3
63
63
  ```
64
64
 
65
65
  See also the [OpenCode plugin documentation](https://opencode.ai/docs/plugins/).
@@ -74,7 +74,7 @@ nano ~/.config/opencode/opencode.json
74
74
  opencode
75
75
  ```
76
76
 
77
- If your global config is `opencode.jsonc`, that file takes precedence - add the entry to its `plugin` array and check the effective list with `opencode debug config`. Pinning a version (e.g. `opencode-telegram-connect@1.0.2`) is recommended; the bare `latest` spec is cached permanently on first install.
77
+ If your global config is `opencode.jsonc`, that file takes precedence - add the entry to its `plugin` array and check the effective list with `opencode debug config`. Pinning a version (e.g. `opencode-telegram-connect@1.0.3`) is recommended; an explicit version makes upgrades deliberate and avoids relying on cache refresh behavior.
78
78
 
79
79
  ## Uninstall
80
80
 
@@ -125,7 +125,7 @@ Save the file exactly as `telegram.env`, not `telegram.env.txt`.
125
125
  Keep the Telegram connection off in OpenCode. After you have privately sent your bot `Hallo`, run:
126
126
 
127
127
  ```sh
128
- npx --yes --package=opencode-telegram-connect@1.0.2 opencode-telegram-user-id
128
+ npx --yes --package=opencode-telegram-connect@1.0.3 opencode-telegram-user-id
129
129
  ```
130
130
 
131
131
  The helper reads the token from your file and prints the user IDs of pending messages, for example `DeinName: TELEGRAM_USER=123456789`. It sends no message and never prints the token. If several people are listed, take your own ID. If nothing is listed, send `Hallo` again and repeat. No other application may poll this bot while you do this.
@@ -198,7 +198,7 @@ You first receive the session ID and then the model answer. The model works with
198
198
 
199
199
  For multiple questions: `/answer <id> answer one || answer two`. For multi-select: `Option A; Option B`. For simple choice questions and permissions you can use the inline buttons sent along.
200
200
 
201
- Other slash commands are forwarded to OpenCode as text; they do not automatically execute an OpenCode slash command. The removed start command is explicitly excluded from this.
201
+ Other slash commands are forwarded to OpenCode as text; they do not automatically execute an OpenCode slash command. `/start` and `/help` are handled locally and never sent to the model.
202
202
 
203
203
  ### Turning Telegram off completely
204
204
 
@@ -210,6 +210,10 @@ This stops polling and releases the bot lock. `/disconnect` in Telegram only rem
210
210
 
211
211
  After restarting OpenCode you must connect again. Only one OpenCode instance can be connected to the same bot at a time. Other instances do not take over the bot automatically. Disconnect the previous instance, then ask the desired agent to connect.
212
212
 
213
+ ## Automatic connection guide
214
+
215
+ After `telegram_connect`, the bridge sends the complete guide to configured users/chats and existing chat bindings. Users must have messaged the bot first and must not have blocked it. Delivery failures are reported by the connect tool; the bridge stays usable. Without static allowlists, the guide is sent after successful `/pair <code>`. Send `/start` or `/help` to display it again while connected.
216
+
213
217
  ## Configuration
214
218
 
215
219
  Existing environment variables take precedence. Accepted names:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-telegram-connect",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Native OpenCode plugin to securely control sessions from Telegram.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/telegram.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const MAX_TELEGRAM_TEXT = 4096;
2
2
 
3
3
  export function splitTelegramText(text, limit = MAX_TELEGRAM_TEXT) {
4
+ if (!Number.isInteger(limit) || limit < 2) throw new Error("Text limit must be an integer of at least 2");
4
5
  const value = String(text ?? "");
5
6
  if (value.length <= limit) return [value];
6
7
  const chunks = [];
@@ -9,8 +10,9 @@ export function splitTelegramText(text, limit = MAX_TELEGRAM_TEXT) {
9
10
  let cut = rest.lastIndexOf("\n", limit);
10
11
  if (cut < Math.floor(limit * 0.6)) cut = rest.lastIndexOf(" ", limit);
11
12
  if (cut < Math.floor(limit * 0.6)) cut = limit;
13
+ if (/[\uD800-\uDBFF]/.test(rest[cut - 1]) && /[\uDC00-\uDFFF]/.test(rest[cut])) cut--;
12
14
  chunks.push(rest.slice(0, cut));
13
- rest = rest.slice(cut).replace(/^\n/, "");
15
+ rest = rest.slice(cut);
14
16
  }
15
17
  if (rest) chunks.push(rest);
16
18
  return chunks;