opencode-telegram-bridge 1.0.8 → 1.1.1

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.
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import "../dist/index.js"
2
+ import "../dist/cli.js"
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,155 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import readline from "node:readline/promises";
6
+ import { stdin, stdout } from "node:process";
7
+ import { fileURLToPath } from "node:url";
8
+ import { runBot } from "./run.js";
9
+ const die = (message) => {
10
+ console.error(message);
11
+ process.exit(1);
12
+ };
13
+ const runCommand = (command, args) => {
14
+ const result = spawnSync(command, args, {
15
+ encoding: "utf8",
16
+ stdio: "inherit",
17
+ });
18
+ if (result.status !== 0) {
19
+ throw new Error(`Command failed: ${command} ${args.join(" ")}`);
20
+ }
21
+ };
22
+ const resolveExecStart = () => {
23
+ const nodePath = process.execPath;
24
+ const cliPath = fileURLToPath(import.meta.url);
25
+ return { nodePath, cliPath };
26
+ };
27
+ const readAnswer = async (prompt, options = {}) => {
28
+ const rl = readline.createInterface({ input: stdin, output: stdout });
29
+ const suffix = options.defaultValue ? ` (${options.defaultValue})` : "";
30
+ const answer = (await rl.question(`${prompt}${suffix}: `)).trim();
31
+ rl.close();
32
+ if (!answer && options.defaultValue) {
33
+ return options.defaultValue;
34
+ }
35
+ if (!answer && options.required) {
36
+ throw new Error(`Missing ${prompt}`);
37
+ }
38
+ return answer;
39
+ };
40
+ const confirmAnswer = async (prompt, defaultValue = false) => {
41
+ const rl = readline.createInterface({ input: stdin, output: stdout });
42
+ const suffix = defaultValue ? "(Y/n)" : "(y/N)";
43
+ const answer = (await rl.question(`${prompt} ${suffix}: `)).trim();
44
+ rl.close();
45
+ if (!answer) {
46
+ return defaultValue;
47
+ }
48
+ return answer.toLowerCase().startsWith("y");
49
+ };
50
+ const writeEnvFile = (envPath, values) => {
51
+ const lines = Object.entries(values).map(([key, value]) => `${key}=${value}`);
52
+ fs.mkdirSync(path.dirname(envPath), { recursive: true });
53
+ fs.writeFileSync(envPath, `${lines.join("\n")}\n`, "utf8");
54
+ };
55
+ const writeUnitFile = (unitPath, content) => {
56
+ fs.mkdirSync(path.dirname(unitPath), { recursive: true });
57
+ fs.writeFileSync(unitPath, content, "utf8");
58
+ };
59
+ const buildUnitFile = (envPath, nodePath, cliPath) => `
60
+ [Unit]
61
+ Description=OpenCode Telegram Bridge
62
+ After=network-online.target
63
+ Wants=network-online.target
64
+
65
+ [Service]
66
+ Type=simple
67
+ EnvironmentFile=${envPath}
68
+ ExecStart=${nodePath} ${cliPath}
69
+ Restart=on-failure
70
+ RestartSec=3
71
+
72
+ [Install]
73
+ WantedBy=default.target
74
+ `;
75
+ const runSetupWizard = async () => {
76
+ if (process.platform !== "linux") {
77
+ die("Setup currently supports Linux systemd only. See the docs for manual setup.");
78
+ }
79
+ const systemctlCheck = spawnSync("systemctl", ["--user", "--version"], {
80
+ encoding: "utf8",
81
+ });
82
+ if (systemctlCheck.status !== 0) {
83
+ die("systemctl --user is not available. Install systemd or use manual setup.");
84
+ }
85
+ const homeDir = os.homedir();
86
+ const envPath = path.join(homeDir, ".config", "opencode-telegram-bridge", "opencode-telegram-bridge.env");
87
+ const unitPath = path.join(homeDir, ".config", "systemd", "user", "opencode-telegram-bridge.service");
88
+ if (fs.existsSync(envPath) || fs.existsSync(unitPath)) {
89
+ const overwrite = await confirmAnswer("Existing config found. Overwrite?", false);
90
+ if (!overwrite) {
91
+ die("Setup cancelled.");
92
+ }
93
+ }
94
+ const botToken = await readAnswer("TELEGRAM_BOT_TOKEN", { required: true });
95
+ const allowedUserId = await readAnswer("TELEGRAM_ALLOWED_USER_ID", {
96
+ required: true,
97
+ });
98
+ if (!Number.isInteger(Number(allowedUserId))) {
99
+ throw new Error("TELEGRAM_ALLOWED_USER_ID must be an integer");
100
+ }
101
+ const serverUrl = await readAnswer("OPENCODE_SERVER_URL", {
102
+ defaultValue: "http://127.0.0.1:4096",
103
+ });
104
+ const serverUsername = await readAnswer("OPENCODE_SERVER_USERNAME", {
105
+ defaultValue: "opencode",
106
+ });
107
+ const serverPassword = await readAnswer("OPENCODE_SERVER_PASSWORD", {});
108
+ const opencodeRestartCommand = await readAnswer("OPENCODE_RESTART_COMMAND", {});
109
+ const opencodeRestartTimeoutMs = opencodeRestartCommand ? "30000" : "";
110
+ const { nodePath, cliPath } = resolveExecStart();
111
+ writeEnvFile(envPath, {
112
+ TELEGRAM_BOT_TOKEN: botToken,
113
+ TELEGRAM_ALLOWED_USER_ID: allowedUserId,
114
+ OPENCODE_SERVER_URL: serverUrl,
115
+ OPENCODE_SERVER_USERNAME: serverUsername,
116
+ OPENCODE_SERVER_PASSWORD: serverPassword,
117
+ OPENCODE_PROMPT_TIMEOUT_MS: "600000",
118
+ TELEGRAM_HANDLER_TIMEOUT_MS: "630000",
119
+ OPENCODE_RESTART_COMMAND: opencodeRestartCommand,
120
+ OPENCODE_RESTART_TIMEOUT_MS: opencodeRestartTimeoutMs,
121
+ OPENCODE_BRIDGE_RESTART_COMMAND: "systemctl --user restart opencode-telegram-bridge --no-block",
122
+ OPENCODE_BRIDGE_RESTART_TIMEOUT_MS: "30000",
123
+ });
124
+ const unitFile = buildUnitFile(envPath, nodePath, cliPath);
125
+ writeUnitFile(unitPath, unitFile);
126
+ runCommand("systemctl", ["--user", "daemon-reload"]);
127
+ runCommand("systemctl", ["--user", "enable", "--now", "opencode-telegram-bridge"]);
128
+ const enableLinger = await confirmAnswer("Enable linger so the service starts on boot without login?", false);
129
+ if (enableLinger) {
130
+ const user = os.userInfo().username;
131
+ const result = spawnSync("sudo", ["loginctl", "enable-linger", user], {
132
+ encoding: "utf8",
133
+ stdio: "inherit",
134
+ });
135
+ if (result.status !== 0) {
136
+ console.warn("Failed to enable linger. Run: sudo loginctl enable-linger");
137
+ }
138
+ }
139
+ console.log("Setup complete. Service is running.");
140
+ console.log(`Env file: ${envPath}`);
141
+ console.log(`Unit file: ${unitPath}`);
142
+ };
143
+ const command = process.argv[2];
144
+ if (!command) {
145
+ runBot();
146
+ }
147
+ else if (command === "setup") {
148
+ runSetupWizard().catch((error) => {
149
+ die(error instanceof Error ? error.message : "Setup failed.");
150
+ });
151
+ }
152
+ else {
153
+ die("Unknown command. Use: opencode-telegram-bridge [setup]");
154
+ }
155
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import "dotenv/config";
1
+ export {};
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -1,16 +1,3 @@
1
- import "dotenv/config";
2
- import { loadConfig } from "./config.js";
3
- import { startBot } from "./bot.js";
4
- import { createOpencodeBridge } from "./opencode.js";
5
- import { createProjectStore } from "./projects.js";
6
- import { createChatModelStore, createChatProjectStore, createPersistentSessionStore, } from "./state.js";
7
- const config = loadConfig();
8
- const sessionStore = createPersistentSessionStore();
9
- const opencode = createOpencodeBridge(config.opencode, { sessionStore });
10
- const projects = createProjectStore();
11
- const chatProjects = createChatProjectStore();
12
- const chatModels = createChatModelStore();
13
- const bot = startBot(config, opencode, projects, chatProjects, chatModels);
14
- process.once("SIGINT", () => bot.stop("SIGINT"));
15
- process.once("SIGTERM", () => bot.stop("SIGTERM"));
1
+ import { runBot } from "./run.js";
2
+ runBot();
16
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;AAC3B,MAAM,YAAY,GAAG,4BAA4B,EAAE,CAAA;AACnD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;AACxE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;AACrC,MAAM,YAAY,GAAG,sBAAsB,EAAE,CAAA;AAC7C,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAA;AACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,CAAA;AAE1E,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;AAChD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,EAAE,CAAA"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import "dotenv/config";
2
+ export declare const runBot: () => import("telegraf").Telegraf<import("telegraf").Context<import("@telegraf/types").Update>>;
3
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAYtB,eAAO,MAAM,MAAM,iGAalB,CAAA"}
package/dist/run.js ADDED
@@ -0,0 +1,19 @@
1
+ import "dotenv/config";
2
+ import { loadConfig } from "./config.js";
3
+ import { startBot } from "./bot.js";
4
+ import { createOpencodeBridge } from "./opencode.js";
5
+ import { createProjectStore } from "./projects.js";
6
+ import { createChatModelStore, createChatProjectStore, createPersistentSessionStore, } from "./state.js";
7
+ export const runBot = () => {
8
+ const config = loadConfig();
9
+ const sessionStore = createPersistentSessionStore();
10
+ const opencode = createOpencodeBridge(config.opencode, { sessionStore });
11
+ const projects = createProjectStore();
12
+ const chatProjects = createChatProjectStore();
13
+ const chatModels = createChatModelStore();
14
+ const bot = startBot(config, opencode, projects, chatProjects, chatModels);
15
+ process.once("SIGINT", () => bot.stop("SIGINT"));
16
+ process.once("SIGTERM", () => bot.stop("SIGTERM"));
17
+ return bot;
18
+ };
19
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,YAAY,CAAA;AAEnB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,EAAE;IACzB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,4BAA4B,EAAE,CAAA;IACnD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;IACxE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,YAAY,GAAG,sBAAsB,EAAE,CAAA;IAC7C,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAA;IACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,CAAA;IAE1E,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;IAElD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
@@ -12,10 +12,13 @@ Set these environment variables in your shell or service environment.
12
12
  - `OPENCODE_SERVER_PASSWORD` - Basic auth password.
13
13
  - `OPENCODE_PROMPT_TIMEOUT_MS` - Prompt timeout in milliseconds (default: 600000).
14
14
  - `TELEGRAM_HANDLER_TIMEOUT_MS` - Telegraf handler timeout in milliseconds (default: prompt timeout + 30000).
15
- - `OPENCODE_RESTART_COMMAND` - Command to restart OpenCode when `/reboot` is used (example: `sudo -n systemctl restart opencode`).
15
+ - `OPENCODE_RESTART_COMMAND` - Command to restart OpenCode when `/reboot` is used (example: `systemctl --user restart opencode --no-block`).
16
16
  - `OPENCODE_RESTART_TIMEOUT_MS` - Restart command timeout in milliseconds (default: 30000).
17
- - `OPENCODE_BRIDGE_RESTART_COMMAND` - Command to restart the Telegram bridge when `/restart` is used (example: `sudo -n systemctl restart opencode-telegram-bridge`).
17
+ - `OPENCODE_BRIDGE_RESTART_COMMAND` - Command to restart the Telegram bridge when `/restart` is used (example: `systemctl --user restart opencode-telegram-bridge --no-block`).
18
18
  - `OPENCODE_BRIDGE_RESTART_TIMEOUT_MS` - Restart command timeout in milliseconds (default: 30000).
19
19
 
20
20
  ## Data storage
21
21
  - Project aliases and chat selections are stored in `~/.opencode-telegram-bridge/projects.db`.
22
+
23
+ ## systemd user service
24
+ The setup wizard writes a user service env file at `~/.config/opencode-telegram-bridge/opencode-telegram-bridge.env`.
@@ -10,6 +10,13 @@
10
10
  npm install -g opencode-telegram-bridge
11
11
  ```
12
12
 
13
+ ## Setup (Linux systemd)
14
+ ```bash
15
+ opencode-telegram-bridge setup
16
+ ```
17
+
18
+ Setup currently supports Linux systemd only. On other platforms, run the bot manually.
19
+
13
20
  ## Run the bot
14
21
  ```bash
15
22
  opencode-telegram-bridge
package/docs/systemd.md CHANGED
@@ -1,8 +1,13 @@
1
- # systemd Service (Linux)
1
+ # systemd Service (Linux user)
2
2
 
3
- This project ships a systemd unit template in `systemd/opencode-telegram-bridge.service`.
3
+ This project ships a user systemd unit template in `systemd/opencode-telegram-bridge.service`.
4
4
 
5
- ## Install
5
+ ## Recommended: setup wizard
6
+ ```bash
7
+ opencode-telegram-bridge setup
8
+ ```
9
+
10
+ ## Manual install
6
11
  1. Install the package:
7
12
 
8
13
  ```bash
@@ -12,18 +17,19 @@ npm install -g opencode-telegram-bridge
12
17
  2. Copy the service and env files:
13
18
 
14
19
  ```bash
15
- sudo mkdir -p /etc/opencode-telegram-bridge
16
- sudo cp systemd/opencode-telegram-bridge.service /etc/systemd/system/opencode-telegram-bridge.service
17
- sudo cp systemd/opencode-telegram-bridge.env.example /etc/opencode-telegram-bridge.env
20
+ mkdir -p ~/.config/systemd/user
21
+ mkdir -p ~/.config/opencode-telegram-bridge
22
+ cp systemd/opencode-telegram-bridge.service ~/.config/systemd/user/opencode-telegram-bridge.service
23
+ cp systemd/opencode-telegram-bridge.env.example ~/.config/opencode-telegram-bridge/opencode-telegram-bridge.env
18
24
  ```
19
25
 
20
26
  3. Edit the env file:
21
27
 
22
28
  ```bash
23
- sudo nano /etc/opencode-telegram-bridge.env
29
+ nano ~/.config/opencode-telegram-bridge/opencode-telegram-bridge.env
24
30
  ```
25
31
 
26
- 4. Update the service paths if needed:
32
+ 4. Update the service path if needed:
27
33
 
28
34
  - `ExecStart=/usr/bin/opencode-telegram-bridge`
29
35
  - If you installed via npm in a non-standard location, set `ExecStart` to the output of `command -v opencode-telegram-bridge`.
@@ -31,11 +37,18 @@ sudo nano /etc/opencode-telegram-bridge.env
31
37
  5. Enable and start:
32
38
 
33
39
  ```bash
34
- sudo systemctl daemon-reload
35
- sudo systemctl enable --now opencode-telegram-bridge
40
+ systemctl --user daemon-reload
41
+ systemctl --user enable --now opencode-telegram-bridge
42
+ ```
43
+
44
+ ## Start on boot (optional)
45
+ User services normally start on login. To run on boot without a login session:
46
+
47
+ ```bash
48
+ sudo loginctl enable-linger $(whoami)
36
49
  ```
37
50
 
38
51
  ## Logs
39
52
  ```bash
40
- sudo journalctl -u opencode-telegram-bridge -f
53
+ journalctl --user -u opencode-telegram-bridge -f
41
54
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-telegram-bridge",
3
- "version": "1.0.8",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -6,6 +6,6 @@ OPENCODE_SERVER_PASSWORD=
6
6
  OPENCODE_PROMPT_TIMEOUT_MS=600000
7
7
  TELEGRAM_HANDLER_TIMEOUT_MS=630000
8
8
  OPENCODE_RESTART_COMMAND=
9
- OPENCODE_RESTART_TIMEOUT_MS=30000
10
- OPENCODE_BRIDGE_RESTART_COMMAND=
9
+ OPENCODE_RESTART_TIMEOUT_MS=
10
+ OPENCODE_BRIDGE_RESTART_COMMAND=systemctl --user restart opencode-telegram-bridge --no-block
11
11
  OPENCODE_BRIDGE_RESTART_TIMEOUT_MS=30000
@@ -5,10 +5,10 @@ Wants=network-online.target
5
5
 
6
6
  [Service]
7
7
  Type=simple
8
- EnvironmentFile=/etc/opencode-telegram-bridge.env
8
+ EnvironmentFile=%h/.config/opencode-telegram-bridge/opencode-telegram-bridge.env
9
9
  ExecStart=/usr/bin/opencode-telegram-bridge
10
10
  Restart=on-failure
11
11
  RestartSec=3
12
12
 
13
13
  [Install]
14
- WantedBy=multi-user.target
14
+ WantedBy=default.target