@locusai/locus-telegram 0.21.6 → 0.21.8
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 +18 -0
- package/dist/bot.js +3 -3
- package/dist/commands/git.js +10 -4
- package/dist/commands/locus.js +5 -3
- package/dist/commands/service.js +6 -4
- package/dist/config.d.ts +4 -4
- package/dist/config.js +44 -22
- package/dist/index.js +10 -13
- package/dist/pm2.js +1 -6
- package/package.json +2 -2
- package/bin/locus-telegram.js +0 -7
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @locusai/locus-telegram
|
|
2
|
+
|
|
3
|
+
## 0.21.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Continious learning improvements
|
|
8
|
+
Fix Telegram package installation issue
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @locusai/sdk@0.21.8
|
|
11
|
+
|
|
12
|
+
## 0.21.7
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Initial telegram package
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @locusai/sdk@0.21.7
|
package/dist/bot.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Bot instance — sets up grammy bot, registers middleware, commands,
|
|
3
3
|
* and callback query handlers.
|
|
4
4
|
*/
|
|
5
|
-
import { Bot } from "grammy";
|
|
6
5
|
import { createLogger } from "@locusai/sdk";
|
|
6
|
+
import { Bot } from "grammy";
|
|
7
|
+
import { handleBranch, handleCheckout, handleCommit, handleDiff, handleGitStatus, handlePR, handleStage, handleStash, } from "./commands/git.js";
|
|
7
8
|
import { handleLocusCommand } from "./commands/locus.js";
|
|
8
|
-
import { handleGitStatus, handleStage, handleCommit, handleStash, handleBranch, handleCheckout, handleDiff, handlePR, } from "./commands/git.js";
|
|
9
9
|
import { handleService } from "./commands/service.js";
|
|
10
|
+
import { formatInfo, formatSuccess } from "./ui/format.js";
|
|
10
11
|
import { CB } from "./ui/keyboards.js";
|
|
11
12
|
import { welcomeMessage } from "./ui/messages.js";
|
|
12
|
-
import { formatSuccess, formatInfo } from "./ui/format.js";
|
|
13
13
|
const logger = createLogger("telegram");
|
|
14
14
|
// ─── Bot Factory ────────────────────────────────────────────────────────────
|
|
15
15
|
export function createBot(config) {
|
package/dist/commands/git.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* PR creation uses `gh` CLI (same as the locus CLI does).
|
|
6
6
|
*/
|
|
7
7
|
import { execSync } from "node:child_process";
|
|
8
|
-
import { codeBlock, formatError, formatSuccess,
|
|
8
|
+
import { bold, codeBlock, escapeHtml, formatError, formatSuccess, } from "../ui/format.js";
|
|
9
9
|
import { stashKeyboard } from "../ui/keyboards.js";
|
|
10
10
|
import { gitBranchCreatedMessage, gitCheckoutMessage, gitCommitMessage, gitStashMessage, prCreatedMessage, } from "../ui/messages.js";
|
|
11
11
|
// ─── Git Helper ─────────────────────────────────────────────────────────────
|
|
@@ -39,7 +39,9 @@ export async function handleGitStatus(ctx) {
|
|
|
39
39
|
await ctx.reply(`${bold("Branch:")} ${escapeHtml(branch)}\n\n${codeBlock(status)}`, { parse_mode: "HTML" });
|
|
40
40
|
}
|
|
41
41
|
catch (error) {
|
|
42
|
-
await ctx.reply(formatError("Failed to get git status", String(error)), {
|
|
42
|
+
await ctx.reply(formatError("Failed to get git status", String(error)), {
|
|
43
|
+
parse_mode: "HTML",
|
|
44
|
+
});
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
/** /stage [files|.] — stage files for commit */
|
|
@@ -204,11 +206,15 @@ export async function handleDiff(ctx) {
|
|
|
204
206
|
});
|
|
205
207
|
}
|
|
206
208
|
else {
|
|
207
|
-
await ctx.reply(`${bold("Staged changes:")}\n\n${codeBlock(staged)}`, {
|
|
209
|
+
await ctx.reply(`${bold("Staged changes:")}\n\n${codeBlock(staged)}`, {
|
|
210
|
+
parse_mode: "HTML",
|
|
211
|
+
});
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
214
|
else {
|
|
211
|
-
await ctx.reply(`${bold("Unstaged changes:")}\n\n${codeBlock(diff)}`, {
|
|
215
|
+
await ctx.reply(`${bold("Unstaged changes:")}\n\n${codeBlock(diff)}`, {
|
|
216
|
+
parse_mode: "HTML",
|
|
217
|
+
});
|
|
212
218
|
}
|
|
213
219
|
}
|
|
214
220
|
catch (error) {
|
package/dist/commands/locus.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* in place at regular intervals.
|
|
7
7
|
*/
|
|
8
8
|
import { invokeLocusStream } from "@locusai/sdk";
|
|
9
|
-
import { formatCommandResult, formatStreamingMessage
|
|
9
|
+
import { formatCommandResult, formatStreamingMessage } from "../ui/format.js";
|
|
10
10
|
import { planKeyboard, reviewKeyboard, runCompleteKeyboard, statusKeyboard, } from "../ui/keyboards.js";
|
|
11
|
-
import { reviewStartedMessage, runStartedMessage
|
|
11
|
+
import { reviewStartedMessage, runStartedMessage } from "../ui/messages.js";
|
|
12
12
|
// ─── Command Map ────────────────────────────────────────────────────────────
|
|
13
13
|
/** Maps Telegram command names to locus CLI arguments. */
|
|
14
14
|
const COMMAND_MAP = {
|
|
@@ -114,7 +114,9 @@ async function handleStreamingCommand(ctx, displayCmd, fullArgs, command, args)
|
|
|
114
114
|
// Send keyboard for post-command actions
|
|
115
115
|
const keyboard = getPostCommandKeyboard(command, args, exitCode ?? 0);
|
|
116
116
|
if (keyboard) {
|
|
117
|
-
await ctx.reply(exitCode === 0
|
|
117
|
+
await ctx.reply(exitCode === 0
|
|
118
|
+
? "What would you like to do next?"
|
|
119
|
+
: "Command failed.", { reply_markup: keyboard });
|
|
118
120
|
}
|
|
119
121
|
resolve();
|
|
120
122
|
});
|
package/dist/commands/service.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Service management commands — PM2 lifecycle control via Telegram.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { serviceStatusMessage,
|
|
4
|
+
import { pm2Delete, pm2Logs, pm2Restart, pm2Start, pm2Status, pm2Stop, } from "../pm2.js";
|
|
5
|
+
import { codeBlock, formatError, formatSuccess } from "../ui/format.js";
|
|
6
|
+
import { serviceNotRunningMessage, serviceStatusMessage, } from "../ui/messages.js";
|
|
7
7
|
/** /service <subcommand> — manage the bot process */
|
|
8
8
|
export async function handleService(ctx, args) {
|
|
9
9
|
const subcommand = args[0] ?? "status";
|
|
@@ -53,6 +53,8 @@ export async function handleService(ctx, args) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
56
|
-
await ctx.reply(formatError("Service command failed", String(error)), {
|
|
56
|
+
await ctx.reply(formatError("Service command failed", String(error)), {
|
|
57
|
+
parse_mode: "HTML",
|
|
58
|
+
});
|
|
57
59
|
}
|
|
58
60
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuration for the Telegram bot, read from the Locus config system.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Users configure via:
|
|
5
|
+
* locus config packages.telegram.botToken "123456:ABC..."
|
|
6
|
+
* locus config packages.telegram.chatIds "12345678,87654321"
|
|
7
7
|
*/
|
|
8
8
|
export interface TelegramConfig {
|
|
9
9
|
botToken: string;
|
package/dist/config.js
CHANGED
|
@@ -1,32 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuration for the Telegram bot, read from the Locus config system.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Users configure via:
|
|
5
|
+
* locus config packages.telegram.botToken "123456:ABC..."
|
|
6
|
+
* locus config packages.telegram.chatIds "12345678,87654321"
|
|
7
7
|
*/
|
|
8
|
+
import { readLocusConfig } from "@locusai/sdk";
|
|
8
9
|
export function loadTelegramConfig() {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const locusConfig = readLocusConfig();
|
|
11
|
+
const pkg = locusConfig.packages?.telegram;
|
|
12
|
+
const botToken = pkg?.botToken;
|
|
13
|
+
if (!botToken || typeof botToken !== "string") {
|
|
14
|
+
throw new Error('Telegram bot token not configured. Run:\n locus config packages.telegram.botToken "<your-token>"\n\nGet a token from @BotFather on Telegram.');
|
|
12
15
|
}
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
15
|
-
throw new Error(
|
|
16
|
+
const chatIdsRaw = pkg?.chatIds;
|
|
17
|
+
if (!chatIdsRaw) {
|
|
18
|
+
throw new Error('Telegram chat IDs not configured. Run:\n locus config packages.telegram.chatIds "12345678"\n\nSend /start to your bot, then use the chat ID from the Telegram API.');
|
|
16
19
|
}
|
|
17
|
-
const allowedChatIds =
|
|
18
|
-
.split(",")
|
|
19
|
-
.map((id) => id.trim())
|
|
20
|
-
.filter((id) => id.length > 0)
|
|
21
|
-
.map((id) => {
|
|
22
|
-
const parsed = Number.parseInt(id, 10);
|
|
23
|
-
if (Number.isNaN(parsed)) {
|
|
24
|
-
throw new Error(`Invalid chat ID: "${id}". Must be a number.`);
|
|
25
|
-
}
|
|
26
|
-
return parsed;
|
|
27
|
-
});
|
|
20
|
+
const allowedChatIds = parseChatIds(chatIdsRaw);
|
|
28
21
|
if (allowedChatIds.length === 0) {
|
|
29
|
-
throw new Error("
|
|
22
|
+
throw new Error("packages.telegram.chatIds must contain at least one chat ID.");
|
|
30
23
|
}
|
|
31
24
|
return { botToken, allowedChatIds };
|
|
32
25
|
}
|
|
26
|
+
function parseChatIds(raw) {
|
|
27
|
+
// Support both array of numbers and comma-separated string
|
|
28
|
+
if (Array.isArray(raw)) {
|
|
29
|
+
return raw.map((id) => {
|
|
30
|
+
const parsed = Number(id);
|
|
31
|
+
if (Number.isNaN(parsed)) {
|
|
32
|
+
throw new Error(`Invalid chat ID: "${id}". Must be a number.`);
|
|
33
|
+
}
|
|
34
|
+
return parsed;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (typeof raw === "string") {
|
|
38
|
+
return raw
|
|
39
|
+
.split(",")
|
|
40
|
+
.map((id) => id.trim())
|
|
41
|
+
.filter((id) => id.length > 0)
|
|
42
|
+
.map((id) => {
|
|
43
|
+
const parsed = Number.parseInt(id, 10);
|
|
44
|
+
if (Number.isNaN(parsed)) {
|
|
45
|
+
throw new Error(`Invalid chat ID: "${id}". Must be a number.`);
|
|
46
|
+
}
|
|
47
|
+
return parsed;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (typeof raw === "number") {
|
|
51
|
+
return [raw];
|
|
52
|
+
}
|
|
53
|
+
throw new Error("Invalid chatIds format. Expected a number, array of numbers, or comma-separated string.");
|
|
54
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { createLogger } from "@locusai/sdk";
|
|
17
17
|
import { createBot } from "./bot.js";
|
|
18
18
|
import { loadTelegramConfig } from "./config.js";
|
|
19
|
-
import {
|
|
19
|
+
import { pm2Delete, pm2Logs, pm2Restart, pm2Start, pm2Status, pm2Stop, } from "./pm2.js";
|
|
20
20
|
const logger = createLogger("telegram");
|
|
21
21
|
export async function main(args) {
|
|
22
22
|
const command = args[0] ?? "help";
|
|
@@ -126,19 +126,16 @@ function printHelp() {
|
|
|
126
126
|
bot Run the bot directly (foreground)
|
|
127
127
|
help Show this help message
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
Configuration (via locus config):
|
|
130
|
+
packages.telegram.botToken Telegram Bot API token (from @BotFather)
|
|
131
|
+
packages.telegram.chatIds Comma-separated chat IDs or JSON array
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
export LOCUS_TELEGRAM_CHAT_ID="12345678"
|
|
137
|
-
|
|
138
|
-
# Start in background
|
|
139
|
-
locus pkg telegram start
|
|
133
|
+
Setup:
|
|
134
|
+
locus config packages.telegram.botToken "123456:ABC-DEF..."
|
|
135
|
+
locus config packages.telegram.chatIds "12345678"
|
|
140
136
|
|
|
141
|
-
|
|
142
|
-
locus pkg telegram
|
|
137
|
+
Examples:
|
|
138
|
+
locus pkg telegram start # Start in background
|
|
139
|
+
locus pkg telegram bot # Run in foreground (development)
|
|
143
140
|
`);
|
|
144
141
|
}
|
package/dist/pm2.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Uses pm2 package API to start/stop/restart/status/logs the bot.
|
|
5
5
|
*/
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
7
|
import { dirname, join } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
9
|
const PROCESS_NAME = "locus-telegram";
|
|
10
10
|
function getPm2Bin() {
|
|
11
11
|
// Try local node_modules first, then global
|
|
@@ -45,11 +45,6 @@ function getBotScriptPath() {
|
|
|
45
45
|
export function pm2Start() {
|
|
46
46
|
const script = getBotScriptPath();
|
|
47
47
|
const pm2 = getPm2Bin();
|
|
48
|
-
// Pass env vars through to the PM2 process
|
|
49
|
-
const envArgs = [];
|
|
50
|
-
if (process.env.LOCUS_TELEGRAM_BOT_TOKEN) {
|
|
51
|
-
envArgs.push("--env", `LOCUS_TELEGRAM_BOT_TOKEN=${process.env.LOCUS_TELEGRAM_BOT_TOKEN}`);
|
|
52
|
-
}
|
|
53
48
|
try {
|
|
54
49
|
// Check if already running
|
|
55
50
|
const list = pm2Exec("jlist");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/locus-telegram",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.8",
|
|
4
4
|
"description": "Remote-control Locus via Telegram with full CLI mapping, git operations, and PM2 management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"format": "biome format --write ."
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@locusai/sdk": "0.21.
|
|
24
|
+
"@locusai/sdk": "^0.21.8",
|
|
25
25
|
"grammy": "^1.35.0",
|
|
26
26
|
"pm2": "^6.0.5"
|
|
27
27
|
},
|