@locusai/locus-telegram 0.22.15 → 0.23.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.
Files changed (2) hide show
  1. package/bin/locus-telegram.js +156 -150
  2. package/package.json +4 -4
@@ -9309,13 +9309,123 @@ var require_mod2 = __commonJS((exports) => {
9309
9309
  __exportStar(require_worker(), exports);
9310
9310
  });
9311
9311
 
9312
+ // ../pm2/dist/index.js
9313
+ import { execSync } from "node:child_process";
9314
+ import { existsSync } from "node:fs";
9315
+ import { dirname, join } from "node:path";
9316
+ import { fileURLToPath } from "node:url";
9317
+ function getPm2Bin() {
9318
+ let dir = process.cwd();
9319
+ while (dir !== dirname(dir)) {
9320
+ const candidate = join(dir, "node_modules", ".bin", "pm2");
9321
+ if (existsSync(candidate))
9322
+ return candidate;
9323
+ dir = dirname(dir);
9324
+ }
9325
+ if (process.argv[1]) {
9326
+ let scriptDir = dirname(process.argv[1]);
9327
+ while (scriptDir !== dirname(scriptDir)) {
9328
+ const candidate = join(scriptDir, "node_modules", ".bin", "pm2");
9329
+ if (existsSync(candidate))
9330
+ return candidate;
9331
+ scriptDir = dirname(scriptDir);
9332
+ }
9333
+ }
9334
+ try {
9335
+ const result = execSync("which pm2", {
9336
+ encoding: "utf-8",
9337
+ stdio: ["pipe", "pipe", "pipe"]
9338
+ }).trim();
9339
+ if (result)
9340
+ return result;
9341
+ } catch {}
9342
+ return "npx pm2";
9343
+ }
9344
+ function pm2Exec(args) {
9345
+ const pm2 = getPm2Bin();
9346
+ try {
9347
+ return execSync(`${pm2} ${args}`, {
9348
+ encoding: "utf-8",
9349
+ stdio: ["pipe", "pipe", "pipe"],
9350
+ env: process.env
9351
+ });
9352
+ } catch (error) {
9353
+ const err = error;
9354
+ throw new Error(err.stderr?.trim() || err.message || "PM2 command failed");
9355
+ }
9356
+ }
9357
+ function pm2Start(config) {
9358
+ const { processName, scriptPath, scriptArgs = [] } = config;
9359
+ const pm2 = getPm2Bin();
9360
+ try {
9361
+ const list = pm2Exec("jlist");
9362
+ const processes = JSON.parse(list);
9363
+ const existing = processes.find((p) => p.name === processName);
9364
+ if (existing) {
9365
+ pm2Exec(`restart ${processName}`);
9366
+ return `Restarted ${processName}`;
9367
+ }
9368
+ } catch {}
9369
+ const argsStr = scriptArgs.length > 0 ? ` -- ${scriptArgs.join(" ")}` : "";
9370
+ execSync(`${pm2} start ${JSON.stringify(scriptPath)} --name ${processName}${argsStr}`, {
9371
+ encoding: "utf-8",
9372
+ stdio: "inherit",
9373
+ env: process.env
9374
+ });
9375
+ return `Started ${processName}`;
9376
+ }
9377
+ function pm2Stop(config) {
9378
+ pm2Exec(`stop ${config.processName}`);
9379
+ return `Stopped ${config.processName}`;
9380
+ }
9381
+ function pm2Restart(config) {
9382
+ pm2Exec(`restart ${config.processName}`);
9383
+ return `Restarted ${config.processName}`;
9384
+ }
9385
+ function pm2Delete(config) {
9386
+ pm2Exec(`delete ${config.processName}`);
9387
+ return `Deleted ${config.processName}`;
9388
+ }
9389
+ function pm2Status(config) {
9390
+ try {
9391
+ const list = pm2Exec("jlist");
9392
+ const processes = JSON.parse(list);
9393
+ const proc = processes.find((p) => p.name === config.processName);
9394
+ if (!proc)
9395
+ return null;
9396
+ return {
9397
+ name: config.processName,
9398
+ status: proc.pm2_env?.status ?? "unknown",
9399
+ pid: proc.pid ?? null,
9400
+ uptime: proc.pm2_env?.pm_uptime ?? null,
9401
+ memory: proc.monit?.memory ?? null,
9402
+ restarts: proc.pm2_env?.restart_time ?? 0
9403
+ };
9404
+ } catch {
9405
+ return null;
9406
+ }
9407
+ }
9408
+ function pm2Logs(config, lines = 50) {
9409
+ try {
9410
+ return pm2Exec(`logs ${config.processName} --nostream --lines ${lines}`);
9411
+ } catch {
9412
+ return "No logs available.";
9413
+ }
9414
+ }
9415
+ function resolvePackageScript(importMetaUrl, binName) {
9416
+ const currentFile = fileURLToPath(importMetaUrl);
9417
+ const packageRoot = dirname(dirname(currentFile));
9418
+ return join(packageRoot, "bin", `${binName}.js`);
9419
+ }
9420
+ var init_dist = () => {};
9421
+
9312
9422
  // ../sdk/dist/index.js
9313
- import { existsSync, readFileSync } from "node:fs";
9423
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
9314
9424
  import { homedir } from "node:os";
9315
- import { join } from "node:path";
9425
+ import { join as join2 } from "node:path";
9316
9426
  import { spawn, spawnSync } from "node:child_process";
9317
9427
  function readJsonFile(filePath) {
9318
- if (!existsSync(filePath))
9428
+ if (!existsSync2(filePath))
9319
9429
  return null;
9320
9430
  try {
9321
9431
  const raw = readFileSync(filePath, "utf-8");
@@ -9341,8 +9451,8 @@ function deepMerge(target, source) {
9341
9451
  }
9342
9452
  function readLocusConfig(cwd) {
9343
9453
  const workingDir = cwd ?? process.cwd();
9344
- const globalPath = join(homedir(), ".locus", "config.json");
9345
- const projectPath = join(workingDir, ".locus", "config.json");
9454
+ const globalPath = join2(homedir(), ".locus", "config.json");
9455
+ const projectPath = join2(workingDir, ".locus", "config.json");
9346
9456
  const globalRaw = readJsonFile(globalPath) ?? {};
9347
9457
  const projectRaw = readJsonFile(projectPath) ?? {};
9348
9458
  const merged = deepMerge(deepMerge(DEFAULT_CONFIG, globalRaw), projectRaw);
@@ -9385,7 +9495,7 @@ function createLogger(name) {
9385
9495
  };
9386
9496
  }
9387
9497
  var DEFAULT_CONFIG, colorEnabled = () => process.stderr.isTTY === true && process.env.NO_COLOR === undefined, wrap = (open, close) => (text) => colorEnabled() ? `${open}${text}${close}` : text, bold, dim, red, yellow, cyan, gray;
9388
- var init_dist = __esm(() => {
9498
+ var init_dist2 = __esm(() => {
9389
9499
  DEFAULT_CONFIG = {
9390
9500
  version: "0.21.7",
9391
9501
  github: {
@@ -9452,6 +9562,13 @@ Send /start to your bot, then use the chat ID from the Telegram API.`);
9452
9562
  }
9453
9563
  return { botToken, allowedChatIds };
9454
9564
  }
9565
+ function getTelegramPm2Config() {
9566
+ return {
9567
+ processName: "locus-telegram",
9568
+ scriptPath: resolvePackageScript(import.meta.url, "locus-telegram"),
9569
+ scriptArgs: ["bot"]
9570
+ };
9571
+ }
9455
9572
  function parseChatIds(raw) {
9456
9573
  if (Array.isArray(raw)) {
9457
9574
  return raw.map((id) => {
@@ -9478,128 +9595,6 @@ function parseChatIds(raw) {
9478
9595
  }
9479
9596
  var init_config = __esm(() => {
9480
9597
  init_dist();
9481
- });
9482
-
9483
- // ../pm2/dist/index.js
9484
- import { execSync } from "node:child_process";
9485
- import { dirname, join as join2 } from "node:path";
9486
- import { fileURLToPath } from "node:url";
9487
- function getPm2Bin() {
9488
- try {
9489
- const result = execSync("which pm2", {
9490
- encoding: "utf-8",
9491
- stdio: ["pipe", "pipe", "pipe"]
9492
- }).trim();
9493
- if (result)
9494
- return result;
9495
- } catch {}
9496
- return "npx pm2";
9497
- }
9498
- function pm2Exec(args) {
9499
- const pm2 = getPm2Bin();
9500
- try {
9501
- return execSync(`${pm2} ${args}`, {
9502
- encoding: "utf-8",
9503
- stdio: ["pipe", "pipe", "pipe"],
9504
- env: process.env
9505
- });
9506
- } catch (error) {
9507
- const err = error;
9508
- throw new Error(err.stderr?.trim() || err.message || "PM2 command failed");
9509
- }
9510
- }
9511
- function pm2Start(config) {
9512
- const { processName, scriptPath, scriptArgs = [] } = config;
9513
- const pm2 = getPm2Bin();
9514
- try {
9515
- const list = pm2Exec("jlist");
9516
- const processes = JSON.parse(list);
9517
- const existing = processes.find((p) => p.name === processName);
9518
- if (existing) {
9519
- pm2Exec(`restart ${processName}`);
9520
- return `Restarted ${processName}`;
9521
- }
9522
- } catch {}
9523
- const argsStr = scriptArgs.length > 0 ? ` -- ${scriptArgs.join(" ")}` : "";
9524
- execSync(`${pm2} start ${JSON.stringify(scriptPath)} --name ${processName}${argsStr}`, {
9525
- encoding: "utf-8",
9526
- stdio: "inherit",
9527
- env: process.env
9528
- });
9529
- return `Started ${processName}`;
9530
- }
9531
- function pm2Stop(config) {
9532
- pm2Exec(`stop ${config.processName}`);
9533
- return `Stopped ${config.processName}`;
9534
- }
9535
- function pm2Restart(config) {
9536
- pm2Exec(`restart ${config.processName}`);
9537
- return `Restarted ${config.processName}`;
9538
- }
9539
- function pm2Delete(config) {
9540
- pm2Exec(`delete ${config.processName}`);
9541
- return `Deleted ${config.processName}`;
9542
- }
9543
- function pm2Status(config) {
9544
- try {
9545
- const list = pm2Exec("jlist");
9546
- const processes = JSON.parse(list);
9547
- const proc = processes.find((p) => p.name === config.processName);
9548
- if (!proc)
9549
- return null;
9550
- return {
9551
- name: config.processName,
9552
- status: proc.pm2_env?.status ?? "unknown",
9553
- pid: proc.pid ?? null,
9554
- uptime: proc.pm2_env?.pm_uptime ?? null,
9555
- memory: proc.monit?.memory ?? null,
9556
- restarts: proc.pm2_env?.restart_time ?? 0
9557
- };
9558
- } catch {
9559
- return null;
9560
- }
9561
- }
9562
- function pm2Logs(config, lines = 50) {
9563
- try {
9564
- return pm2Exec(`logs ${config.processName} --nostream --lines ${lines}`);
9565
- } catch {
9566
- return "No logs available.";
9567
- }
9568
- }
9569
- function resolvePackageScript(importMetaUrl, binName) {
9570
- const currentFile = fileURLToPath(importMetaUrl);
9571
- const packageRoot = dirname(dirname(currentFile));
9572
- return join2(packageRoot, "bin", `${binName}.js`);
9573
- }
9574
- var init_dist2 = () => {};
9575
-
9576
- // src/pm2.ts
9577
- function getConfig() {
9578
- return {
9579
- processName: "locus-telegram",
9580
- scriptPath: resolvePackageScript(import.meta.url, "locus-telegram"),
9581
- scriptArgs: ["bot"]
9582
- };
9583
- }
9584
- function pm2Start2() {
9585
- return pm2Start(getConfig());
9586
- }
9587
- function pm2Stop2() {
9588
- return pm2Stop(getConfig());
9589
- }
9590
- function pm2Restart2() {
9591
- return pm2Restart(getConfig());
9592
- }
9593
- function pm2Delete2() {
9594
- return pm2Delete(getConfig());
9595
- }
9596
- function pm2Status2() {
9597
- return pm2Status(getConfig());
9598
- }
9599
- function pm2Logs2(lines = 50) {
9600
- return pm2Logs(getConfig(), lines);
9601
- }
9602
- var init_pm2 = __esm(() => {
9603
9598
  init_dist2();
9604
9599
  });
9605
9600
 
@@ -10813,7 +10808,7 @@ function getPostCommandKeyboard(command, args, exitCode) {
10813
10808
  var EDIT_INTERVAL = 2000;
10814
10809
  var init_locus = __esm(() => {
10815
10810
  init_dist3();
10816
- init_dist();
10811
+ init_dist2();
10817
10812
  init_tracker();
10818
10813
  init_keyboards();
10819
10814
  init_messages();
@@ -10825,27 +10820,27 @@ async function handleService(ctx, args) {
10825
10820
  try {
10826
10821
  switch (subcommand) {
10827
10822
  case "start": {
10828
- const result = pm2Start2();
10823
+ const result = pm2Start(getTelegramPm2Config());
10829
10824
  await ctx.reply(formatSuccess(result), { parse_mode: "HTML" });
10830
10825
  break;
10831
10826
  }
10832
10827
  case "stop": {
10833
- const result = pm2Stop2();
10828
+ const result = pm2Stop(getTelegramPm2Config());
10834
10829
  await ctx.reply(formatSuccess(result), { parse_mode: "HTML" });
10835
10830
  break;
10836
10831
  }
10837
10832
  case "restart": {
10838
- const result = pm2Restart2();
10833
+ const result = pm2Restart(getTelegramPm2Config());
10839
10834
  await ctx.reply(formatSuccess(result), { parse_mode: "HTML" });
10840
10835
  break;
10841
10836
  }
10842
10837
  case "delete": {
10843
- const result = pm2Delete2();
10838
+ const result = pm2Delete(getTelegramPm2Config());
10844
10839
  await ctx.reply(formatSuccess(result), { parse_mode: "HTML" });
10845
10840
  break;
10846
10841
  }
10847
10842
  case "status": {
10848
- const status = pm2Status2();
10843
+ const status = pm2Status(getTelegramPm2Config());
10849
10844
  if (!status) {
10850
10845
  await ctx.reply(serviceNotRunningMessage(), {
10851
10846
  parse_mode: "HTML"
@@ -10857,7 +10852,7 @@ async function handleService(ctx, args) {
10857
10852
  }
10858
10853
  case "logs": {
10859
10854
  const lines = args[1] ? Number(args[1]) : 50;
10860
- const logs = pm2Logs2(lines);
10855
+ const logs = pm2Logs(getTelegramPm2Config(), lines);
10861
10856
  await ctx.reply(codeBlock(logs), { parse_mode: "HTML" });
10862
10857
  break;
10863
10858
  }
@@ -10872,7 +10867,8 @@ async function handleService(ctx, args) {
10872
10867
  }
10873
10868
  }
10874
10869
  var init_service = __esm(() => {
10875
- init_pm2();
10870
+ init_dist();
10871
+ init_config();
10876
10872
  init_messages();
10877
10873
  });
10878
10874
 
@@ -10881,6 +10877,8 @@ var exports_bot = {};
10881
10877
  __export(exports_bot, {
10882
10878
  createBot: () => createBot
10883
10879
  });
10880
+ import { exec as execCb3 } from "node:child_process";
10881
+ import { promisify as promisify3 } from "node:util";
10884
10882
  function createBot(config) {
10885
10883
  const bot = new import_grammy3.Bot(config.botToken);
10886
10884
  bot.use(async (ctx, next) => {
@@ -10985,7 +10983,7 @@ function registerCallbackHandlers(bot) {
10985
10983
  });
10986
10984
  bot.callbackQuery(CB.SHOW_PLAN_DETAILS, async (ctx) => {
10987
10985
  await ctx.answerCallbackQuery();
10988
- await handleLocusCommand(ctx, "plan", ["--show"]);
10986
+ await handleLocusCommand(ctx, "plan", ["list"]);
10989
10987
  });
10990
10988
  bot.callbackQuery(CB.VIEW_LOGS, async (ctx) => {
10991
10989
  await ctx.answerCallbackQuery();
@@ -11001,9 +10999,16 @@ function registerCallbackHandlers(bot) {
11001
10999
  const pr = ctx.match[1];
11002
11000
  await ctx.answerCallbackQuery({ text: "Approving PR..." });
11003
11001
  await ctx.editMessageReplyMarkup({ reply_markup: undefined });
11004
- await ctx.reply(formatSuccess(`Approved PR #${pr}`), {
11005
- parse_mode: "HTML"
11006
- });
11002
+ try {
11003
+ await exec3(`gh pr review ${pr} --approve`, { cwd: process.cwd() });
11004
+ await ctx.reply(formatSuccess(`Approved PR #${pr}`), {
11005
+ parse_mode: "HTML"
11006
+ });
11007
+ } catch (error) {
11008
+ await ctx.reply(formatError(`Failed to approve PR #${pr}`, String(error)), {
11009
+ parse_mode: "HTML"
11010
+ });
11011
+ }
11007
11012
  });
11008
11013
  bot.callbackQuery(/^review:changes:(\d+)$/, async (ctx) => {
11009
11014
  const pr = ctx.match[1];
@@ -11014,7 +11019,7 @@ function registerCallbackHandlers(bot) {
11014
11019
  bot.callbackQuery(/^review:diff:(\d+)$/, async (ctx) => {
11015
11020
  const pr = ctx.match[1];
11016
11021
  await ctx.answerCallbackQuery();
11017
- await handleLocusCommand(ctx, "review", [pr, "--diff"]);
11022
+ await handleLocusCommand(ctx, "review", [pr]);
11018
11023
  });
11019
11024
  bot.callbackQuery(CB.RUN_SPRINT, async (ctx) => {
11020
11025
  await ctx.answerCallbackQuery({ text: "Starting sprint run..." });
@@ -11060,9 +11065,9 @@ function parseArgs(text, command) {
11060
11065
  return [];
11061
11066
  return rest.split(/\s+/);
11062
11067
  }
11063
- var import_grammy3, logger2;
11068
+ var import_grammy3, exec3, logger2;
11064
11069
  var init_bot = __esm(() => {
11065
- init_dist();
11070
+ init_dist2();
11066
11071
  init_cancel();
11067
11072
  init_git();
11068
11073
  init_locus();
@@ -11070,6 +11075,7 @@ var init_bot = __esm(() => {
11070
11075
  init_keyboards();
11071
11076
  init_messages();
11072
11077
  import_grammy3 = __toESM(require_mod(), 1);
11078
+ exec3 = promisify3(execCb3);
11073
11079
  logger2 = createLogger("telegram");
11074
11080
  });
11075
11081
 
@@ -11106,23 +11112,23 @@ async function main(args) {
11106
11112
  }
11107
11113
  }
11108
11114
  function handleStart() {
11109
- const result = pm2Start2();
11115
+ const result = pm2Start(getTelegramPm2Config());
11110
11116
  logger3.info(result);
11111
11117
  }
11112
11118
  function handleStop() {
11113
- const result = pm2Stop2();
11119
+ const result = pm2Stop(getTelegramPm2Config());
11114
11120
  logger3.info(result);
11115
11121
  }
11116
11122
  function handleRestart() {
11117
- const result = pm2Restart2();
11123
+ const result = pm2Restart(getTelegramPm2Config());
11118
11124
  logger3.info(result);
11119
11125
  }
11120
11126
  function handleDelete() {
11121
- const result = pm2Delete2();
11127
+ const result = pm2Delete(getTelegramPm2Config());
11122
11128
  logger3.info(result);
11123
11129
  }
11124
11130
  function handleStatus() {
11125
- const status = pm2Status2();
11131
+ const status = pm2Status(getTelegramPm2Config());
11126
11132
  if (!status) {
11127
11133
  logger3.warn("Bot is not running");
11128
11134
  return;
@@ -11140,7 +11146,7 @@ function handleStatus() {
11140
11146
  }
11141
11147
  function handleLogs(args) {
11142
11148
  const lines = args[0] ? Number(args[0]) : 50;
11143
- const logs = pm2Logs2(lines);
11149
+ const logs = pm2Logs(getTelegramPm2Config(), lines);
11144
11150
  console.log(logs);
11145
11151
  }
11146
11152
  async function handleBot() {
@@ -11224,8 +11230,8 @@ function printHelp() {
11224
11230
  var import_runner, logger3;
11225
11231
  var init_src = __esm(() => {
11226
11232
  init_dist();
11233
+ init_dist2();
11227
11234
  init_config();
11228
- init_pm2();
11229
11235
  import_runner = __toESM(require_mod2(), 1);
11230
11236
  logger3 = createLogger("telegram");
11231
11237
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locusai/locus-telegram",
3
- "version": "0.22.15",
3
+ "version": "0.23.1",
4
4
  "description": "Remote-control Locus via Telegram with full CLI mapping, git operations, and PM2 management",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,9 +27,9 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@grammyjs/runner": "^2.0.3",
30
- "@locusai/locus-gateway": "^0.22.15",
31
- "@locusai/locus-pm2": "^0.22.15",
32
- "@locusai/sdk": "^0.22.15",
30
+ "@locusai/locus-gateway": "^0.23.1",
31
+ "@locusai/locus-pm2": "^0.23.1",
32
+ "@locusai/sdk": "^0.23.1",
33
33
  "grammy": "^1.35.0"
34
34
  },
35
35
  "devDependencies": {