@hasna/conversations 0.2.38 → 0.2.40

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/index.js CHANGED
@@ -13645,6 +13645,14 @@ var init_db = __esm(() => {
13645
13645
  });
13646
13646
 
13647
13647
  // src/lib/identity.ts
13648
+ var exports_identity = {};
13649
+ __export(exports_identity, {
13650
+ updateCachedAutoName: () => updateCachedAutoName,
13651
+ resolveIdentity: () => resolveIdentity,
13652
+ requireIdentity: () => requireIdentity,
13653
+ getAutoName: () => getAutoName,
13654
+ _resetAutoName: () => _resetAutoName
13655
+ });
13648
13656
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync6 } from "fs";
13649
13657
  import { join as join9, dirname as dirname3 } from "path";
13650
13658
  function isNameTaken(name) {
@@ -13692,6 +13700,15 @@ function resolveIdentity(explicit) {
13692
13700
  return envValue;
13693
13701
  return getAutoName();
13694
13702
  }
13703
+ function requireIdentity(explicit) {
13704
+ const explicitValue = explicit?.trim();
13705
+ if (explicitValue)
13706
+ return explicitValue;
13707
+ const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
13708
+ if (envValue)
13709
+ return envValue;
13710
+ throw new Error("Agent identity required. Set CONVERSATIONS_AGENT_ID env var or pass --from flag.");
13711
+ }
13695
13712
  function updateCachedAutoName(newName) {
13696
13713
  cachedAutoName = newName;
13697
13714
  try {
@@ -13700,6 +13717,9 @@ function updateCachedAutoName(newName) {
13700
13717
  `, "utf-8");
13701
13718
  } catch {}
13702
13719
  }
13720
+ function _resetAutoName() {
13721
+ cachedAutoName = null;
13722
+ }
13703
13723
  var AGENT_ID_FILE, cachedAutoName = null;
13704
13724
  var init_identity = __esm(() => {
13705
13725
  init_names();
@@ -14914,7 +14934,7 @@ var init_presence = __esm(() => {
14914
14934
  var require_package = __commonJS((exports, module) => {
14915
14935
  module.exports = {
14916
14936
  name: "@hasna/conversations",
14917
- version: "0.2.38",
14937
+ version: "0.2.40",
14918
14938
  description: "Real-time CLI messaging for AI agents",
14919
14939
  type: "module",
14920
14940
  bin: {
@@ -45597,6 +45617,10 @@ var init_projects2 = __esm(() => {
45597
45617
  // src/mcp/channel.ts
45598
45618
  function setSessionAgent(agentId) {
45599
45619
  sessionAgentId = agentId;
45620
+ try {
45621
+ const { updateCachedAutoName: updateCachedAutoName2 } = (init_identity(), __toCommonJS(exports_identity));
45622
+ updateCachedAutoName2(agentId);
45623
+ } catch {}
45600
45624
  }
45601
45625
  function getSessionAgent() {
45602
45626
  return sessionAgentId || process.env.CONVERSATIONS_AGENT_ID || null;
@@ -45664,14 +45688,14 @@ ${msg.content}`;
45664
45688
  const agent = getSessionAgent();
45665
45689
  const sid = getSessionId();
45666
45690
  if (agent) {
45667
- const msgs = readMessages({ to: agent, order: "asc", limit: 20 }).filter((m) => m.id > lastAgentMsgId);
45691
+ const msgs = readMessages({ to: agent, order: "asc", limit: 20 }).filter((m) => m.id > lastAgentMsgId && m.from_agent !== agent);
45668
45692
  for (const msg of msgs) {
45669
45693
  lastAgentMsgId = msg.id;
45670
45694
  pushNotification(msg, false);
45671
45695
  }
45672
45696
  }
45673
45697
  if (sid) {
45674
- const msgs = readMessages({ to: `session:${sid}`, order: "asc", limit: 20 }).filter((m) => m.id > lastSessionMsgId);
45698
+ const msgs = readMessages({ to: `session:${sid}`, order: "asc", limit: 20 }).filter((m) => m.id > lastSessionMsgId && m.from_agent !== agent);
45675
45699
  for (const msg of msgs) {
45676
45700
  lastSessionMsgId = msg.id;
45677
45701
  pushNotification(msg, true);
@@ -47026,6 +47050,98 @@ var init_cloud = __esm(() => {
47026
47050
  CONFLICT_TABLES = new Set(["spaces", "projects", "agent_presence"]);
47027
47051
  });
47028
47052
 
47053
+ // src/mcp/telegram-channel.ts
47054
+ async function telegramRequest(token, method, params) {
47055
+ const url2 = `https://api.telegram.org/bot${token}/${method}`;
47056
+ const res = await fetch(url2, {
47057
+ method: "POST",
47058
+ headers: { "Content-Type": "application/json" },
47059
+ body: params ? JSON.stringify(params) : undefined
47060
+ });
47061
+ const data = await res.json();
47062
+ if (!data.ok)
47063
+ throw new Error(`Telegram API error: ${data.description}`);
47064
+ return data.result;
47065
+ }
47066
+ function registerTelegramChannel(server) {
47067
+ const token = process.env.TELEGRAM_BOT_TOKEN;
47068
+ if (!token)
47069
+ return;
47070
+ let lastUpdateId = 0;
47071
+ let pollTimer = null;
47072
+ let botUsername = "bot";
47073
+ telegramRequest(token, "getMe").then((me) => {
47074
+ botUsername = me.username || me.first_name || "bot";
47075
+ console.error(`[telegram-channel] connected as @${botUsername}`);
47076
+ }).catch(() => {});
47077
+ server.registerTool("telegram_send", {
47078
+ description: "Send a message to a Telegram chat. Use this to reply to Telegram messages received via the channel bridge.",
47079
+ inputSchema: {
47080
+ chat_id: exports_external2.coerce.number().describe("Telegram chat ID to send to (from the incoming message's chat_id meta)"),
47081
+ text: exports_external2.string().describe("Message text to send"),
47082
+ parse_mode: exports_external2.string().optional().describe("Optional: HTML or MarkdownV2"),
47083
+ reply_to_message_id: exports_external2.coerce.number().optional().describe("Optional: message ID to reply to")
47084
+ }
47085
+ }, async (args) => {
47086
+ const result = await telegramRequest(token, "sendMessage", {
47087
+ chat_id: args.chat_id,
47088
+ text: args.text,
47089
+ parse_mode: args.parse_mode,
47090
+ reply_to_message_id: args.reply_to_message_id
47091
+ });
47092
+ return { content: [{ type: "text", text: JSON.stringify(result) }] };
47093
+ });
47094
+ function pushNotification(update) {
47095
+ const msg = update.message;
47096
+ if (!msg?.text)
47097
+ return;
47098
+ const from = msg.from?.username || msg.from?.first_name || "unknown";
47099
+ const chatTitle = msg.chat.title || msg.chat.username || String(msg.chat.id);
47100
+ const context = [
47101
+ `From: ${from}`,
47102
+ `Chat: ${chatTitle} (${msg.chat.id})`,
47103
+ `Message ID: ${msg.message_id}`,
47104
+ msg.chat.type !== "private" ? `Type: ${msg.chat.type}` : null
47105
+ ].filter(Boolean).join(" | ");
47106
+ const enrichedContent = `[${context}]
47107
+ ${msg.text}`;
47108
+ server.server.notification({
47109
+ method: "notifications/claude/channel",
47110
+ params: {
47111
+ content: enrichedContent,
47112
+ meta: {
47113
+ from,
47114
+ chat_id: String(msg.chat.id),
47115
+ message_id: String(msg.message_id),
47116
+ chat_type: msg.chat.type,
47117
+ ...msg.chat.title ? { chat_title: msg.chat.title } : {}
47118
+ }
47119
+ }
47120
+ }).catch(() => {});
47121
+ }
47122
+ async function poll() {
47123
+ try {
47124
+ const updates = await telegramRequest(token, "getUpdates", {
47125
+ offset: lastUpdateId + 1,
47126
+ timeout: 1,
47127
+ allowed_updates: ["message"]
47128
+ });
47129
+ for (const update of updates) {
47130
+ lastUpdateId = update.update_id;
47131
+ pushNotification(update);
47132
+ }
47133
+ } catch {}
47134
+ }
47135
+ setTimeout(() => {
47136
+ pollTimer = setInterval(() => poll(), POLL_INTERVAL_MS2);
47137
+ console.error("[telegram-channel] polling started");
47138
+ }, 2000);
47139
+ }
47140
+ var POLL_INTERVAL_MS2 = 2000;
47141
+ var init_telegram_channel = __esm(() => {
47142
+ init_zod2();
47143
+ });
47144
+
47029
47145
  // src/mcp/tools/tmux.ts
47030
47146
  function sleep2(ms) {
47031
47147
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -47166,6 +47282,7 @@ var init_mcp2 = __esm(() => {
47166
47282
  init_advanced();
47167
47283
  init_cloud();
47168
47284
  init_channel();
47285
+ init_telegram_channel();
47169
47286
  init_tmux2();
47170
47287
  import__package2 = __toESM(require_package(), 1);
47171
47288
  server = new McpServer({
@@ -47180,6 +47297,7 @@ var init_mcp2 = __esm(() => {
47180
47297
  registerAdvancedTools(server, import__package2.default.version);
47181
47298
  registerTmuxTools(server);
47182
47299
  registerChannelBridge(server);
47300
+ registerTelegramChannel(server);
47183
47301
  isDirectRun = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("mcp.js") || process.argv[1]?.endsWith("mcp.ts");
47184
47302
  if (isDirectRun) {
47185
47303
  startMcpServer().catch((error48) => {
package/bin/mcp.js CHANGED
@@ -17924,6 +17924,441 @@ var init_db = __esm(() => {
17924
17924
  init_dist();
17925
17925
  });
17926
17926
 
17927
+ // src/lib/names.ts
17928
+ var AGENT_NAMES;
17929
+ var init_names = __esm(() => {
17930
+ AGENT_NAMES = [
17931
+ "amber-fox",
17932
+ "arctic-wolf",
17933
+ "ashen-crow",
17934
+ "azure-hawk",
17935
+ "astral-lynx",
17936
+ "autumn-bear",
17937
+ "agile-puma",
17938
+ "alpine-ibex",
17939
+ "ancient-owl",
17940
+ "aqua-otter",
17941
+ "arid-viper",
17942
+ "atom-finch",
17943
+ "auburn-deer",
17944
+ "aurora-seal",
17945
+ "avid-mink",
17946
+ "blaze-tiger",
17947
+ "bright-heron",
17948
+ "bronze-eagle",
17949
+ "brisk-hare",
17950
+ "burnt-moth",
17951
+ "bold-raven",
17952
+ "blue-whale",
17953
+ "boreal-fox",
17954
+ "brass-cobra",
17955
+ "brave-ram",
17956
+ "brick-crane",
17957
+ "brief-newt",
17958
+ "briny-crab",
17959
+ "broad-elk",
17960
+ "brook-dove",
17961
+ "calm-panda",
17962
+ "cedar-jay",
17963
+ "chief-lion",
17964
+ "chrome-bat",
17965
+ "civic-wren",
17966
+ "clear-swan",
17967
+ "cliff-goat",
17968
+ "coal-shark",
17969
+ "cold-crane",
17970
+ "copper-jay",
17971
+ "coral-fish",
17972
+ "crisp-lark",
17973
+ "cross-mole",
17974
+ "cubic-wasp",
17975
+ "cyan-toad",
17976
+ "dark-stag",
17977
+ "dawn-robin",
17978
+ "deep-squid",
17979
+ "delta-fox",
17980
+ "dense-boar",
17981
+ "dew-spider",
17982
+ "dim-gecko",
17983
+ "draft-bear",
17984
+ "drift-gull",
17985
+ "dry-newt",
17986
+ "dual-crane",
17987
+ "dune-mouse",
17988
+ "dusk-moth",
17989
+ "dusty-mule",
17990
+ "dwarf-carp",
17991
+ "east-falcon",
17992
+ "echo-parrot",
17993
+ "edge-shark",
17994
+ "elm-beetle",
17995
+ "ember-lynx",
17996
+ "epoch-crane",
17997
+ "even-pike",
17998
+ "extra-ant",
17999
+ "elder-stork",
18000
+ "ebon-crow",
18001
+ "ever-finch",
18002
+ "exact-moth",
18003
+ "exile-wren",
18004
+ "equal-dove",
18005
+ "etch-hare",
18006
+ "faint-orca",
18007
+ "far-condor",
18008
+ "fern-mouse",
18009
+ "fierce-yak",
18010
+ "first-kite",
18011
+ "fjord-seal",
18012
+ "flint-wolf",
18013
+ "fog-parrot",
18014
+ "forge-bull",
18015
+ "fossil-ray",
18016
+ "frank-mink",
18017
+ "free-eagle",
18018
+ "fresh-colt",
18019
+ "frost-bear",
18020
+ "fuse-wasp",
18021
+ "gale-hawk",
18022
+ "gem-turtle",
18023
+ "ghost-lynx",
18024
+ "gilt-robin",
18025
+ "glad-moose",
18026
+ "glass-eel",
18027
+ "gleam-puma",
18028
+ "glyph-owl",
18029
+ "gold-crane",
18030
+ "gorge-lion",
18031
+ "grain-duck",
18032
+ "grand-wolf",
18033
+ "gray-fox",
18034
+ "green-hare",
18035
+ "grit-shark",
18036
+ "half-stork",
18037
+ "haze-panther",
18038
+ "heart-dove",
18039
+ "helm-eagle",
18040
+ "herb-toad",
18041
+ "hex-spider",
18042
+ "high-falcon",
18043
+ "hive-hornet",
18044
+ "holo-swan",
18045
+ "hood-cobra",
18046
+ "horn-bison",
18047
+ "huge-squid",
18048
+ "hull-crab",
18049
+ "hunt-marten",
18050
+ "husk-moth",
18051
+ "ice-leopard",
18052
+ "idle-crane",
18053
+ "inch-beetle",
18054
+ "indigo-jay",
18055
+ "inner-fox",
18056
+ "ion-parrot",
18057
+ "iron-bull",
18058
+ "isle-pelican",
18059
+ "ivory-hawk",
18060
+ "ivy-snake",
18061
+ "iota-wren",
18062
+ "ink-raven",
18063
+ "ignite-ram",
18064
+ "inert-slug",
18065
+ "infra-mole",
18066
+ "jade-tiger",
18067
+ "jest-magpie",
18068
+ "jewel-crane",
18069
+ "joint-boar",
18070
+ "jovial-elk",
18071
+ "jump-frog",
18072
+ "jungle-cat",
18073
+ "jury-dove",
18074
+ "just-heron",
18075
+ "jolt-wasp",
18076
+ "keen-osprey",
18077
+ "kelp-seal",
18078
+ "key-falcon",
18079
+ "kind-panda",
18080
+ "knot-viper",
18081
+ "kraft-bear",
18082
+ "kite-mouse",
18083
+ "knoll-deer",
18084
+ "know-crane",
18085
+ "karma-wolf",
18086
+ "lake-otter",
18087
+ "lapis-jay",
18088
+ "last-condor",
18089
+ "leaf-gecko",
18090
+ "lean-coyote",
18091
+ "light-lynx",
18092
+ "lime-parrot",
18093
+ "live-eagle",
18094
+ "long-crane",
18095
+ "lost-fox",
18096
+ "loud-finch",
18097
+ "low-shark",
18098
+ "luck-rabbit",
18099
+ "lunar-owl",
18100
+ "lush-ibis",
18101
+ "malt-badger",
18102
+ "maple-wren",
18103
+ "mars-falcon",
18104
+ "matte-crow",
18105
+ "mesa-hawk",
18106
+ "mild-orca",
18107
+ "mint-dove",
18108
+ "mist-puma",
18109
+ "mock-robin",
18110
+ "mono-wolf",
18111
+ "moon-bear",
18112
+ "moss-turtle",
18113
+ "mud-heron",
18114
+ "mute-swan",
18115
+ "myth-lynx",
18116
+ "navy-eagle",
18117
+ "near-mink",
18118
+ "neon-parrot",
18119
+ "nest-crane",
18120
+ "next-fox",
18121
+ "nimble-ram",
18122
+ "node-spider",
18123
+ "noon-hawk",
18124
+ "north-seal",
18125
+ "nova-owl",
18126
+ "null-moth",
18127
+ "numb-carp",
18128
+ "nutmeg-jay",
18129
+ "neat-cobra",
18130
+ "nomad-elk",
18131
+ "oak-badger",
18132
+ "oat-finch",
18133
+ "odd-pelican",
18134
+ "olive-bear",
18135
+ "onyx-raven",
18136
+ "opal-crane",
18137
+ "open-wolf",
18138
+ "orbit-lynx",
18139
+ "ore-shark",
18140
+ "outer-dove",
18141
+ "pale-tiger",
18142
+ "park-heron",
18143
+ "peak-eagle",
18144
+ "pine-fox",
18145
+ "pixel-owl",
18146
+ "plain-goat",
18147
+ "plum-crane",
18148
+ "polar-ray",
18149
+ "port-falcon",
18150
+ "prime-wolf",
18151
+ "prism-jay",
18152
+ "proud-lion",
18153
+ "pulse-bat",
18154
+ "pure-swan",
18155
+ "pyro-hawk",
18156
+ "quake-bear",
18157
+ "quartz-jay",
18158
+ "quest-falcon",
18159
+ "quick-otter",
18160
+ "quiet-crane",
18161
+ "rain-leopard",
18162
+ "rapid-hare",
18163
+ "raw-condor",
18164
+ "reef-dolphin",
18165
+ "regal-stag",
18166
+ "ridge-fox",
18167
+ "rift-cobra",
18168
+ "rigid-crane",
18169
+ "river-otter",
18170
+ "rock-eagle",
18171
+ "root-mole",
18172
+ "rose-finch",
18173
+ "rough-boar",
18174
+ "ruby-hawk",
18175
+ "rust-wolf",
18176
+ "sage-owl",
18177
+ "salt-crane",
18178
+ "sand-viper",
18179
+ "satin-dove",
18180
+ "scale-dragon",
18181
+ "scarlet-ibis",
18182
+ "sea-falcon",
18183
+ "shade-lynx",
18184
+ "sharp-eagle",
18185
+ "shell-crab",
18186
+ "short-fox",
18187
+ "sigma-jay",
18188
+ "silk-moth",
18189
+ "silver-wolf",
18190
+ "slate-bear",
18191
+ "slim-heron",
18192
+ "smoke-puma",
18193
+ "snap-turtle",
18194
+ "snow-leopard",
18195
+ "solar-crane",
18196
+ "solid-ram",
18197
+ "sonic-bat",
18198
+ "south-seal",
18199
+ "spark-robin",
18200
+ "spice-wren",
18201
+ "split-mink",
18202
+ "spring-elk",
18203
+ "squid-ink",
18204
+ "stark-crow",
18205
+ "steel-hawk",
18206
+ "stern-bull",
18207
+ "still-swan",
18208
+ "stone-fox",
18209
+ "storm-eagle",
18210
+ "stout-boar",
18211
+ "stray-cat",
18212
+ "strong-lion",
18213
+ "sun-parrot",
18214
+ "surf-dolphin",
18215
+ "swift-deer",
18216
+ "teal-crane",
18217
+ "terra-wolf",
18218
+ "thick-bear",
18219
+ "thin-spider",
18220
+ "third-owl",
18221
+ "thorn-fox",
18222
+ "tide-seal",
18223
+ "timber-jay",
18224
+ "tiny-wren",
18225
+ "toast-mole",
18226
+ "topaz-hawk",
18227
+ "torch-lynx",
18228
+ "trace-falcon",
18229
+ "true-eagle",
18230
+ "tusk-walrus",
18231
+ "ultra-crane",
18232
+ "umbra-wolf",
18233
+ "unit-fox",
18234
+ "upper-hawk",
18235
+ "urban-jay",
18236
+ "vale-deer",
18237
+ "vast-eagle",
18238
+ "vault-bear",
18239
+ "velvet-owl",
18240
+ "vent-crane",
18241
+ "verse-fox",
18242
+ "vigor-lynx",
18243
+ "vine-parrot",
18244
+ "vivid-swan",
18245
+ "void-raven",
18246
+ "volt-hawk",
18247
+ "vow-falcon",
18248
+ "vintage-jay",
18249
+ "vista-wolf",
18250
+ "vital-hare",
18251
+ "warm-otter",
18252
+ "wave-dolphin",
18253
+ "wax-crane",
18254
+ "west-falcon",
18255
+ "wheat-mouse",
18256
+ "white-tiger",
18257
+ "wide-eagle",
18258
+ "wild-fox",
18259
+ "wind-hawk",
18260
+ "wire-spider",
18261
+ "wise-owl",
18262
+ "wood-thrush",
18263
+ "wool-ram",
18264
+ "wren-song",
18265
+ "wry-crow",
18266
+ "xeno-crane",
18267
+ "xerus-fox",
18268
+ "yarn-robin",
18269
+ "yew-falcon",
18270
+ "young-wolf",
18271
+ "zeal-hawk",
18272
+ "zen-panda",
18273
+ "zero-crane",
18274
+ "zinc-eagle",
18275
+ "zone-fox"
18276
+ ];
18277
+ });
18278
+
18279
+ // src/lib/identity.ts
18280
+ var exports_identity = {};
18281
+ __export(exports_identity, {
18282
+ updateCachedAutoName: () => updateCachedAutoName,
18283
+ resolveIdentity: () => resolveIdentity,
18284
+ requireIdentity: () => requireIdentity,
18285
+ getAutoName: () => getAutoName,
18286
+ _resetAutoName: () => _resetAutoName
18287
+ });
18288
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7 } from "fs";
18289
+ import { join as join11, dirname as dirname3 } from "path";
18290
+ function isNameTaken(name) {
18291
+ try {
18292
+ const { getDb: getDb2 } = (init_db(), __toCommonJS(exports_db));
18293
+ const db2 = getDb2();
18294
+ const row = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(name);
18295
+ return !!row;
18296
+ } catch {
18297
+ return false;
18298
+ }
18299
+ }
18300
+ function getAutoName() {
18301
+ if (cachedAutoName)
18302
+ return cachedAutoName;
18303
+ try {
18304
+ const name2 = readFileSync5(AGENT_ID_FILE, "utf-8").trim();
18305
+ if (name2) {
18306
+ cachedAutoName = name2;
18307
+ return name2;
18308
+ }
18309
+ } catch {}
18310
+ const shuffled = [...AGENT_NAMES].sort(() => Math.random() - 0.5);
18311
+ let name = shuffled[0];
18312
+ for (const candidate of shuffled) {
18313
+ if (!isNameTaken(candidate)) {
18314
+ name = candidate;
18315
+ break;
18316
+ }
18317
+ }
18318
+ cachedAutoName = name;
18319
+ try {
18320
+ mkdirSync7(dirname3(AGENT_ID_FILE), { recursive: true });
18321
+ writeFileSync3(AGENT_ID_FILE, name + `
18322
+ `, "utf-8");
18323
+ } catch {}
18324
+ return name;
18325
+ }
18326
+ function resolveIdentity(explicit) {
18327
+ const explicitValue = explicit?.trim();
18328
+ if (explicitValue)
18329
+ return explicitValue;
18330
+ const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
18331
+ if (envValue)
18332
+ return envValue;
18333
+ return getAutoName();
18334
+ }
18335
+ function requireIdentity(explicit) {
18336
+ const explicitValue = explicit?.trim();
18337
+ if (explicitValue)
18338
+ return explicitValue;
18339
+ const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
18340
+ if (envValue)
18341
+ return envValue;
18342
+ throw new Error("Agent identity required. Set CONVERSATIONS_AGENT_ID env var or pass --from flag.");
18343
+ }
18344
+ function updateCachedAutoName(newName) {
18345
+ cachedAutoName = newName;
18346
+ try {
18347
+ mkdirSync7(dirname3(AGENT_ID_FILE), { recursive: true });
18348
+ writeFileSync3(AGENT_ID_FILE, newName + `
18349
+ `, "utf-8");
18350
+ } catch {}
18351
+ }
18352
+ function _resetAutoName() {
18353
+ cachedAutoName = null;
18354
+ }
18355
+ var AGENT_ID_FILE, cachedAutoName = null;
18356
+ var init_identity = __esm(() => {
18357
+ init_names();
18358
+ init_db();
18359
+ AGENT_ID_FILE = join11(getDataDir2(), "agent-id");
18360
+ });
18361
+
17927
18362
  // src/lib/pg-migrations.ts
17928
18363
  var exports_pg_migrations = {};
17929
18364
  __export(exports_pg_migrations, {
@@ -40793,418 +41228,8 @@ function getSessionActivity(sessionId) {
40793
41228
  };
40794
41229
  }
40795
41230
 
40796
- // src/lib/identity.ts
40797
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync7 } from "fs";
40798
- import { join as join11, dirname as dirname3 } from "path";
40799
-
40800
- // src/lib/names.ts
40801
- var AGENT_NAMES = [
40802
- "amber-fox",
40803
- "arctic-wolf",
40804
- "ashen-crow",
40805
- "azure-hawk",
40806
- "astral-lynx",
40807
- "autumn-bear",
40808
- "agile-puma",
40809
- "alpine-ibex",
40810
- "ancient-owl",
40811
- "aqua-otter",
40812
- "arid-viper",
40813
- "atom-finch",
40814
- "auburn-deer",
40815
- "aurora-seal",
40816
- "avid-mink",
40817
- "blaze-tiger",
40818
- "bright-heron",
40819
- "bronze-eagle",
40820
- "brisk-hare",
40821
- "burnt-moth",
40822
- "bold-raven",
40823
- "blue-whale",
40824
- "boreal-fox",
40825
- "brass-cobra",
40826
- "brave-ram",
40827
- "brick-crane",
40828
- "brief-newt",
40829
- "briny-crab",
40830
- "broad-elk",
40831
- "brook-dove",
40832
- "calm-panda",
40833
- "cedar-jay",
40834
- "chief-lion",
40835
- "chrome-bat",
40836
- "civic-wren",
40837
- "clear-swan",
40838
- "cliff-goat",
40839
- "coal-shark",
40840
- "cold-crane",
40841
- "copper-jay",
40842
- "coral-fish",
40843
- "crisp-lark",
40844
- "cross-mole",
40845
- "cubic-wasp",
40846
- "cyan-toad",
40847
- "dark-stag",
40848
- "dawn-robin",
40849
- "deep-squid",
40850
- "delta-fox",
40851
- "dense-boar",
40852
- "dew-spider",
40853
- "dim-gecko",
40854
- "draft-bear",
40855
- "drift-gull",
40856
- "dry-newt",
40857
- "dual-crane",
40858
- "dune-mouse",
40859
- "dusk-moth",
40860
- "dusty-mule",
40861
- "dwarf-carp",
40862
- "east-falcon",
40863
- "echo-parrot",
40864
- "edge-shark",
40865
- "elm-beetle",
40866
- "ember-lynx",
40867
- "epoch-crane",
40868
- "even-pike",
40869
- "extra-ant",
40870
- "elder-stork",
40871
- "ebon-crow",
40872
- "ever-finch",
40873
- "exact-moth",
40874
- "exile-wren",
40875
- "equal-dove",
40876
- "etch-hare",
40877
- "faint-orca",
40878
- "far-condor",
40879
- "fern-mouse",
40880
- "fierce-yak",
40881
- "first-kite",
40882
- "fjord-seal",
40883
- "flint-wolf",
40884
- "fog-parrot",
40885
- "forge-bull",
40886
- "fossil-ray",
40887
- "frank-mink",
40888
- "free-eagle",
40889
- "fresh-colt",
40890
- "frost-bear",
40891
- "fuse-wasp",
40892
- "gale-hawk",
40893
- "gem-turtle",
40894
- "ghost-lynx",
40895
- "gilt-robin",
40896
- "glad-moose",
40897
- "glass-eel",
40898
- "gleam-puma",
40899
- "glyph-owl",
40900
- "gold-crane",
40901
- "gorge-lion",
40902
- "grain-duck",
40903
- "grand-wolf",
40904
- "gray-fox",
40905
- "green-hare",
40906
- "grit-shark",
40907
- "half-stork",
40908
- "haze-panther",
40909
- "heart-dove",
40910
- "helm-eagle",
40911
- "herb-toad",
40912
- "hex-spider",
40913
- "high-falcon",
40914
- "hive-hornet",
40915
- "holo-swan",
40916
- "hood-cobra",
40917
- "horn-bison",
40918
- "huge-squid",
40919
- "hull-crab",
40920
- "hunt-marten",
40921
- "husk-moth",
40922
- "ice-leopard",
40923
- "idle-crane",
40924
- "inch-beetle",
40925
- "indigo-jay",
40926
- "inner-fox",
40927
- "ion-parrot",
40928
- "iron-bull",
40929
- "isle-pelican",
40930
- "ivory-hawk",
40931
- "ivy-snake",
40932
- "iota-wren",
40933
- "ink-raven",
40934
- "ignite-ram",
40935
- "inert-slug",
40936
- "infra-mole",
40937
- "jade-tiger",
40938
- "jest-magpie",
40939
- "jewel-crane",
40940
- "joint-boar",
40941
- "jovial-elk",
40942
- "jump-frog",
40943
- "jungle-cat",
40944
- "jury-dove",
40945
- "just-heron",
40946
- "jolt-wasp",
40947
- "keen-osprey",
40948
- "kelp-seal",
40949
- "key-falcon",
40950
- "kind-panda",
40951
- "knot-viper",
40952
- "kraft-bear",
40953
- "kite-mouse",
40954
- "knoll-deer",
40955
- "know-crane",
40956
- "karma-wolf",
40957
- "lake-otter",
40958
- "lapis-jay",
40959
- "last-condor",
40960
- "leaf-gecko",
40961
- "lean-coyote",
40962
- "light-lynx",
40963
- "lime-parrot",
40964
- "live-eagle",
40965
- "long-crane",
40966
- "lost-fox",
40967
- "loud-finch",
40968
- "low-shark",
40969
- "luck-rabbit",
40970
- "lunar-owl",
40971
- "lush-ibis",
40972
- "malt-badger",
40973
- "maple-wren",
40974
- "mars-falcon",
40975
- "matte-crow",
40976
- "mesa-hawk",
40977
- "mild-orca",
40978
- "mint-dove",
40979
- "mist-puma",
40980
- "mock-robin",
40981
- "mono-wolf",
40982
- "moon-bear",
40983
- "moss-turtle",
40984
- "mud-heron",
40985
- "mute-swan",
40986
- "myth-lynx",
40987
- "navy-eagle",
40988
- "near-mink",
40989
- "neon-parrot",
40990
- "nest-crane",
40991
- "next-fox",
40992
- "nimble-ram",
40993
- "node-spider",
40994
- "noon-hawk",
40995
- "north-seal",
40996
- "nova-owl",
40997
- "null-moth",
40998
- "numb-carp",
40999
- "nutmeg-jay",
41000
- "neat-cobra",
41001
- "nomad-elk",
41002
- "oak-badger",
41003
- "oat-finch",
41004
- "odd-pelican",
41005
- "olive-bear",
41006
- "onyx-raven",
41007
- "opal-crane",
41008
- "open-wolf",
41009
- "orbit-lynx",
41010
- "ore-shark",
41011
- "outer-dove",
41012
- "pale-tiger",
41013
- "park-heron",
41014
- "peak-eagle",
41015
- "pine-fox",
41016
- "pixel-owl",
41017
- "plain-goat",
41018
- "plum-crane",
41019
- "polar-ray",
41020
- "port-falcon",
41021
- "prime-wolf",
41022
- "prism-jay",
41023
- "proud-lion",
41024
- "pulse-bat",
41025
- "pure-swan",
41026
- "pyro-hawk",
41027
- "quake-bear",
41028
- "quartz-jay",
41029
- "quest-falcon",
41030
- "quick-otter",
41031
- "quiet-crane",
41032
- "rain-leopard",
41033
- "rapid-hare",
41034
- "raw-condor",
41035
- "reef-dolphin",
41036
- "regal-stag",
41037
- "ridge-fox",
41038
- "rift-cobra",
41039
- "rigid-crane",
41040
- "river-otter",
41041
- "rock-eagle",
41042
- "root-mole",
41043
- "rose-finch",
41044
- "rough-boar",
41045
- "ruby-hawk",
41046
- "rust-wolf",
41047
- "sage-owl",
41048
- "salt-crane",
41049
- "sand-viper",
41050
- "satin-dove",
41051
- "scale-dragon",
41052
- "scarlet-ibis",
41053
- "sea-falcon",
41054
- "shade-lynx",
41055
- "sharp-eagle",
41056
- "shell-crab",
41057
- "short-fox",
41058
- "sigma-jay",
41059
- "silk-moth",
41060
- "silver-wolf",
41061
- "slate-bear",
41062
- "slim-heron",
41063
- "smoke-puma",
41064
- "snap-turtle",
41065
- "snow-leopard",
41066
- "solar-crane",
41067
- "solid-ram",
41068
- "sonic-bat",
41069
- "south-seal",
41070
- "spark-robin",
41071
- "spice-wren",
41072
- "split-mink",
41073
- "spring-elk",
41074
- "squid-ink",
41075
- "stark-crow",
41076
- "steel-hawk",
41077
- "stern-bull",
41078
- "still-swan",
41079
- "stone-fox",
41080
- "storm-eagle",
41081
- "stout-boar",
41082
- "stray-cat",
41083
- "strong-lion",
41084
- "sun-parrot",
41085
- "surf-dolphin",
41086
- "swift-deer",
41087
- "teal-crane",
41088
- "terra-wolf",
41089
- "thick-bear",
41090
- "thin-spider",
41091
- "third-owl",
41092
- "thorn-fox",
41093
- "tide-seal",
41094
- "timber-jay",
41095
- "tiny-wren",
41096
- "toast-mole",
41097
- "topaz-hawk",
41098
- "torch-lynx",
41099
- "trace-falcon",
41100
- "true-eagle",
41101
- "tusk-walrus",
41102
- "ultra-crane",
41103
- "umbra-wolf",
41104
- "unit-fox",
41105
- "upper-hawk",
41106
- "urban-jay",
41107
- "vale-deer",
41108
- "vast-eagle",
41109
- "vault-bear",
41110
- "velvet-owl",
41111
- "vent-crane",
41112
- "verse-fox",
41113
- "vigor-lynx",
41114
- "vine-parrot",
41115
- "vivid-swan",
41116
- "void-raven",
41117
- "volt-hawk",
41118
- "vow-falcon",
41119
- "vintage-jay",
41120
- "vista-wolf",
41121
- "vital-hare",
41122
- "warm-otter",
41123
- "wave-dolphin",
41124
- "wax-crane",
41125
- "west-falcon",
41126
- "wheat-mouse",
41127
- "white-tiger",
41128
- "wide-eagle",
41129
- "wild-fox",
41130
- "wind-hawk",
41131
- "wire-spider",
41132
- "wise-owl",
41133
- "wood-thrush",
41134
- "wool-ram",
41135
- "wren-song",
41136
- "wry-crow",
41137
- "xeno-crane",
41138
- "xerus-fox",
41139
- "yarn-robin",
41140
- "yew-falcon",
41141
- "young-wolf",
41142
- "zeal-hawk",
41143
- "zen-panda",
41144
- "zero-crane",
41145
- "zinc-eagle",
41146
- "zone-fox"
41147
- ];
41148
-
41149
- // src/lib/identity.ts
41150
- init_db();
41151
- var AGENT_ID_FILE = join11(getDataDir2(), "agent-id");
41152
- var cachedAutoName = null;
41153
- function isNameTaken(name) {
41154
- try {
41155
- const { getDb: getDb2 } = (init_db(), __toCommonJS(exports_db));
41156
- const db2 = getDb2();
41157
- const row = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(name);
41158
- return !!row;
41159
- } catch {
41160
- return false;
41161
- }
41162
- }
41163
- function getAutoName() {
41164
- if (cachedAutoName)
41165
- return cachedAutoName;
41166
- try {
41167
- const name2 = readFileSync5(AGENT_ID_FILE, "utf-8").trim();
41168
- if (name2) {
41169
- cachedAutoName = name2;
41170
- return name2;
41171
- }
41172
- } catch {}
41173
- const shuffled = [...AGENT_NAMES].sort(() => Math.random() - 0.5);
41174
- let name = shuffled[0];
41175
- for (const candidate of shuffled) {
41176
- if (!isNameTaken(candidate)) {
41177
- name = candidate;
41178
- break;
41179
- }
41180
- }
41181
- cachedAutoName = name;
41182
- try {
41183
- mkdirSync7(dirname3(AGENT_ID_FILE), { recursive: true });
41184
- writeFileSync3(AGENT_ID_FILE, name + `
41185
- `, "utf-8");
41186
- } catch {}
41187
- return name;
41188
- }
41189
- function resolveIdentity(explicit) {
41190
- const explicitValue = explicit?.trim();
41191
- if (explicitValue)
41192
- return explicitValue;
41193
- const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
41194
- if (envValue)
41195
- return envValue;
41196
- return getAutoName();
41197
- }
41198
- function updateCachedAutoName(newName) {
41199
- cachedAutoName = newName;
41200
- try {
41201
- mkdirSync7(dirname3(AGENT_ID_FILE), { recursive: true });
41202
- writeFileSync3(AGENT_ID_FILE, newName + `
41203
- `, "utf-8");
41204
- } catch {}
41205
- }
41206
-
41207
41231
  // src/mcp/tools/messaging.ts
41232
+ init_identity();
41208
41233
  function registerMessagingTools(server, resolveProjectId) {
41209
41234
  server.registerTool("send_message", {
41210
41235
  description: "Send a DM to an agent by name, or to a specific agent-claude session by ID. When target_session_id is provided, the message is routed to that exact session and auto-injected into its conversation.",
@@ -41732,6 +41757,7 @@ function unarchiveSpace(name) {
41732
41757
  }
41733
41758
 
41734
41759
  // src/mcp/tools/spaces.ts
41760
+ init_identity();
41735
41761
  function registerSpaceTools(server) {
41736
41762
  server.registerTool("create_space", {
41737
41763
  description: "Create a space and auto-join.",
@@ -42224,6 +42250,7 @@ function deleteProject(id) {
42224
42250
  }
42225
42251
 
42226
42252
  // src/mcp/tools/projects.ts
42253
+ init_identity();
42227
42254
  function registerProjectTools(server) {
42228
42255
  server.registerTool("create_project", {
42229
42256
  description: "Create a project for agent collaboration.",
@@ -42426,11 +42453,18 @@ function registerProjectTools(server) {
42426
42453
  });
42427
42454
  }
42428
42455
 
42456
+ // src/mcp/tools/agents.ts
42457
+ init_identity();
42458
+
42429
42459
  // src/mcp/channel.ts
42430
42460
  var POLL_INTERVAL_MS = 1000;
42431
42461
  var sessionAgentId = null;
42432
42462
  function setSessionAgent(agentId) {
42433
42463
  sessionAgentId = agentId;
42464
+ try {
42465
+ const { updateCachedAutoName: updateCachedAutoName2 } = (init_identity(), __toCommonJS(exports_identity));
42466
+ updateCachedAutoName2(agentId);
42467
+ } catch {}
42434
42468
  }
42435
42469
  function getSessionAgent() {
42436
42470
  return sessionAgentId || process.env.CONVERSATIONS_AGENT_ID || null;
@@ -42498,14 +42532,14 @@ ${msg.content}`;
42498
42532
  const agent = getSessionAgent();
42499
42533
  const sid = getSessionId();
42500
42534
  if (agent) {
42501
- const msgs = readMessages({ to: agent, order: "asc", limit: 20 }).filter((m) => m.id > lastAgentMsgId);
42535
+ const msgs = readMessages({ to: agent, order: "asc", limit: 20 }).filter((m) => m.id > lastAgentMsgId && m.from_agent !== agent);
42502
42536
  for (const msg of msgs) {
42503
42537
  lastAgentMsgId = msg.id;
42504
42538
  pushNotification(msg, false);
42505
42539
  }
42506
42540
  }
42507
42541
  if (sid) {
42508
- const msgs = readMessages({ to: `session:${sid}`, order: "asc", limit: 20 }).filter((m) => m.id > lastSessionMsgId);
42542
+ const msgs = readMessages({ to: `session:${sid}`, order: "asc", limit: 20 }).filter((m) => m.id > lastSessionMsgId && m.from_agent !== agent);
42509
42543
  for (const msg of msgs) {
42510
42544
  lastSessionMsgId = msg.id;
42511
42545
  pushNotification(msg, true);
@@ -42709,6 +42743,9 @@ function registerAgentTools(server, agentFocus, getAgentFocus) {
42709
42743
  });
42710
42744
  }
42711
42745
 
42746
+ // src/mcp/tools/advanced.ts
42747
+ init_identity();
42748
+
42712
42749
  // src/lib/reactions.ts
42713
42750
  init_db();
42714
42751
  function addReaction(messageId, agent, emoji3) {
@@ -44169,6 +44206,95 @@ function formatError2(e) {
44169
44206
  return String(e);
44170
44207
  }
44171
44208
 
44209
+ // src/mcp/telegram-channel.ts
44210
+ var POLL_INTERVAL_MS2 = 2000;
44211
+ async function telegramRequest(token, method, params) {
44212
+ const url2 = `https://api.telegram.org/bot${token}/${method}`;
44213
+ const res = await fetch(url2, {
44214
+ method: "POST",
44215
+ headers: { "Content-Type": "application/json" },
44216
+ body: params ? JSON.stringify(params) : undefined
44217
+ });
44218
+ const data = await res.json();
44219
+ if (!data.ok)
44220
+ throw new Error(`Telegram API error: ${data.description}`);
44221
+ return data.result;
44222
+ }
44223
+ function registerTelegramChannel(server) {
44224
+ const token = process.env.TELEGRAM_BOT_TOKEN;
44225
+ if (!token)
44226
+ return;
44227
+ let lastUpdateId = 0;
44228
+ let pollTimer = null;
44229
+ let botUsername = "bot";
44230
+ telegramRequest(token, "getMe").then((me) => {
44231
+ botUsername = me.username || me.first_name || "bot";
44232
+ console.error(`[telegram-channel] connected as @${botUsername}`);
44233
+ }).catch(() => {});
44234
+ server.registerTool("telegram_send", {
44235
+ description: "Send a message to a Telegram chat. Use this to reply to Telegram messages received via the channel bridge.",
44236
+ inputSchema: {
44237
+ chat_id: exports_external.coerce.number().describe("Telegram chat ID to send to (from the incoming message's chat_id meta)"),
44238
+ text: exports_external.string().describe("Message text to send"),
44239
+ parse_mode: exports_external.string().optional().describe("Optional: HTML or MarkdownV2"),
44240
+ reply_to_message_id: exports_external.coerce.number().optional().describe("Optional: message ID to reply to")
44241
+ }
44242
+ }, async (args) => {
44243
+ const result = await telegramRequest(token, "sendMessage", {
44244
+ chat_id: args.chat_id,
44245
+ text: args.text,
44246
+ parse_mode: args.parse_mode,
44247
+ reply_to_message_id: args.reply_to_message_id
44248
+ });
44249
+ return { content: [{ type: "text", text: JSON.stringify(result) }] };
44250
+ });
44251
+ function pushNotification(update) {
44252
+ const msg = update.message;
44253
+ if (!msg?.text)
44254
+ return;
44255
+ const from = msg.from?.username || msg.from?.first_name || "unknown";
44256
+ const chatTitle = msg.chat.title || msg.chat.username || String(msg.chat.id);
44257
+ const context = [
44258
+ `From: ${from}`,
44259
+ `Chat: ${chatTitle} (${msg.chat.id})`,
44260
+ `Message ID: ${msg.message_id}`,
44261
+ msg.chat.type !== "private" ? `Type: ${msg.chat.type}` : null
44262
+ ].filter(Boolean).join(" | ");
44263
+ const enrichedContent = `[${context}]
44264
+ ${msg.text}`;
44265
+ server.server.notification({
44266
+ method: "notifications/claude/channel",
44267
+ params: {
44268
+ content: enrichedContent,
44269
+ meta: {
44270
+ from,
44271
+ chat_id: String(msg.chat.id),
44272
+ message_id: String(msg.message_id),
44273
+ chat_type: msg.chat.type,
44274
+ ...msg.chat.title ? { chat_title: msg.chat.title } : {}
44275
+ }
44276
+ }
44277
+ }).catch(() => {});
44278
+ }
44279
+ async function poll() {
44280
+ try {
44281
+ const updates = await telegramRequest(token, "getUpdates", {
44282
+ offset: lastUpdateId + 1,
44283
+ timeout: 1,
44284
+ allowed_updates: ["message"]
44285
+ });
44286
+ for (const update of updates) {
44287
+ lastUpdateId = update.update_id;
44288
+ pushNotification(update);
44289
+ }
44290
+ } catch {}
44291
+ }
44292
+ setTimeout(() => {
44293
+ pollTimer = setInterval(() => poll(), POLL_INTERVAL_MS2);
44294
+ console.error("[telegram-channel] polling started");
44295
+ }, 2000);
44296
+ }
44297
+
44172
44298
  // src/cli/commands/tmux.ts
44173
44299
  import { execSync } from "child_process";
44174
44300
  function sleep(ms) {
@@ -44317,7 +44443,7 @@ function registerTmuxTools(server) {
44317
44443
  // package.json
44318
44444
  var package_default = {
44319
44445
  name: "@hasna/conversations",
44320
- version: "0.2.38",
44446
+ version: "0.2.40",
44321
44447
  description: "Real-time CLI messaging for AI agents",
44322
44448
  type: "module",
44323
44449
  bin: {
@@ -44421,6 +44547,7 @@ registerAgentTools(server, agentFocus, getAgentFocus);
44421
44547
  registerAdvancedTools(server, package_default.version);
44422
44548
  registerTmuxTools(server);
44423
44549
  registerChannelBridge(server);
44550
+ registerTelegramChannel(server);
44424
44551
  async function startMcpServer() {
44425
44552
  const transport = new StdioServerTransport;
44426
44553
  registerCloudSyncTools(server);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Telegram channel bridge for conversations MCP server.
3
+ *
4
+ * Polls a Telegram bot for new messages and pushes them as
5
+ * `notifications/claude/channel` events. Also registers a
6
+ * `telegram_send` tool for replying.
7
+ *
8
+ * Requires: TELEGRAM_BOT_TOKEN env var or connect-telegram profile.
9
+ *
10
+ * Usage: Set TELEGRAM_BOT_TOKEN and the bridge auto-starts.
11
+ */
12
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
13
+ export declare function registerTelegramChannel(server: McpServer): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {