@hasna/conversations 0.2.50 → 0.2.51

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/README.md CHANGED
@@ -35,13 +35,13 @@ conversations-mcp
35
35
  Long-lived Streamable HTTP transport (stateless, bind `127.0.0.1` only):
36
36
 
37
37
  ```bash
38
- conversations-mcp --http # default port 8811
39
- conversations-mcp --http --port 8811
38
+ conversations-mcp --http # default port 8856
39
+ conversations-mcp --http --port 8856
40
40
  MCP_HTTP=1 conversations-mcp
41
41
  ```
42
42
 
43
- - Health: `GET http://127.0.0.1:8811/health`
44
- - MCP: `http://127.0.0.1:8811/mcp`
43
+ - Health: `GET http://127.0.0.1:8856/health`
44
+ - MCP: `http://127.0.0.1:8856/mcp`
45
45
 
46
46
  The dashboard server also exposes `/health` and `/mcp` when running.
47
47
 
package/bin/hook.js CHANGED
@@ -4,37 +4,27 @@ 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);
@@ -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;
@@ -9614,6 +9604,17 @@ function getDb() {
9614
9604
  read_at TEXT
9615
9605
  )
9616
9606
  `);
9607
+ const initialMsgCols = db.prepare("PRAGMA table_info(messages)").all();
9608
+ const initialMsgColNames = initialMsgCols.map((c) => c.name);
9609
+ if (initialMsgColNames.includes("channel") && !initialMsgColNames.includes("space")) {
9610
+ db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
9611
+ db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
9612
+ db.exec(`
9613
+ UPDATE messages
9614
+ SET session_id = 'space:' || substr(session_id, 9)
9615
+ WHERE session_id LIKE 'channel:%'
9616
+ `);
9617
+ }
9617
9618
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
9618
9619
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
9619
9620
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
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);
@@ -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;
@@ -13529,6 +13515,17 @@ function getDb() {
13529
13515
  read_at TEXT
13530
13516
  )
13531
13517
  `);
13518
+ const initialMsgCols = db.prepare("PRAGMA table_info(messages)").all();
13519
+ const initialMsgColNames = initialMsgCols.map((c) => c.name);
13520
+ if (initialMsgColNames.includes("channel") && !initialMsgColNames.includes("space")) {
13521
+ db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
13522
+ db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
13523
+ db.exec(`
13524
+ UPDATE messages
13525
+ SET session_id = 'space:' || substr(session_id, 9)
13526
+ WHERE session_id LIKE 'channel:%'
13527
+ `);
13528
+ }
13532
13529
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
13533
13530
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
13534
13531
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
@@ -15531,7 +15528,7 @@ var init_space_notifications = __esm(() => {
15531
15528
  var require_package = __commonJS((exports, module) => {
15532
15529
  module.exports = {
15533
15530
  name: "@hasna/conversations",
15534
- version: "0.2.50",
15531
+ version: "0.2.51",
15535
15532
  description: "Real-time CLI messaging for AI agents",
15536
15533
  type: "module",
15537
15534
  bin: {
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);
@@ -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;
@@ -17809,6 +17795,17 @@ function getDb() {
17809
17795
  read_at TEXT
17810
17796
  )
17811
17797
  `);
17798
+ const initialMsgCols = db.prepare("PRAGMA table_info(messages)").all();
17799
+ const initialMsgColNames = initialMsgCols.map((c) => c.name);
17800
+ if (initialMsgColNames.includes("channel") && !initialMsgColNames.includes("space")) {
17801
+ db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
17802
+ db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
17803
+ db.exec(`
17804
+ UPDATE messages
17805
+ SET session_id = 'space:' || substr(session_id, 9)
17806
+ WHERE session_id LIKE 'channel:%'
17807
+ `);
17808
+ }
17812
17809
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
17813
17810
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
17814
17811
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
@@ -46882,7 +46879,7 @@ function startMcpHttpServer(options) {
46882
46879
  // package.json
46883
46880
  var package_default = {
46884
46881
  name: "@hasna/conversations",
46885
- version: "0.2.50",
46882
+ version: "0.2.51",
46886
46883
  description: "Real-time CLI messaging for AI agents",
46887
46884
  type: "module",
46888
46885
  bin: {
package/dist/index.js CHANGED
@@ -5,60 +5,39 @@ 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);
@@ -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;
@@ -9638,6 +9617,17 @@ function getDb() {
9638
9617
  read_at TEXT
9639
9618
  )
9640
9619
  `);
9620
+ const initialMsgCols = db.prepare("PRAGMA table_info(messages)").all();
9621
+ const initialMsgColNames = initialMsgCols.map((c) => c.name);
9622
+ if (initialMsgColNames.includes("channel") && !initialMsgColNames.includes("space")) {
9623
+ db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
9624
+ db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
9625
+ db.exec(`
9626
+ UPDATE messages
9627
+ SET session_id = 'space:' || substr(session_id, 9)
9628
+ WHERE session_id LIKE 'channel:%'
9629
+ `);
9630
+ }
9641
9631
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
9642
9632
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
9643
9633
  db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.50",
3
+ "version": "0.2.51",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {