blun-king-cli 5.3.6 → 5.3.7

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/blun-cli.js +150 -0
  2. package/package.json +1 -1
package/blun-cli.js CHANGED
@@ -655,6 +655,11 @@ async function handleCommand(input) {
655
655
  await cmdAgent(args);
656
656
  break;
657
657
 
658
+ case "/tg":
659
+ case "/telegram":
660
+ await cmdTelegram(args);
661
+ break;
662
+
658
663
  case "/screenshot":
659
664
  await cmdScreenshot(args);
660
665
  break;
@@ -1100,6 +1105,21 @@ function cmdSet(args) {
1100
1105
  break;
1101
1106
 
1102
1107
  default:
1108
+ // Handle plugin.X.Y settings
1109
+ if (key && key.startsWith("plugin.")) {
1110
+ var pluginParts = key.split(".");
1111
+ if (pluginParts.length === 3) {
1112
+ var pName = pluginParts[1];
1113
+ var pField = pluginParts[2];
1114
+ var plugins = loadPlugins();
1115
+ if (!plugins[pName]) { printError("Plugin '" + pName + "' not installed. /plugin add " + pName); break; }
1116
+ if (!plugins[pName].config) plugins[pName].config = {};
1117
+ plugins[pName].config[pField] = val;
1118
+ savePlugins(plugins);
1119
+ printSuccess("Plugin " + pName + "." + pField + " = " + (pField.includes("token") ? "***" + val.slice(-6) : val));
1120
+ break;
1121
+ }
1122
+ }
1103
1123
  printError("Unknown setting. Use /settings to see all options.");
1104
1124
  }
1105
1125
  }
@@ -1638,6 +1658,8 @@ function cmdPlugin(args) {
1638
1658
  if (!plugins[parts[1]]) { printError("Plugin not found: " + parts[1]); return; }
1639
1659
  plugins[parts[1]].running = true;
1640
1660
  savePlugins(plugins);
1661
+ // Actually start built-in plugins
1662
+ if (parts[1] === "telegram") { ensureTgBot(); }
1641
1663
  printSuccess("Plugin '" + parts[1] + "' started.");
1642
1664
 
1643
1665
  } else if (action === "stop" && parts[1]) {
@@ -1651,6 +1673,134 @@ function cmdPlugin(args) {
1651
1673
  }
1652
1674
  }
1653
1675
 
1676
+ // ── Telegram Plugin ──
1677
+ var _tgBot = null;
1678
+ var _tgMessages = [];
1679
+ var _tgMaxMessages = 50;
1680
+
1681
+ function getTgConfig() {
1682
+ var plugins = loadPlugins();
1683
+ var tg = plugins.telegram;
1684
+ if (!tg || !tg.config) return null;
1685
+ return tg.config;
1686
+ }
1687
+
1688
+ function ensureTgBot() {
1689
+ if (_tgBot) return _tgBot;
1690
+ var cfg = getTgConfig();
1691
+ if (!cfg || !cfg.bot_token) {
1692
+ printError("Telegram not configured. Run: /plugin add telegram");
1693
+ printInfo("Then set token: /set plugin.telegram.bot_token <YOUR_BOT_TOKEN>");
1694
+ printInfo("And chat ID: /set plugin.telegram.chat_id <YOUR_CHAT_ID>");
1695
+ return null;
1696
+ }
1697
+ try {
1698
+ var TelegramBot = require("node-telegram-bot-api");
1699
+ _tgBot = new TelegramBot(cfg.bot_token, { polling: true });
1700
+ _tgBot.on("message", function(msg) {
1701
+ _tgMessages.push({
1702
+ id: msg.message_id,
1703
+ from: msg.from ? (msg.from.first_name || msg.from.username || "?") : "?",
1704
+ text: msg.text || "(media)",
1705
+ date: new Date(msg.date * 1000).toLocaleTimeString(),
1706
+ chat_id: String(msg.chat.id)
1707
+ });
1708
+ if (_tgMessages.length > _tgMaxMessages) _tgMessages.shift();
1709
+ });
1710
+ printSuccess("Telegram Bot connected.");
1711
+ return _tgBot;
1712
+ } catch(e) {
1713
+ printError("Telegram connection failed: " + e.message);
1714
+ return null;
1715
+ }
1716
+ }
1717
+
1718
+ async function cmdTelegram(args) {
1719
+ var parts = (args || "").trim().split(/\s+/);
1720
+ var action = parts[0] || "status";
1721
+
1722
+ if (action === "status") {
1723
+ var cfg = getTgConfig();
1724
+ if (!cfg || !cfg.bot_token) {
1725
+ printError("Telegram not configured.");
1726
+ printInfo(" /plugin add telegram");
1727
+ printInfo(" /set plugin.telegram.bot_token <TOKEN>");
1728
+ printInfo(" /set plugin.telegram.chat_id <CHAT_ID>");
1729
+ } else {
1730
+ console.log("");
1731
+ console.log(C.bold + " Telegram Plugin" + C.reset);
1732
+ console.log(" Token: " + C.green + (cfg.bot_token ? "***" + cfg.bot_token.slice(-6) : "not set") + C.reset);
1733
+ console.log(" Chat: " + C.green + (cfg.chat_id || "not set") + C.reset);
1734
+ console.log(" Bot: " + (_tgBot ? C.green + "connected" : C.red + "disconnected") + C.reset);
1735
+ console.log(" Messages buffered: " + _tgMessages.length);
1736
+ console.log("");
1737
+ }
1738
+
1739
+ } else if (action === "connect" || action === "start") {
1740
+ ensureTgBot();
1741
+
1742
+ } else if (action === "send") {
1743
+ var cfg = getTgConfig();
1744
+ if (!cfg || !cfg.chat_id) { printError("No chat_id set. /set plugin.telegram.chat_id <ID>"); return; }
1745
+ var bot = ensureTgBot();
1746
+ if (!bot) return;
1747
+ var text = parts.slice(1).join(" ");
1748
+ if (!text) { printError("Usage: /tg send <message>"); return; }
1749
+ try {
1750
+ await bot.sendMessage(cfg.chat_id, text);
1751
+ printSuccess("Message sent.");
1752
+ } catch(e) {
1753
+ printError("Send failed: " + e.message);
1754
+ }
1755
+
1756
+ } else if (action === "read" || action === "messages" || action === "inbox") {
1757
+ if (_tgMessages.length === 0) {
1758
+ printInfo("No messages yet. Connect first: /tg connect");
1759
+ return;
1760
+ }
1761
+ console.log("");
1762
+ console.log(C.bold + " Last " + Math.min(_tgMessages.length, 20) + " messages:" + C.reset);
1763
+ _tgMessages.slice(-20).forEach(function(m) {
1764
+ console.log(C.dim + " [" + m.date + "] " + C.reset + C.brightCyan + m.from + C.reset + ": " + m.text);
1765
+ });
1766
+ console.log("");
1767
+
1768
+ } else if (action === "disconnect" || action === "stop") {
1769
+ if (_tgBot) {
1770
+ _tgBot.stopPolling();
1771
+ _tgBot = null;
1772
+ printSuccess("Telegram disconnected.");
1773
+ } else {
1774
+ printInfo("Not connected.");
1775
+ }
1776
+
1777
+ } else if (action === "file" || action === "photo") {
1778
+ var cfg = getTgConfig();
1779
+ if (!cfg || !cfg.chat_id) { printError("No chat_id set."); return; }
1780
+ var bot = ensureTgBot();
1781
+ if (!bot) return;
1782
+ var filePath = parts.slice(1).join(" ");
1783
+ if (!filePath || !fs.existsSync(filePath)) { printError("File not found: " + filePath); return; }
1784
+ try {
1785
+ await bot.sendDocument(cfg.chat_id, filePath);
1786
+ printSuccess("File sent: " + path.basename(filePath));
1787
+ } catch(e) {
1788
+ printError("Send failed: " + e.message);
1789
+ }
1790
+
1791
+ } else {
1792
+ console.log("");
1793
+ console.log(C.bold + " Telegram Commands:" + C.reset);
1794
+ console.log(" /tg status Show connection status");
1795
+ console.log(" /tg connect Connect to Telegram");
1796
+ console.log(" /tg send <msg> Send a message");
1797
+ console.log(" /tg read Show received messages");
1798
+ console.log(" /tg file <path> Send a file/photo");
1799
+ console.log(" /tg disconnect Disconnect");
1800
+ console.log("");
1801
+ }
1802
+ }
1803
+
1654
1804
  function cmdPermissions(args) {
1655
1805
  var perms = loadPermissions();
1656
1806
  if (!args) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "5.3.6",
3
+ "version": "5.3.7",
4
4
  "description": "BLUN King CLI — Your local AI assistant powered by Gemma4",
5
5
  "type": "commonjs",
6
6
  "bin": {