@hasna/conversations 0.2.34 → 0.2.35

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/hook.js CHANGED
@@ -4,42 +4,32 @@ var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- function __accessProp(key) {
8
- return this[key];
9
- }
7
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
10
8
  var __toCommonJS = (from) => {
11
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
9
+ var entry = __moduleCache.get(from), desc;
12
10
  if (entry)
13
11
  return entry;
14
12
  entry = __defProp({}, "__esModule", { value: true });
15
- if (from && typeof from === "object" || typeof from === "function") {
16
- for (var key of __getOwnPropNames(from))
17
- if (!__hasOwnProp.call(entry, key))
18
- __defProp(entry, key, {
19
- get: __accessProp.bind(from, key),
20
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
- });
22
- }
13
+ if (from && typeof from === "object" || typeof from === "function")
14
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ }));
23
18
  __moduleCache.set(from, entry);
24
19
  return entry;
25
20
  };
26
- var __moduleCache;
27
- var __returnValue = (v) => v;
28
- function __exportSetter(name, newValue) {
29
- this[name] = __returnValue.bind(null, newValue);
30
- }
31
21
  var __export = (target, all) => {
32
22
  for (var name in all)
33
23
  __defProp(target, name, {
34
24
  get: all[name],
35
25
  enumerable: true,
36
26
  configurable: true,
37
- set: __exportSetter.bind(all, name)
27
+ set: (newValue) => all[name] = () => newValue
38
28
  });
39
29
  };
40
30
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
41
31
 
42
- // node_modules/@hasna/cloud/dist/index.js
32
+ // ../../../../node_modules/@hasna/cloud/dist/index.js
43
33
  import { createRequire } from "module";
44
34
  import { Database } from "bun:sqlite";
45
35
  import {
@@ -60,11 +50,11 @@ import { homedir as homedir4 } from "os";
60
50
  import { join as join4 } from "path";
61
51
  import { join as join6, dirname } from "path";
62
52
  import { homedir as homedir5, platform } from "os";
63
- function __accessProp2(key) {
53
+ function __accessProp(key) {
64
54
  return this[key];
65
55
  }
66
- function __exportSetter2(name, newValue) {
67
- this[name] = __returnValue2.bind(null, newValue);
56
+ function __exportSetter(name, newValue) {
57
+ this[name] = __returnValue.bind(null, newValue);
68
58
  }
69
59
  function translateSql(sql, dialect) {
70
60
  if (dialect === "sqlite")
@@ -1107,19 +1097,19 @@ var __create, __getProtoOf, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toE
1107
1097
  for (let key of __getOwnPropNames2(mod))
1108
1098
  if (!__hasOwnProp2.call(to, key))
1109
1099
  __defProp2(to, key, {
1110
- get: __accessProp2.bind(mod, key),
1100
+ get: __accessProp.bind(mod, key),
1111
1101
  enumerable: true
1112
1102
  });
1113
1103
  if (canCache)
1114
1104
  cache.set(mod, to);
1115
1105
  return to;
1116
- }, __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
1106
+ }, __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
1117
1107
  for (var name in all)
1118
1108
  __defProp2(target, name, {
1119
1109
  get: all[name],
1120
1110
  enumerable: true,
1121
1111
  configurable: true,
1122
- set: __exportSetter2.bind(all, name)
1112
+ set: __exportSetter.bind(all, name)
1123
1113
  });
1124
1114
  }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util, objectUtil, ZodParsedType, getParsedType = (data) => {
1125
1115
  const t = typeof data;
package/bin/index.js CHANGED
@@ -6,60 +6,39 @@ var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- function __accessProp(key) {
10
- return this[key];
11
- }
12
- var __toESMCache_node;
13
- var __toESMCache_esm;
14
9
  var __toESM = (mod, isNodeMode, target) => {
15
- var canCache = mod != null && typeof mod === "object";
16
- if (canCache) {
17
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
- var cached = cache.get(mod);
19
- if (cached)
20
- return cached;
21
- }
22
10
  target = mod != null ? __create(__getProtoOf(mod)) : {};
23
11
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
24
12
  for (let key of __getOwnPropNames(mod))
25
13
  if (!__hasOwnProp.call(to, key))
26
14
  __defProp(to, key, {
27
- get: __accessProp.bind(mod, key),
15
+ get: () => mod[key],
28
16
  enumerable: true
29
17
  });
30
- if (canCache)
31
- cache.set(mod, to);
32
18
  return to;
33
19
  };
20
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
34
21
  var __toCommonJS = (from) => {
35
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
22
+ var entry = __moduleCache.get(from), desc;
36
23
  if (entry)
37
24
  return entry;
38
25
  entry = __defProp({}, "__esModule", { value: true });
39
- if (from && typeof from === "object" || typeof from === "function") {
40
- for (var key of __getOwnPropNames(from))
41
- if (!__hasOwnProp.call(entry, key))
42
- __defProp(entry, key, {
43
- get: __accessProp.bind(from, key),
44
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
45
- });
46
- }
26
+ if (from && typeof from === "object" || typeof from === "function")
27
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
28
+ get: () => from[key],
29
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
+ }));
47
31
  __moduleCache.set(from, entry);
48
32
  return entry;
49
33
  };
50
- var __moduleCache;
51
34
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
52
- var __returnValue = (v) => v;
53
- function __exportSetter(name, newValue) {
54
- this[name] = __returnValue.bind(null, newValue);
55
- }
56
35
  var __export = (target, all) => {
57
36
  for (var name in all)
58
37
  __defProp(target, name, {
59
38
  get: all[name],
60
39
  enumerable: true,
61
40
  configurable: true,
62
- set: __exportSetter.bind(all, name)
41
+ set: (newValue) => all[name] = () => newValue
63
42
  });
64
43
  };
65
44
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -2256,7 +2235,7 @@ var init_names = __esm(() => {
2256
2235
  ];
2257
2236
  });
2258
2237
 
2259
- // node_modules/@hasna/cloud/dist/index.js
2238
+ // ../../../../node_modules/@hasna/cloud/dist/index.js
2260
2239
  var exports_dist = {};
2261
2240
  __export(exports_dist, {
2262
2241
  translateSql: () => translateSql,
@@ -2351,11 +2330,11 @@ import { join as join5 } from "path";
2351
2330
  import { join as join6, dirname } from "path";
2352
2331
  import { existsSync as existsSync6, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
2353
2332
  import { homedir as homedir5, platform } from "os";
2354
- function __accessProp2(key) {
2333
+ function __accessProp(key) {
2355
2334
  return this[key];
2356
2335
  }
2357
- function __exportSetter2(name, newValue) {
2358
- this[name] = __returnValue2.bind(null, newValue);
2336
+ function __exportSetter(name, newValue) {
2337
+ this[name] = __returnValue.bind(null, newValue);
2359
2338
  }
2360
2339
  function translateSql(sql, dialect) {
2361
2340
  if (dialect === "sqlite")
@@ -3668,9 +3647,9 @@ async function syncTransfer(source, target, options, _direction) {
3668
3647
  const batch = rows.slice(offset, offset + batchSize);
3669
3648
  try {
3670
3649
  if (isAsyncAdapter(target)) {
3671
- await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
3650
+ await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
3672
3651
  } else {
3673
- batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
3652
+ batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
3674
3653
  }
3675
3654
  result.rowsWritten += batch.length;
3676
3655
  } catch (err) {
@@ -3717,7 +3696,7 @@ async function syncTransfer(source, target, options, _direction) {
3717
3696
  }
3718
3697
  return results;
3719
3698
  }
3720
- async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
3699
+ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
3721
3700
  if (batch.length === 0)
3722
3701
  return;
3723
3702
  const colList = columns.map((c) => `"${c}"`).join(", ");
@@ -3727,20 +3706,22 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
3727
3706
  }).join(", ");
3728
3707
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
3729
3708
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
3709
+ const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
3730
3710
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
3731
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
3711
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
3732
3712
  const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
3733
3713
  await target.run(sql, ...params);
3734
3714
  }
3735
- function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
3715
+ function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
3736
3716
  if (batch.length === 0)
3737
3717
  return;
3738
3718
  const colList = columns.map((c) => `"${c}"`).join(", ");
3739
3719
  const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
3740
3720
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
3741
3721
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
3722
+ const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
3742
3723
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
3743
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
3724
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
3744
3725
  const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
3745
3726
  target.run(sql, ...params);
3746
3727
  }
@@ -4810,7 +4791,7 @@ async function ensureAllPgDatabases() {
4810
4791
  }
4811
4792
  return results;
4812
4793
  }
4813
- function registerCloudTools(server, serviceName) {
4794
+ function registerCloudTools(server, serviceName, opts = {}) {
4814
4795
  server.tool(`${serviceName}_cloud_status`, "Show cloud configuration and connection health", {}, async () => {
4815
4796
  const config = getCloudConfig();
4816
4797
  const lines = [
@@ -4843,8 +4824,13 @@ function registerCloudTools(server, serviceName) {
4843
4824
  isError: true
4844
4825
  };
4845
4826
  }
4846
- const local = new SqliteAdapter(getDbPath(serviceName));
4827
+ const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
4847
4828
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
4829
+ if (opts.migrations?.length) {
4830
+ for (const sql of opts.migrations) {
4831
+ await cloud.run(sql);
4832
+ }
4833
+ }
4848
4834
  const tableList = tablesStr ? tablesStr.split(",").map((t) => t.trim()) : listSqliteTables(local);
4849
4835
  const results = await syncPush(local, cloud, { tables: tableList });
4850
4836
  local.close();
@@ -4866,7 +4852,7 @@ function registerCloudTools(server, serviceName) {
4866
4852
  isError: true
4867
4853
  };
4868
4854
  }
4869
- const local = new SqliteAdapter(getDbPath(serviceName));
4855
+ const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
4870
4856
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
4871
4857
  let tableList;
4872
4858
  if (tablesStr) {
@@ -4989,10 +4975,10 @@ function registerCloudCommands(program2, serviceName) {
4989
4975
  }
4990
4976
  });
4991
4977
  }
4992
- var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node2, __toESMCache_esm2, __toESM2 = (mod, isNodeMode, target) => {
4978
+ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node, __toESMCache_esm, __toESM2 = (mod, isNodeMode, target) => {
4993
4979
  var canCache = mod != null && typeof mod === "object";
4994
4980
  if (canCache) {
4995
- var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
4981
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
4996
4982
  var cached = cache.get(mod);
4997
4983
  if (cached)
4998
4984
  return cached;
@@ -5002,19 +4988,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
5002
4988
  for (let key of __getOwnPropNames2(mod))
5003
4989
  if (!__hasOwnProp2.call(to, key))
5004
4990
  __defProp2(to, key, {
5005
- get: __accessProp2.bind(mod, key),
4991
+ get: __accessProp.bind(mod, key),
5006
4992
  enumerable: true
5007
4993
  });
5008
4994
  if (canCache)
5009
4995
  cache.set(mod, to);
5010
4996
  return to;
5011
- }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
4997
+ }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
5012
4998
  for (var name in all)
5013
4999
  __defProp2(target, name, {
5014
5000
  get: all[name],
5015
5001
  enumerable: true,
5016
5002
  configurable: true,
5017
- set: __exportSetter2.bind(all, name)
5003
+ set: __exportSetter.bind(all, name)
5018
5004
  });
5019
5005
  }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require2, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util, objectUtil, ZodParsedType, getParsedType = (data) => {
5020
5006
  const t = typeof data;
@@ -14928,7 +14914,7 @@ var init_presence = __esm(() => {
14928
14914
  var require_package = __commonJS((exports, module) => {
14929
14915
  module.exports = {
14930
14916
  name: "@hasna/conversations",
14931
- version: "0.2.34",
14917
+ version: "0.2.35",
14932
14918
  description: "Real-time CLI messaging for AI agents",
14933
14919
  type: "module",
14934
14920
  bin: {
@@ -43146,7 +43132,7 @@ var require_formats = __commonJS((exports) => {
43146
43132
  }
43147
43133
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
43148
43134
  function getTime(strictTimeZone) {
43149
- return function time3(str) {
43135
+ return function time(str) {
43150
43136
  const matches = TIME.exec(str);
43151
43137
  if (!matches)
43152
43138
  return false;
@@ -44725,25 +44711,49 @@ var init_stdio2 = __esm(() => {
44725
44711
  // src/mcp/tools/messaging.ts
44726
44712
  function registerMessagingTools(server, resolveProjectId) {
44727
44713
  server.registerTool("send_message", {
44728
- description: "Send a DM to an agent.",
44714
+ 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.",
44729
44715
  inputSchema: {
44730
- to: exports_external2.string(),
44716
+ to: exports_external2.string().describe("Agent name to send to, OR use target_session_id instead for session targeting"),
44731
44717
  content: exports_external2.string(),
44732
44718
  from: exports_external2.string().optional(),
44733
44719
  priority: exports_external2.string().optional(),
44734
44720
  blocking: exports_external2.coerce.boolean().optional(),
44735
- project_id: exports_external2.string().optional()
44721
+ project_id: exports_external2.string().optional(),
44722
+ target_session_id: exports_external2.string().optional().describe("If provided, sends to a specific agent-claude session ID (UUID). The message auto-injects into that session's conversation.")
44736
44723
  }
44737
44724
  }, async (args) => {
44738
- const { from: fromParam, to, content, priority, blocking, project_id } = args;
44725
+ const { from: fromParam, to, content, priority, blocking, project_id, target_session_id } = args;
44739
44726
  const from = resolveIdentity(fromParam);
44740
44727
  const msg = sendMessage({
44741
44728
  from,
44742
- to,
44729
+ to: target_session_id ? `session:${target_session_id}` : to,
44743
44730
  content,
44744
44731
  priority,
44745
44732
  blocking,
44746
- project_id
44733
+ project_id,
44734
+ metadata: target_session_id ? { target_session_id } : undefined
44735
+ });
44736
+ return {
44737
+ content: [{ type: "text", text: JSON.stringify(msg) }]
44738
+ };
44739
+ });
44740
+ server.registerTool("send_to_session", {
44741
+ description: "Send a message to a specific agent-claude session by its session ID. The message will be auto-injected into that session's conversation via the channel bridge.",
44742
+ inputSchema: {
44743
+ target_session_id: exports_external2.string().describe("The agent-claude session ID (UUID) to send the message to"),
44744
+ content: exports_external2.string().describe("Message content to inject into the target session"),
44745
+ from: exports_external2.string().optional().describe("Sender agent name (defaults to CONVERSATIONS_AGENT_ID)"),
44746
+ priority: exports_external2.string().optional()
44747
+ }
44748
+ }, async (args) => {
44749
+ const { target_session_id, content, from: fromParam, priority } = args;
44750
+ const from = resolveIdentity(fromParam);
44751
+ const msg = sendMessage({
44752
+ from,
44753
+ to: `session:${target_session_id}`,
44754
+ content,
44755
+ priority,
44756
+ metadata: { target_session_id }
44747
44757
  });
44748
44758
  return {
44749
44759
  content: [{ type: "text", text: JSON.stringify(msg) }]
@@ -46918,55 +46928,73 @@ var init_cloud = __esm(() => {
46918
46928
  });
46919
46929
 
46920
46930
  // src/mcp/channel.ts
46921
- function registerChannelBridge(server, getAgentId) {
46931
+ function registerChannelBridge(server, getAgentId, getSessionId) {
46922
46932
  server.server.registerCapabilities({
46923
46933
  experimental: {
46924
46934
  "claude/channel": {}
46925
46935
  }
46926
46936
  });
46927
46937
  let lastSeenId = 0;
46938
+ let lastSeenSessionId = 0;
46928
46939
  let pollTimer = null;
46929
- function seedLastSeen(agentId) {
46930
- const latest = readMessages({
46931
- to: agentId,
46932
- order: "desc",
46933
- limit: 1
46940
+ function seedLastSeen(agentId, sessionId) {
46941
+ const latestAgent = readMessages({ to: agentId, order: "desc", limit: 1 });
46942
+ if (latestAgent.length > 0)
46943
+ lastSeenId = latestAgent[0].id;
46944
+ if (sessionId) {
46945
+ const latestSession = readMessages({ to: `session:${sessionId}`, order: "desc", limit: 1 });
46946
+ if (latestSession.length > 0)
46947
+ lastSeenSessionId = latestSession[0].id;
46948
+ }
46949
+ }
46950
+ function pushNotification(msg) {
46951
+ server.server.notification({
46952
+ method: "notifications/claude/channel",
46953
+ params: {
46954
+ content: msg.content,
46955
+ meta: {
46956
+ from: msg.from_agent,
46957
+ session_id: msg.session_id,
46958
+ ...msg.space ? { space: msg.space } : {},
46959
+ ...msg.priority && msg.priority !== "normal" ? { priority: msg.priority } : {}
46960
+ }
46961
+ }
46934
46962
  });
46935
- if (latest.length > 0) {
46936
- lastSeenId = latest[0].id;
46937
- }
46938
46963
  }
46939
46964
  function startPolling2() {
46940
46965
  if (pollTimer)
46941
46966
  return;
46942
46967
  const agentId = getAgentId();
46943
- if (!agentId)
46968
+ const sessionId = getSessionId();
46969
+ if (!agentId && !sessionId)
46944
46970
  return;
46945
- seedLastSeen(agentId);
46971
+ if (agentId)
46972
+ seedLastSeen(agentId, sessionId);
46946
46973
  pollTimer = setInterval(() => {
46947
- const currentAgent = getAgentId();
46948
- if (!currentAgent)
46949
- return;
46950
46974
  try {
46951
- const newMessages = readMessages({
46952
- to: currentAgent,
46953
- order: "asc",
46954
- limit: 20
46955
- }).filter((m) => m.id > lastSeenId);
46956
- for (const msg of newMessages) {
46957
- lastSeenId = msg.id;
46958
- server.server.notification({
46959
- method: "notifications/claude/channel",
46960
- params: {
46961
- content: msg.content,
46962
- meta: {
46963
- from: msg.from_agent,
46964
- session_id: msg.session_id,
46965
- ...msg.space ? { space: msg.space } : {},
46966
- ...msg.priority !== "normal" ? { priority: msg.priority } : {}
46967
- }
46968
- }
46969
- });
46975
+ const currentAgent = getAgentId();
46976
+ const currentSession = getSessionId();
46977
+ if (currentAgent) {
46978
+ const newAgentMsgs = readMessages({
46979
+ to: currentAgent,
46980
+ order: "asc",
46981
+ limit: 20
46982
+ }).filter((m) => m.id > lastSeenId);
46983
+ for (const msg of newAgentMsgs) {
46984
+ lastSeenId = msg.id;
46985
+ pushNotification(msg);
46986
+ }
46987
+ }
46988
+ if (currentSession) {
46989
+ const newSessionMsgs = readMessages({
46990
+ to: `session:${currentSession}`,
46991
+ order: "asc",
46992
+ limit: 20
46993
+ }).filter((m) => m.id > lastSeenSessionId);
46994
+ for (const msg of newSessionMsgs) {
46995
+ lastSeenSessionId = msg.id;
46996
+ pushNotification(msg);
46997
+ }
46970
46998
  }
46971
46999
  } catch {}
46972
47000
  }, POLL_INTERVAL_MS);
@@ -47131,7 +47159,7 @@ var init_mcp2 = __esm(() => {
47131
47159
  registerAgentTools(server, agentFocus, getAgentFocus);
47132
47160
  registerAdvancedTools(server, import__package2.default.version);
47133
47161
  registerTmuxTools(server);
47134
- registerChannelBridge(server, () => process.env.CONVERSATIONS_AGENT_ID ?? null);
47162
+ registerChannelBridge(server, () => process.env.CONVERSATIONS_AGENT_ID ?? null, () => process.env.CONVERSATIONS_SESSION_ID ?? null);
47135
47163
  isDirectRun = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("mcp.js") || process.argv[1]?.endsWith("mcp.ts");
47136
47164
  if (isDirectRun) {
47137
47165
  startMcpServer().catch((error48) => {
package/bin/mcp.js CHANGED
@@ -6,60 +6,39 @@ var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- function __accessProp(key) {
10
- return this[key];
11
- }
12
- var __toESMCache_node;
13
- var __toESMCache_esm;
14
9
  var __toESM = (mod, isNodeMode, target) => {
15
- var canCache = mod != null && typeof mod === "object";
16
- if (canCache) {
17
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
- var cached = cache.get(mod);
19
- if (cached)
20
- return cached;
21
- }
22
10
  target = mod != null ? __create(__getProtoOf(mod)) : {};
23
11
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
24
12
  for (let key of __getOwnPropNames(mod))
25
13
  if (!__hasOwnProp.call(to, key))
26
14
  __defProp(to, key, {
27
- get: __accessProp.bind(mod, key),
15
+ get: () => mod[key],
28
16
  enumerable: true
29
17
  });
30
- if (canCache)
31
- cache.set(mod, to);
32
18
  return to;
33
19
  };
20
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
34
21
  var __toCommonJS = (from) => {
35
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
22
+ var entry = __moduleCache.get(from), desc;
36
23
  if (entry)
37
24
  return entry;
38
25
  entry = __defProp({}, "__esModule", { value: true });
39
- if (from && typeof from === "object" || typeof from === "function") {
40
- for (var key of __getOwnPropNames(from))
41
- if (!__hasOwnProp.call(entry, key))
42
- __defProp(entry, key, {
43
- get: __accessProp.bind(from, key),
44
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
45
- });
46
- }
26
+ if (from && typeof from === "object" || typeof from === "function")
27
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
28
+ get: () => from[key],
29
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
+ }));
47
31
  __moduleCache.set(from, entry);
48
32
  return entry;
49
33
  };
50
- var __moduleCache;
51
34
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
52
- var __returnValue = (v) => v;
53
- function __exportSetter(name, newValue) {
54
- this[name] = __returnValue.bind(null, newValue);
55
- }
56
35
  var __export = (target, all) => {
57
36
  for (var name in all)
58
37
  __defProp(target, name, {
59
38
  get: all[name],
60
39
  enumerable: true,
61
40
  configurable: true,
62
- set: __exportSetter.bind(all, name)
41
+ set: (newValue) => all[name] = () => newValue
63
42
  });
64
43
  };
65
44
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -6323,7 +6302,7 @@ var require_formats = __commonJS((exports) => {
6323
6302
  }
6324
6303
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6325
6304
  function getTime(strictTimeZone) {
6326
- return function time3(str) {
6305
+ return function time(str) {
6327
6306
  const matches = TIME.exec(str);
6328
6307
  if (!matches)
6329
6308
  return false;
@@ -6536,7 +6515,7 @@ var require_dist = __commonJS((exports, module) => {
6536
6515
  exports.default = formatsPlugin;
6537
6516
  });
6538
6517
 
6539
- // node_modules/@hasna/cloud/dist/index.js
6518
+ // ../../../../node_modules/@hasna/cloud/dist/index.js
6540
6519
  var exports_dist = {};
6541
6520
  __export(exports_dist, {
6542
6521
  translateSql: () => translateSql,
@@ -6631,11 +6610,11 @@ import { join as join5 } from "path";
6631
6610
  import { join as join6, dirname } from "path";
6632
6611
  import { existsSync as existsSync6, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
6633
6612
  import { homedir as homedir5, platform } from "os";
6634
- function __accessProp2(key) {
6613
+ function __accessProp(key) {
6635
6614
  return this[key];
6636
6615
  }
6637
- function __exportSetter2(name, newValue) {
6638
- this[name] = __returnValue2.bind(null, newValue);
6616
+ function __exportSetter(name, newValue) {
6617
+ this[name] = __returnValue.bind(null, newValue);
6639
6618
  }
6640
6619
  function translateSql(sql, dialect) {
6641
6620
  if (dialect === "sqlite")
@@ -7948,9 +7927,9 @@ async function syncTransfer(source, target, options, _direction) {
7948
7927
  const batch = rows.slice(offset, offset + batchSize);
7949
7928
  try {
7950
7929
  if (isAsyncAdapter(target)) {
7951
- await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
7930
+ await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
7952
7931
  } else {
7953
- batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
7932
+ batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
7954
7933
  }
7955
7934
  result.rowsWritten += batch.length;
7956
7935
  } catch (err) {
@@ -7997,7 +7976,7 @@ async function syncTransfer(source, target, options, _direction) {
7997
7976
  }
7998
7977
  return results;
7999
7978
  }
8000
- async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
7979
+ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
8001
7980
  if (batch.length === 0)
8002
7981
  return;
8003
7982
  const colList = columns.map((c) => `"${c}"`).join(", ");
@@ -8007,20 +7986,22 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
8007
7986
  }).join(", ");
8008
7987
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
8009
7988
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
7989
+ const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
8010
7990
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
8011
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
7991
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
8012
7992
  const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
8013
7993
  await target.run(sql, ...params);
8014
7994
  }
8015
- function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
7995
+ function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
8016
7996
  if (batch.length === 0)
8017
7997
  return;
8018
7998
  const colList = columns.map((c) => `"${c}"`).join(", ");
8019
7999
  const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
8020
8000
  const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
8021
8001
  const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
8002
+ const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
8022
8003
  const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
8023
- ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
8004
+ ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
8024
8005
  const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
8025
8006
  target.run(sql, ...params);
8026
8007
  }
@@ -9090,7 +9071,7 @@ async function ensureAllPgDatabases() {
9090
9071
  }
9091
9072
  return results;
9092
9073
  }
9093
- function registerCloudTools(server, serviceName) {
9074
+ function registerCloudTools(server, serviceName, opts = {}) {
9094
9075
  server.tool(`${serviceName}_cloud_status`, "Show cloud configuration and connection health", {}, async () => {
9095
9076
  const config2 = getCloudConfig();
9096
9077
  const lines = [
@@ -9123,8 +9104,13 @@ function registerCloudTools(server, serviceName) {
9123
9104
  isError: true
9124
9105
  };
9125
9106
  }
9126
- const local = new SqliteAdapter(getDbPath(serviceName));
9107
+ const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
9127
9108
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
9109
+ if (opts.migrations?.length) {
9110
+ for (const sql of opts.migrations) {
9111
+ await cloud.run(sql);
9112
+ }
9113
+ }
9128
9114
  const tableList = tablesStr ? tablesStr.split(",").map((t) => t.trim()) : listSqliteTables(local);
9129
9115
  const results = await syncPush(local, cloud, { tables: tableList });
9130
9116
  local.close();
@@ -9146,7 +9132,7 @@ function registerCloudTools(server, serviceName) {
9146
9132
  isError: true
9147
9133
  };
9148
9134
  }
9149
- const local = new SqliteAdapter(getDbPath(serviceName));
9135
+ const local = new SqliteAdapter(opts.dbPath ?? getDbPath(serviceName));
9150
9136
  const cloud = new PgAdapterAsync(getConnectionString(serviceName));
9151
9137
  let tableList;
9152
9138
  if (tablesStr) {
@@ -9269,10 +9255,10 @@ function registerCloudCommands(program, serviceName) {
9269
9255
  }
9270
9256
  });
9271
9257
  }
9272
- var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node2, __toESMCache_esm2, __toESM2 = (mod, isNodeMode, target) => {
9258
+ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node, __toESMCache_esm, __toESM2 = (mod, isNodeMode, target) => {
9273
9259
  var canCache = mod != null && typeof mod === "object";
9274
9260
  if (canCache) {
9275
- var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
9261
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
9276
9262
  var cached2 = cache.get(mod);
9277
9263
  if (cached2)
9278
9264
  return cached2;
@@ -9282,19 +9268,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
9282
9268
  for (let key of __getOwnPropNames2(mod))
9283
9269
  if (!__hasOwnProp2.call(to, key))
9284
9270
  __defProp2(to, key, {
9285
- get: __accessProp2.bind(mod, key),
9271
+ get: __accessProp.bind(mod, key),
9286
9272
  enumerable: true
9287
9273
  });
9288
9274
  if (canCache)
9289
9275
  cache.set(mod, to);
9290
9276
  return to;
9291
- }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
9277
+ }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
9292
9278
  for (var name in all)
9293
9279
  __defProp2(target, name, {
9294
9280
  get: all[name],
9295
9281
  enumerable: true,
9296
9282
  configurable: true,
9297
- set: __exportSetter2.bind(all, name)
9283
+ set: __exportSetter.bind(all, name)
9298
9284
  });
9299
9285
  }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults2, require_utils2, require_utils_legacy, require_utils_webcrypto, require_utils22, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist2, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util2, objectUtil2, ZodParsedType2, getParsedType3 = (data) => {
9300
9286
  const t = typeof data;
@@ -41221,25 +41207,49 @@ function updateCachedAutoName(newName) {
41221
41207
  // src/mcp/tools/messaging.ts
41222
41208
  function registerMessagingTools(server, resolveProjectId) {
41223
41209
  server.registerTool("send_message", {
41224
- description: "Send a DM to an agent.",
41210
+ 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.",
41225
41211
  inputSchema: {
41226
- to: exports_external.string(),
41212
+ to: exports_external.string().describe("Agent name to send to, OR use target_session_id instead for session targeting"),
41227
41213
  content: exports_external.string(),
41228
41214
  from: exports_external.string().optional(),
41229
41215
  priority: exports_external.string().optional(),
41230
41216
  blocking: exports_external.coerce.boolean().optional(),
41231
- project_id: exports_external.string().optional()
41217
+ project_id: exports_external.string().optional(),
41218
+ target_session_id: exports_external.string().optional().describe("If provided, sends to a specific agent-claude session ID (UUID). The message auto-injects into that session's conversation.")
41232
41219
  }
41233
41220
  }, async (args) => {
41234
- const { from: fromParam, to, content, priority, blocking, project_id } = args;
41221
+ const { from: fromParam, to, content, priority, blocking, project_id, target_session_id } = args;
41235
41222
  const from = resolveIdentity(fromParam);
41236
41223
  const msg = sendMessage({
41237
41224
  from,
41238
- to,
41225
+ to: target_session_id ? `session:${target_session_id}` : to,
41239
41226
  content,
41240
41227
  priority,
41241
41228
  blocking,
41242
- project_id
41229
+ project_id,
41230
+ metadata: target_session_id ? { target_session_id } : undefined
41231
+ });
41232
+ return {
41233
+ content: [{ type: "text", text: JSON.stringify(msg) }]
41234
+ };
41235
+ });
41236
+ server.registerTool("send_to_session", {
41237
+ description: "Send a message to a specific agent-claude session by its session ID. The message will be auto-injected into that session's conversation via the channel bridge.",
41238
+ inputSchema: {
41239
+ target_session_id: exports_external.string().describe("The agent-claude session ID (UUID) to send the message to"),
41240
+ content: exports_external.string().describe("Message content to inject into the target session"),
41241
+ from: exports_external.string().optional().describe("Sender agent name (defaults to CONVERSATIONS_AGENT_ID)"),
41242
+ priority: exports_external.string().optional()
41243
+ }
41244
+ }, async (args) => {
41245
+ const { target_session_id, content, from: fromParam, priority } = args;
41246
+ const from = resolveIdentity(fromParam);
41247
+ const msg = sendMessage({
41248
+ from,
41249
+ to: `session:${target_session_id}`,
41250
+ content,
41251
+ priority,
41252
+ metadata: { target_session_id }
41243
41253
  });
41244
41254
  return {
41245
41255
  content: [{ type: "text", text: JSON.stringify(msg) }]
@@ -44065,55 +44075,73 @@ function formatError2(e) {
44065
44075
 
44066
44076
  // src/mcp/channel.ts
44067
44077
  var POLL_INTERVAL_MS = 1000;
44068
- function registerChannelBridge(server, getAgentId) {
44078
+ function registerChannelBridge(server, getAgentId, getSessionId) {
44069
44079
  server.server.registerCapabilities({
44070
44080
  experimental: {
44071
44081
  "claude/channel": {}
44072
44082
  }
44073
44083
  });
44074
44084
  let lastSeenId = 0;
44085
+ let lastSeenSessionId = 0;
44075
44086
  let pollTimer = null;
44076
- function seedLastSeen(agentId) {
44077
- const latest = readMessages({
44078
- to: agentId,
44079
- order: "desc",
44080
- limit: 1
44087
+ function seedLastSeen(agentId, sessionId) {
44088
+ const latestAgent = readMessages({ to: agentId, order: "desc", limit: 1 });
44089
+ if (latestAgent.length > 0)
44090
+ lastSeenId = latestAgent[0].id;
44091
+ if (sessionId) {
44092
+ const latestSession = readMessages({ to: `session:${sessionId}`, order: "desc", limit: 1 });
44093
+ if (latestSession.length > 0)
44094
+ lastSeenSessionId = latestSession[0].id;
44095
+ }
44096
+ }
44097
+ function pushNotification(msg) {
44098
+ server.server.notification({
44099
+ method: "notifications/claude/channel",
44100
+ params: {
44101
+ content: msg.content,
44102
+ meta: {
44103
+ from: msg.from_agent,
44104
+ session_id: msg.session_id,
44105
+ ...msg.space ? { space: msg.space } : {},
44106
+ ...msg.priority && msg.priority !== "normal" ? { priority: msg.priority } : {}
44107
+ }
44108
+ }
44081
44109
  });
44082
- if (latest.length > 0) {
44083
- lastSeenId = latest[0].id;
44084
- }
44085
44110
  }
44086
44111
  function startPolling() {
44087
44112
  if (pollTimer)
44088
44113
  return;
44089
44114
  const agentId = getAgentId();
44090
- if (!agentId)
44115
+ const sessionId = getSessionId();
44116
+ if (!agentId && !sessionId)
44091
44117
  return;
44092
- seedLastSeen(agentId);
44118
+ if (agentId)
44119
+ seedLastSeen(agentId, sessionId);
44093
44120
  pollTimer = setInterval(() => {
44094
- const currentAgent = getAgentId();
44095
- if (!currentAgent)
44096
- return;
44097
44121
  try {
44098
- const newMessages = readMessages({
44099
- to: currentAgent,
44100
- order: "asc",
44101
- limit: 20
44102
- }).filter((m) => m.id > lastSeenId);
44103
- for (const msg of newMessages) {
44104
- lastSeenId = msg.id;
44105
- server.server.notification({
44106
- method: "notifications/claude/channel",
44107
- params: {
44108
- content: msg.content,
44109
- meta: {
44110
- from: msg.from_agent,
44111
- session_id: msg.session_id,
44112
- ...msg.space ? { space: msg.space } : {},
44113
- ...msg.priority !== "normal" ? { priority: msg.priority } : {}
44114
- }
44115
- }
44116
- });
44122
+ const currentAgent = getAgentId();
44123
+ const currentSession = getSessionId();
44124
+ if (currentAgent) {
44125
+ const newAgentMsgs = readMessages({
44126
+ to: currentAgent,
44127
+ order: "asc",
44128
+ limit: 20
44129
+ }).filter((m) => m.id > lastSeenId);
44130
+ for (const msg of newAgentMsgs) {
44131
+ lastSeenId = msg.id;
44132
+ pushNotification(msg);
44133
+ }
44134
+ }
44135
+ if (currentSession) {
44136
+ const newSessionMsgs = readMessages({
44137
+ to: `session:${currentSession}`,
44138
+ order: "asc",
44139
+ limit: 20
44140
+ }).filter((m) => m.id > lastSeenSessionId);
44141
+ for (const msg of newSessionMsgs) {
44142
+ lastSeenSessionId = msg.id;
44143
+ pushNotification(msg);
44144
+ }
44117
44145
  }
44118
44146
  } catch {}
44119
44147
  }, POLL_INTERVAL_MS);
@@ -44269,7 +44297,7 @@ function registerTmuxTools(server) {
44269
44297
  // package.json
44270
44298
  var package_default = {
44271
44299
  name: "@hasna/conversations",
44272
- version: "0.2.34",
44300
+ version: "0.2.35",
44273
44301
  description: "Real-time CLI messaging for AI agents",
44274
44302
  type: "module",
44275
44303
  bin: {
@@ -44372,7 +44400,7 @@ registerProjectTools(server);
44372
44400
  registerAgentTools(server, agentFocus, getAgentFocus);
44373
44401
  registerAdvancedTools(server, package_default.version);
44374
44402
  registerTmuxTools(server);
44375
- registerChannelBridge(server, () => process.env.CONVERSATIONS_AGENT_ID ?? null);
44403
+ registerChannelBridge(server, () => process.env.CONVERSATIONS_AGENT_ID ?? null, () => process.env.CONVERSATIONS_SESSION_ID ?? null);
44376
44404
  async function startMcpServer() {
44377
44405
  const transport = new StdioServerTransport;
44378
44406
  registerCloudSyncTools(server);
package/dist/index.js CHANGED
@@ -5,65 +5,44 @@ var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- function __accessProp(key) {
9
- return this[key];
10
- }
11
- var __toESMCache_node;
12
- var __toESMCache_esm;
13
8
  var __toESM = (mod, isNodeMode, target) => {
14
- var canCache = mod != null && typeof mod === "object";
15
- if (canCache) {
16
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
- var cached = cache.get(mod);
18
- if (cached)
19
- return cached;
20
- }
21
9
  target = mod != null ? __create(__getProtoOf(mod)) : {};
22
10
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
11
  for (let key of __getOwnPropNames(mod))
24
12
  if (!__hasOwnProp.call(to, key))
25
13
  __defProp(to, key, {
26
- get: __accessProp.bind(mod, key),
14
+ get: () => mod[key],
27
15
  enumerable: true
28
16
  });
29
- if (canCache)
30
- cache.set(mod, to);
31
17
  return to;
32
18
  };
19
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
33
20
  var __toCommonJS = (from) => {
34
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
21
+ var entry = __moduleCache.get(from), desc;
35
22
  if (entry)
36
23
  return entry;
37
24
  entry = __defProp({}, "__esModule", { value: true });
38
- if (from && typeof from === "object" || typeof from === "function") {
39
- for (var key of __getOwnPropNames(from))
40
- if (!__hasOwnProp.call(entry, key))
41
- __defProp(entry, key, {
42
- get: __accessProp.bind(from, key),
43
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
44
- });
45
- }
25
+ if (from && typeof from === "object" || typeof from === "function")
26
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
27
+ get: () => from[key],
28
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
+ }));
46
30
  __moduleCache.set(from, entry);
47
31
  return entry;
48
32
  };
49
- var __moduleCache;
50
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
51
- var __returnValue = (v) => v;
52
- function __exportSetter(name, newValue) {
53
- this[name] = __returnValue.bind(null, newValue);
54
- }
55
34
  var __export = (target, all) => {
56
35
  for (var name in all)
57
36
  __defProp(target, name, {
58
37
  get: all[name],
59
38
  enumerable: true,
60
39
  configurable: true,
61
- set: __exportSetter.bind(all, name)
40
+ set: (newValue) => all[name] = () => newValue
62
41
  });
63
42
  };
64
43
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
65
44
 
66
- // node_modules/@hasna/cloud/dist/index.js
45
+ // ../../../../node_modules/@hasna/cloud/dist/index.js
67
46
  import { createRequire } from "module";
68
47
  import { Database } from "bun:sqlite";
69
48
  import {
@@ -84,11 +63,11 @@ import { homedir as homedir4 } from "os";
84
63
  import { join as join4 } from "path";
85
64
  import { join as join6, dirname } from "path";
86
65
  import { homedir as homedir5, platform } from "os";
87
- function __accessProp2(key) {
66
+ function __accessProp(key) {
88
67
  return this[key];
89
68
  }
90
- function __exportSetter2(name, newValue) {
91
- this[name] = __returnValue2.bind(null, newValue);
69
+ function __exportSetter(name, newValue) {
70
+ this[name] = __returnValue.bind(null, newValue);
92
71
  }
93
72
  function translateSql(sql, dialect) {
94
73
  if (dialect === "sqlite")
@@ -1118,10 +1097,10 @@ class SyncProgressTracker {
1118
1097
  }
1119
1098
  }
1120
1099
  }
1121
- var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node2, __toESMCache_esm2, __toESM2 = (mod, isNodeMode, target) => {
1100
+ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node, __toESMCache_esm, __toESM2 = (mod, isNodeMode, target) => {
1122
1101
  var canCache = mod != null && typeof mod === "object";
1123
1102
  if (canCache) {
1124
- var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
1103
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
1125
1104
  var cached = cache.get(mod);
1126
1105
  if (cached)
1127
1106
  return cached;
@@ -1131,19 +1110,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
1131
1110
  for (let key of __getOwnPropNames2(mod))
1132
1111
  if (!__hasOwnProp2.call(to, key))
1133
1112
  __defProp2(to, key, {
1134
- get: __accessProp2.bind(mod, key),
1113
+ get: __accessProp.bind(mod, key),
1135
1114
  enumerable: true
1136
1115
  });
1137
1116
  if (canCache)
1138
1117
  cache.set(mod, to);
1139
1118
  return to;
1140
- }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
1119
+ }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
1141
1120
  for (var name in all)
1142
1121
  __defProp2(target, name, {
1143
1122
  get: all[name],
1144
1123
  enumerable: true,
1145
1124
  configurable: true,
1146
- set: __exportSetter2.bind(all, name)
1125
+ set: __exportSetter.bind(all, name)
1147
1126
  });
1148
1127
  }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util, objectUtil, ZodParsedType, getParsedType = (data) => {
1149
1128
  const t = typeof data;
@@ -1,17 +1,14 @@
1
1
  /**
2
2
  * Claude Code channel bridge for conversations MCP server.
3
3
  *
4
- * Declares `experimental['claude/channel']` capability so Claude Code
5
- * (and agent-claude) can use this server as a channel for inter-session
6
- * messaging. When enabled, polls for new DMs to the current agent and
7
- * pushes them as `notifications/claude/channel` events.
4
+ * Declares `experimental['claude/channel']` capability so agent-claude
5
+ * can use this server as a channel for inter-session messaging.
8
6
  *
9
- * Usage: Start agent-claude with:
10
- * agent-claude --channels server:conversations --dangerously-load-development-channels
7
+ * Polls for new messages addressed to:
8
+ * 1. The agent name (CONVERSATIONS_AGENT_ID) — standard DMs
9
+ * 2. The session ID (session:<uuid>) — targeted session injection via send_to_session
10
+ *
11
+ * Messages are pushed as `notifications/claude/channel` events.
11
12
  */
12
13
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
13
- /**
14
- * Register the claude/channel capability and start polling for
15
- * inbound messages to push as notifications.
16
- */
17
- export declare function registerChannelBridge(server: McpServer, getAgentId: () => string | null): void;
14
+ export declare function registerChannelBridge(server: McpServer, getAgentId: () => string | null, getSessionId: () => string | null): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.34",
3
+ "version": "0.2.35",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {