@locusai/telegram 0.10.1 → 0.10.2
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/bin/telegram.js +197 -197
- package/package.json +2 -2
package/bin/telegram.js
CHANGED
|
@@ -40713,203 +40713,6 @@ var import_telegraf = __toESM(require_lib3(), 1);
|
|
|
40713
40713
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
40714
40714
|
import { join } from "node:path";
|
|
40715
40715
|
|
|
40716
|
-
// src/formatter.ts
|
|
40717
|
-
var MAX_MESSAGE_LENGTH = 4000;
|
|
40718
|
-
function stripAnsi(text) {
|
|
40719
|
-
return text.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\].*?\x07/g, "");
|
|
40720
|
-
}
|
|
40721
|
-
function truncateOutput(text, maxLength = MAX_MESSAGE_LENGTH) {
|
|
40722
|
-
if (text.length <= maxLength)
|
|
40723
|
-
return text;
|
|
40724
|
-
const halfLen = Math.floor((maxLength - 50) / 2);
|
|
40725
|
-
const start = text.slice(0, halfLen);
|
|
40726
|
-
const end = text.slice(-halfLen);
|
|
40727
|
-
return `${start}
|
|
40728
|
-
|
|
40729
|
-
... (truncated ${text.length - maxLength} chars) ...
|
|
40730
|
-
|
|
40731
|
-
${end}`;
|
|
40732
|
-
}
|
|
40733
|
-
function formatCommandOutput(command, output, exitCode) {
|
|
40734
|
-
const status = exitCode === 0 ? "completed" : `failed (exit code: ${exitCode})`;
|
|
40735
|
-
const cleanOutput = stripAnsi(output);
|
|
40736
|
-
const truncated = truncateOutput(cleanOutput, MAX_MESSAGE_LENGTH - 200);
|
|
40737
|
-
let msg = `<b>Command:</b> <code>${escapeHtml(command)}</code>
|
|
40738
|
-
`;
|
|
40739
|
-
msg += `<b>Status:</b> ${exitCode === 0 ? "✅" : "❌"} ${escapeHtml(status)}
|
|
40740
|
-
|
|
40741
|
-
`;
|
|
40742
|
-
if (truncated.trim()) {
|
|
40743
|
-
msg += `<pre>${escapeHtml(truncated)}</pre>`;
|
|
40744
|
-
} else {
|
|
40745
|
-
msg += "<i>No output</i>";
|
|
40746
|
-
}
|
|
40747
|
-
return msg;
|
|
40748
|
-
}
|
|
40749
|
-
function formatError(message) {
|
|
40750
|
-
return `❌ <b>Error:</b> ${escapeHtml(message)}`;
|
|
40751
|
-
}
|
|
40752
|
-
function formatSuccess(message) {
|
|
40753
|
-
return `✅ ${escapeHtml(message)}`;
|
|
40754
|
-
}
|
|
40755
|
-
function formatInfo(message) {
|
|
40756
|
-
return `ℹ️ ${escapeHtml(message)}`;
|
|
40757
|
-
}
|
|
40758
|
-
function escapeHtml(text) {
|
|
40759
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
40760
|
-
}
|
|
40761
|
-
|
|
40762
|
-
// src/commands/config.ts
|
|
40763
|
-
var CONFIG_DIR = ".locus";
|
|
40764
|
-
var SETTINGS_FILE = "settings.json";
|
|
40765
|
-
var ALLOWED_KEYS = {
|
|
40766
|
-
provider: {
|
|
40767
|
-
description: "AI provider (claude, codex)",
|
|
40768
|
-
validate: (v) => ["claude", "codex"].includes(v) ? null : "Invalid provider. Must be: claude, codex"
|
|
40769
|
-
},
|
|
40770
|
-
model: {
|
|
40771
|
-
description: "AI model override (e.g. opus, sonnet, haiku)"
|
|
40772
|
-
},
|
|
40773
|
-
apiUrl: {
|
|
40774
|
-
description: "Locus API base URL"
|
|
40775
|
-
},
|
|
40776
|
-
agentCount: {
|
|
40777
|
-
description: "Default number of agents for /run (1-5)",
|
|
40778
|
-
validate: (v) => {
|
|
40779
|
-
const n = Number.parseInt(v, 10);
|
|
40780
|
-
if (Number.isNaN(n) || n < 1 || n > 5)
|
|
40781
|
-
return "Must be a number between 1 and 5";
|
|
40782
|
-
return null;
|
|
40783
|
-
}
|
|
40784
|
-
}
|
|
40785
|
-
};
|
|
40786
|
-
var USAGE = `<b>Usage:</b>
|
|
40787
|
-
/config — Show current settings
|
|
40788
|
-
/config set <key> <value> — Update a setting
|
|
40789
|
-
/config unset <key> — Remove a setting
|
|
40790
|
-
|
|
40791
|
-
<b>Available keys:</b>
|
|
40792
|
-
${Object.entries(ALLOWED_KEYS).map(([k, v]) => ` <code>${k}</code> — ${v.description}`).join(`
|
|
40793
|
-
`)}`;
|
|
40794
|
-
function getSettingsPath(config) {
|
|
40795
|
-
return join(config.projectPath, CONFIG_DIR, SETTINGS_FILE);
|
|
40796
|
-
}
|
|
40797
|
-
function loadSettings(config) {
|
|
40798
|
-
const path = getSettingsPath(config);
|
|
40799
|
-
if (!existsSync(path))
|
|
40800
|
-
return null;
|
|
40801
|
-
const raw = readFileSync(path, "utf-8");
|
|
40802
|
-
return JSON.parse(raw);
|
|
40803
|
-
}
|
|
40804
|
-
function saveSettings(config, settings) {
|
|
40805
|
-
const path = getSettingsPath(config);
|
|
40806
|
-
writeFileSync(path, `${JSON.stringify(settings, null, 2)}
|
|
40807
|
-
`, "utf-8");
|
|
40808
|
-
}
|
|
40809
|
-
function formatSettingsDisplay(settings) {
|
|
40810
|
-
let msg = `<b>Current Settings</b>
|
|
40811
|
-
|
|
40812
|
-
`;
|
|
40813
|
-
for (const key of Object.keys(ALLOWED_KEYS)) {
|
|
40814
|
-
const value = settings[key];
|
|
40815
|
-
const display = value !== undefined && value !== null ? String(value) : "<i>not set</i>";
|
|
40816
|
-
msg += `<code>${escapeHtml(key)}</code>: ${value !== undefined && value !== null ? `<code>${escapeHtml(String(value))}</code>` : display}
|
|
40817
|
-
`;
|
|
40818
|
-
}
|
|
40819
|
-
return msg;
|
|
40820
|
-
}
|
|
40821
|
-
async function configCommand(ctx, config) {
|
|
40822
|
-
const text = (ctx.message && "text" in ctx.message ? ctx.message.text : "") || "";
|
|
40823
|
-
const input = text.replace(/^\/config\s*/, "").trim();
|
|
40824
|
-
console.log(`[config] Received: ${input || "(empty)"}`);
|
|
40825
|
-
if (!input) {
|
|
40826
|
-
try {
|
|
40827
|
-
const settings = loadSettings(config);
|
|
40828
|
-
if (!settings) {
|
|
40829
|
-
await ctx.reply(formatError("No settings file found. Run locus init first."), {
|
|
40830
|
-
parse_mode: "HTML"
|
|
40831
|
-
});
|
|
40832
|
-
return;
|
|
40833
|
-
}
|
|
40834
|
-
await ctx.reply(formatSettingsDisplay(settings), { parse_mode: "HTML" });
|
|
40835
|
-
} catch (err) {
|
|
40836
|
-
await ctx.reply(formatError(`Failed to read settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
40837
|
-
}
|
|
40838
|
-
return;
|
|
40839
|
-
}
|
|
40840
|
-
const parts = input.split(/\s+/);
|
|
40841
|
-
const subcommand = parts[0];
|
|
40842
|
-
if (subcommand === "set") {
|
|
40843
|
-
const key = parts[1];
|
|
40844
|
-
const value = parts.slice(2).join(" ");
|
|
40845
|
-
if (!key || !value) {
|
|
40846
|
-
await ctx.reply(formatError("Usage: /config set <key> <value>"), {
|
|
40847
|
-
parse_mode: "HTML"
|
|
40848
|
-
});
|
|
40849
|
-
return;
|
|
40850
|
-
}
|
|
40851
|
-
if (!ALLOWED_KEYS[key]) {
|
|
40852
|
-
await ctx.reply(formatError(`Unknown key: ${escapeHtml(key)}
|
|
40853
|
-
|
|
40854
|
-
Allowed keys: ${Object.keys(ALLOWED_KEYS).join(", ")}`), { parse_mode: "HTML" });
|
|
40855
|
-
return;
|
|
40856
|
-
}
|
|
40857
|
-
const validator = ALLOWED_KEYS[key].validate;
|
|
40858
|
-
if (validator) {
|
|
40859
|
-
const error = validator(value);
|
|
40860
|
-
if (error) {
|
|
40861
|
-
await ctx.reply(formatError(error), { parse_mode: "HTML" });
|
|
40862
|
-
return;
|
|
40863
|
-
}
|
|
40864
|
-
}
|
|
40865
|
-
try {
|
|
40866
|
-
const settings = loadSettings(config) || {};
|
|
40867
|
-
if (key === "agentCount") {
|
|
40868
|
-
settings[key] = Number.parseInt(value, 10);
|
|
40869
|
-
} else {
|
|
40870
|
-
settings[key] = value;
|
|
40871
|
-
}
|
|
40872
|
-
saveSettings(config, settings);
|
|
40873
|
-
await ctx.reply(formatSuccess(`Set <code>${escapeHtml(key)}</code> = <code>${escapeHtml(value)}</code>`), { parse_mode: "HTML" });
|
|
40874
|
-
} catch (err) {
|
|
40875
|
-
await ctx.reply(formatError(`Failed to update settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
40876
|
-
}
|
|
40877
|
-
return;
|
|
40878
|
-
}
|
|
40879
|
-
if (subcommand === "unset") {
|
|
40880
|
-
const key = parts[1];
|
|
40881
|
-
if (!key) {
|
|
40882
|
-
await ctx.reply(formatError("Usage: /config unset <key>"), {
|
|
40883
|
-
parse_mode: "HTML"
|
|
40884
|
-
});
|
|
40885
|
-
return;
|
|
40886
|
-
}
|
|
40887
|
-
if (!ALLOWED_KEYS[key]) {
|
|
40888
|
-
await ctx.reply(formatError(`Unknown key: ${escapeHtml(key)}
|
|
40889
|
-
|
|
40890
|
-
Allowed keys: ${Object.keys(ALLOWED_KEYS).join(", ")}`), { parse_mode: "HTML" });
|
|
40891
|
-
return;
|
|
40892
|
-
}
|
|
40893
|
-
try {
|
|
40894
|
-
const settings = loadSettings(config);
|
|
40895
|
-
if (!settings) {
|
|
40896
|
-
await ctx.reply(formatError("No settings file found."), {
|
|
40897
|
-
parse_mode: "HTML"
|
|
40898
|
-
});
|
|
40899
|
-
return;
|
|
40900
|
-
}
|
|
40901
|
-
delete settings[key];
|
|
40902
|
-
saveSettings(config, settings);
|
|
40903
|
-
await ctx.reply(formatSuccess(`Removed <code>${escapeHtml(key)}</code> from settings.`), {
|
|
40904
|
-
parse_mode: "HTML"
|
|
40905
|
-
});
|
|
40906
|
-
} catch (err) {
|
|
40907
|
-
await ctx.reply(formatError(`Failed to update settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
40908
|
-
}
|
|
40909
|
-
return;
|
|
40910
|
-
}
|
|
40911
|
-
await ctx.reply(USAGE, { parse_mode: "HTML" });
|
|
40912
|
-
}
|
|
40913
40716
|
// src/command-whitelist.ts
|
|
40914
40717
|
var SAFE_BRANCH = /^[a-zA-Z0-9_\-./]+$/;
|
|
40915
40718
|
var SAFE_PATH = /^[a-zA-Z0-9_\-./\s]+$/;
|
|
@@ -41251,6 +41054,203 @@ function parseArgs(input) {
|
|
|
41251
41054
|
return args;
|
|
41252
41055
|
}
|
|
41253
41056
|
|
|
41057
|
+
// src/formatter.ts
|
|
41058
|
+
var MAX_MESSAGE_LENGTH = 4000;
|
|
41059
|
+
function stripAnsi(text) {
|
|
41060
|
+
return text.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\].*?\x07/g, "");
|
|
41061
|
+
}
|
|
41062
|
+
function truncateOutput(text, maxLength = MAX_MESSAGE_LENGTH) {
|
|
41063
|
+
if (text.length <= maxLength)
|
|
41064
|
+
return text;
|
|
41065
|
+
const halfLen = Math.floor((maxLength - 50) / 2);
|
|
41066
|
+
const start = text.slice(0, halfLen);
|
|
41067
|
+
const end = text.slice(-halfLen);
|
|
41068
|
+
return `${start}
|
|
41069
|
+
|
|
41070
|
+
... (truncated ${text.length - maxLength} chars) ...
|
|
41071
|
+
|
|
41072
|
+
${end}`;
|
|
41073
|
+
}
|
|
41074
|
+
function formatCommandOutput(command, output, exitCode) {
|
|
41075
|
+
const status = exitCode === 0 ? "completed" : `failed (exit code: ${exitCode})`;
|
|
41076
|
+
const cleanOutput = stripAnsi(output);
|
|
41077
|
+
const truncated = truncateOutput(cleanOutput, MAX_MESSAGE_LENGTH - 200);
|
|
41078
|
+
let msg = `<b>Command:</b> <code>${escapeHtml(command)}</code>
|
|
41079
|
+
`;
|
|
41080
|
+
msg += `<b>Status:</b> ${exitCode === 0 ? "✅" : "❌"} ${escapeHtml(status)}
|
|
41081
|
+
|
|
41082
|
+
`;
|
|
41083
|
+
if (truncated.trim()) {
|
|
41084
|
+
msg += `<pre>${escapeHtml(truncated)}</pre>`;
|
|
41085
|
+
} else {
|
|
41086
|
+
msg += "<i>No output</i>";
|
|
41087
|
+
}
|
|
41088
|
+
return msg;
|
|
41089
|
+
}
|
|
41090
|
+
function formatError(message) {
|
|
41091
|
+
return `❌ <b>Error:</b> ${escapeHtml(message)}`;
|
|
41092
|
+
}
|
|
41093
|
+
function formatSuccess(message) {
|
|
41094
|
+
return `✅ ${escapeHtml(message)}`;
|
|
41095
|
+
}
|
|
41096
|
+
function formatInfo(message) {
|
|
41097
|
+
return `ℹ️ ${escapeHtml(message)}`;
|
|
41098
|
+
}
|
|
41099
|
+
function escapeHtml(text) {
|
|
41100
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
41101
|
+
}
|
|
41102
|
+
|
|
41103
|
+
// src/commands/config.ts
|
|
41104
|
+
var CONFIG_DIR = ".locus";
|
|
41105
|
+
var SETTINGS_FILE = "settings.json";
|
|
41106
|
+
var ALLOWED_KEYS = {
|
|
41107
|
+
provider: {
|
|
41108
|
+
description: "AI provider (claude, codex)",
|
|
41109
|
+
validate: (v) => ["claude", "codex"].includes(v) ? null : "Invalid provider. Must be: claude, codex"
|
|
41110
|
+
},
|
|
41111
|
+
model: {
|
|
41112
|
+
description: "AI model override (e.g. opus, sonnet, haiku)"
|
|
41113
|
+
},
|
|
41114
|
+
apiUrl: {
|
|
41115
|
+
description: "Locus API base URL"
|
|
41116
|
+
},
|
|
41117
|
+
agentCount: {
|
|
41118
|
+
description: "Default number of agents for /run (1-5)",
|
|
41119
|
+
validate: (v) => {
|
|
41120
|
+
const n = Number.parseInt(v, 10);
|
|
41121
|
+
if (Number.isNaN(n) || n < 1 || n > 5)
|
|
41122
|
+
return "Must be a number between 1 and 5";
|
|
41123
|
+
return null;
|
|
41124
|
+
}
|
|
41125
|
+
}
|
|
41126
|
+
};
|
|
41127
|
+
var USAGE = `<b>Usage:</b>
|
|
41128
|
+
/config — Show current settings
|
|
41129
|
+
/config set <key> <value> — Update a setting
|
|
41130
|
+
/config unset <key> — Remove a setting
|
|
41131
|
+
|
|
41132
|
+
<b>Available keys:</b>
|
|
41133
|
+
${Object.entries(ALLOWED_KEYS).map(([k, v]) => ` <code>${k}</code> — ${v.description}`).join(`
|
|
41134
|
+
`)}`;
|
|
41135
|
+
function getSettingsPath(config) {
|
|
41136
|
+
return join(config.projectPath, CONFIG_DIR, SETTINGS_FILE);
|
|
41137
|
+
}
|
|
41138
|
+
function loadSettings(config) {
|
|
41139
|
+
const path = getSettingsPath(config);
|
|
41140
|
+
if (!existsSync(path))
|
|
41141
|
+
return null;
|
|
41142
|
+
const raw = readFileSync(path, "utf-8");
|
|
41143
|
+
return JSON.parse(raw);
|
|
41144
|
+
}
|
|
41145
|
+
function saveSettings(config, settings) {
|
|
41146
|
+
const path = getSettingsPath(config);
|
|
41147
|
+
writeFileSync(path, `${JSON.stringify(settings, null, 2)}
|
|
41148
|
+
`, "utf-8");
|
|
41149
|
+
}
|
|
41150
|
+
function formatSettingsDisplay(settings) {
|
|
41151
|
+
let msg = `<b>Current Settings</b>
|
|
41152
|
+
|
|
41153
|
+
`;
|
|
41154
|
+
for (const key of Object.keys(ALLOWED_KEYS)) {
|
|
41155
|
+
const value = settings[key];
|
|
41156
|
+
const display = value !== undefined && value !== null ? String(value) : "<i>not set</i>";
|
|
41157
|
+
msg += `<code>${escapeHtml(key)}</code>: ${value !== undefined && value !== null ? `<code>${escapeHtml(String(value))}</code>` : display}
|
|
41158
|
+
`;
|
|
41159
|
+
}
|
|
41160
|
+
return msg;
|
|
41161
|
+
}
|
|
41162
|
+
async function configCommand(ctx, config) {
|
|
41163
|
+
const text = (ctx.message && "text" in ctx.message ? ctx.message.text : "") || "";
|
|
41164
|
+
const input = text.replace(/^\/config\s*/, "").trim();
|
|
41165
|
+
console.log(`[config] Received: ${input || "(empty)"}`);
|
|
41166
|
+
if (!input) {
|
|
41167
|
+
try {
|
|
41168
|
+
const settings = loadSettings(config);
|
|
41169
|
+
if (!settings) {
|
|
41170
|
+
await ctx.reply(formatError("No settings file found. Run locus init first."), {
|
|
41171
|
+
parse_mode: "HTML"
|
|
41172
|
+
});
|
|
41173
|
+
return;
|
|
41174
|
+
}
|
|
41175
|
+
await ctx.reply(formatSettingsDisplay(settings), { parse_mode: "HTML" });
|
|
41176
|
+
} catch (err) {
|
|
41177
|
+
await ctx.reply(formatError(`Failed to read settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
41178
|
+
}
|
|
41179
|
+
return;
|
|
41180
|
+
}
|
|
41181
|
+
const parts = parseArgs(input);
|
|
41182
|
+
const subcommand = parts[0];
|
|
41183
|
+
if (subcommand === "set") {
|
|
41184
|
+
const key = parts[1];
|
|
41185
|
+
const value = parts.slice(2).join(" ");
|
|
41186
|
+
if (!key || !value) {
|
|
41187
|
+
await ctx.reply(formatError("Usage: /config set <key> <value>"), {
|
|
41188
|
+
parse_mode: "HTML"
|
|
41189
|
+
});
|
|
41190
|
+
return;
|
|
41191
|
+
}
|
|
41192
|
+
if (!ALLOWED_KEYS[key]) {
|
|
41193
|
+
await ctx.reply(formatError(`Unknown key: ${escapeHtml(key)}
|
|
41194
|
+
|
|
41195
|
+
Allowed keys: ${Object.keys(ALLOWED_KEYS).join(", ")}`), { parse_mode: "HTML" });
|
|
41196
|
+
return;
|
|
41197
|
+
}
|
|
41198
|
+
const validator = ALLOWED_KEYS[key].validate;
|
|
41199
|
+
if (validator) {
|
|
41200
|
+
const error = validator(value);
|
|
41201
|
+
if (error) {
|
|
41202
|
+
await ctx.reply(formatError(error), { parse_mode: "HTML" });
|
|
41203
|
+
return;
|
|
41204
|
+
}
|
|
41205
|
+
}
|
|
41206
|
+
try {
|
|
41207
|
+
const settings = loadSettings(config) || {};
|
|
41208
|
+
if (key === "agentCount") {
|
|
41209
|
+
settings[key] = Number.parseInt(value, 10);
|
|
41210
|
+
} else {
|
|
41211
|
+
settings[key] = value;
|
|
41212
|
+
}
|
|
41213
|
+
saveSettings(config, settings);
|
|
41214
|
+
await ctx.reply(formatSuccess(`Set <code>${escapeHtml(key)}</code> = <code>${escapeHtml(value)}</code>`), { parse_mode: "HTML" });
|
|
41215
|
+
} catch (err) {
|
|
41216
|
+
await ctx.reply(formatError(`Failed to update settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
41217
|
+
}
|
|
41218
|
+
return;
|
|
41219
|
+
}
|
|
41220
|
+
if (subcommand === "unset") {
|
|
41221
|
+
const key = parts[1];
|
|
41222
|
+
if (!key) {
|
|
41223
|
+
await ctx.reply(formatError("Usage: /config unset <key>"), {
|
|
41224
|
+
parse_mode: "HTML"
|
|
41225
|
+
});
|
|
41226
|
+
return;
|
|
41227
|
+
}
|
|
41228
|
+
if (!ALLOWED_KEYS[key]) {
|
|
41229
|
+
await ctx.reply(formatError(`Unknown key: ${escapeHtml(key)}
|
|
41230
|
+
|
|
41231
|
+
Allowed keys: ${Object.keys(ALLOWED_KEYS).join(", ")}`), { parse_mode: "HTML" });
|
|
41232
|
+
return;
|
|
41233
|
+
}
|
|
41234
|
+
try {
|
|
41235
|
+
const settings = loadSettings(config);
|
|
41236
|
+
if (!settings) {
|
|
41237
|
+
await ctx.reply(formatError("No settings file found."), {
|
|
41238
|
+
parse_mode: "HTML"
|
|
41239
|
+
});
|
|
41240
|
+
return;
|
|
41241
|
+
}
|
|
41242
|
+
delete settings[key];
|
|
41243
|
+
saveSettings(config, settings);
|
|
41244
|
+
await ctx.reply(formatSuccess(`Removed <code>${escapeHtml(key)}</code> from settings.`), {
|
|
41245
|
+
parse_mode: "HTML"
|
|
41246
|
+
});
|
|
41247
|
+
} catch (err) {
|
|
41248
|
+
await ctx.reply(formatError(`Failed to update settings: ${err instanceof Error ? err.message : String(err)}`), { parse_mode: "HTML" });
|
|
41249
|
+
}
|
|
41250
|
+
return;
|
|
41251
|
+
}
|
|
41252
|
+
await ctx.reply(USAGE, { parse_mode: "HTML" });
|
|
41253
|
+
}
|
|
41254
41254
|
// src/shell-executor.ts
|
|
41255
41255
|
import { spawn } from "node:child_process";
|
|
41256
41256
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/telegram",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Telegram bot for Locus - remote control your AI agents from Telegram",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"author": "",
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@locusai/sdk": "^0.10.
|
|
35
|
+
"@locusai/sdk": "^0.10.2",
|
|
36
36
|
"dotenv": "^16.4.7",
|
|
37
37
|
"telegraf": "^4.16.3"
|
|
38
38
|
},
|