@hasna/conversations 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.js CHANGED
@@ -2806,6 +2806,14 @@ function markMentionsRead(agent, space) {
2806
2806
  const result = db2.prepare("UPDATE message_mentions SET notified_at = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE mentioned_agent = ? AND notified_at IS NULL").run(agent);
2807
2807
  return result.changes;
2808
2808
  }
2809
+ function markUnreadByIds(ids) {
2810
+ if (ids.length === 0)
2811
+ return 0;
2812
+ const db2 = getDb();
2813
+ const placeholders = ids.map(() => "?").join(",");
2814
+ const result = db2.prepare(`UPDATE messages SET read_at = NULL WHERE id IN (${placeholders})`).run(...ids);
2815
+ return result.changes;
2816
+ }
2809
2817
  var init_messages = __esm(() => {
2810
2818
  init_db();
2811
2819
  init_webhooks();
@@ -4445,7 +4453,7 @@ var init_poll = __esm(() => {
4445
4453
  var require_package = __commonJS((exports, module) => {
4446
4454
  module.exports = {
4447
4455
  name: "@hasna/conversations",
4448
- version: "0.2.13",
4456
+ version: "0.2.15",
4449
4457
  description: "Real-time CLI messaging for AI agents",
4450
4458
  type: "module",
4451
4459
  bin: {
@@ -33785,6 +33793,20 @@ var init_mcp2 = __esm(() => {
33785
33793
  content: [{ type: "text", text: JSON.stringify({ marked_read: count }) }]
33786
33794
  };
33787
33795
  });
33796
+ server.registerTool("mark_unread", {
33797
+ description: "Re-flag a message (or messages) as unread so it re-appears in read_messages(unread_only:true). Useful for bookmarking messages to action later.",
33798
+ inputSchema: {
33799
+ message_id: exports_external.coerce.number().optional().describe("Single message ID"),
33800
+ ids: exports_external.array(exports_external.coerce.number()).optional().describe("Multiple message IDs")
33801
+ }
33802
+ }, async (args) => {
33803
+ if (!args.message_id && (!args.ids || args.ids.length === 0)) {
33804
+ return { content: [{ type: "text", text: "Provide message_id or ids" }], isError: true };
33805
+ }
33806
+ const ids = args.ids ?? (args.message_id ? [args.message_id] : []);
33807
+ const count = markUnreadByIds(ids);
33808
+ return { content: [{ type: "text", text: JSON.stringify({ marked_unread: count }) }] };
33809
+ });
33788
33810
  server.registerTool("mark_space_read", {
33789
33811
  description: "Mark ALL messages in a space as read without fetching them. Use this on busy spaces (200+ messages) where read_messages would overflow tokens.",
33790
33812
  inputSchema: {
@@ -33892,6 +33914,31 @@ var init_mcp2 = __esm(() => {
33892
33914
  content: [{ type: "text", text: JSON.stringify(spaces) }]
33893
33915
  };
33894
33916
  });
33917
+ server.registerTool("broadcast", {
33918
+ description: "Send the same message to multiple spaces at once. Useful for status updates, bug reports, or announcements that need to go to several spaces.",
33919
+ inputSchema: {
33920
+ spaces: exports_external.array(exports_external.string()).describe("List of space names to send to"),
33921
+ content: exports_external.string().describe("Message content"),
33922
+ from: exports_external.string().optional().describe("Sender agent name"),
33923
+ priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional()
33924
+ }
33925
+ }, async (args) => {
33926
+ const { spaces, content, from: fromParam, priority } = args;
33927
+ const from = resolveIdentity(fromParam);
33928
+ const results = [];
33929
+ const errors4 = [];
33930
+ for (const space of spaces) {
33931
+ try {
33932
+ const msg = sendMessage({ from, to: space, content, space, priority });
33933
+ results.push({ space, id: msg.id });
33934
+ } catch (e) {
33935
+ errors4.push(`${space}: ${e instanceof Error ? e.message : String(e)}`);
33936
+ }
33937
+ }
33938
+ return {
33939
+ content: [{ type: "text", text: JSON.stringify({ sent: results, errors: errors4, total: results.length }) }]
33940
+ };
33941
+ });
33895
33942
  server.registerTool("list_unread_counts", {
33896
33943
  description: "Get unread message counts per space without fetching message content. Use this at session start to triage which spaces need attention before calling read_messages.",
33897
33944
  inputSchema: {
package/bin/mcp.js CHANGED
@@ -29309,6 +29309,14 @@ function markMentionsRead(agent, space) {
29309
29309
  const result = db2.prepare("UPDATE message_mentions SET notified_at = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE mentioned_agent = ? AND notified_at IS NULL").run(agent);
29310
29310
  return result.changes;
29311
29311
  }
29312
+ function markUnreadByIds(ids) {
29313
+ if (ids.length === 0)
29314
+ return 0;
29315
+ const db2 = getDb();
29316
+ const placeholders = ids.map(() => "?").join(",");
29317
+ const result = db2.prepare(`UPDATE messages SET read_at = NULL WHERE id IN (${placeholders})`).run(...ids);
29318
+ return result.changes;
29319
+ }
29312
29320
 
29313
29321
  // src/lib/sessions.ts
29314
29322
  init_db();
@@ -30935,7 +30943,7 @@ function getGraphStats() {
30935
30943
  // package.json
30936
30944
  var package_default = {
30937
30945
  name: "@hasna/conversations",
30938
- version: "0.2.13",
30946
+ version: "0.2.15",
30939
30947
  description: "Real-time CLI messaging for AI agents",
30940
30948
  type: "module",
30941
30949
  bin: {
@@ -31154,6 +31162,20 @@ server.registerTool("mark_read", {
31154
31162
  content: [{ type: "text", text: JSON.stringify({ marked_read: count }) }]
31155
31163
  };
31156
31164
  });
31165
+ server.registerTool("mark_unread", {
31166
+ description: "Re-flag a message (or messages) as unread so it re-appears in read_messages(unread_only:true). Useful for bookmarking messages to action later.",
31167
+ inputSchema: {
31168
+ message_id: exports_external.coerce.number().optional().describe("Single message ID"),
31169
+ ids: exports_external.array(exports_external.coerce.number()).optional().describe("Multiple message IDs")
31170
+ }
31171
+ }, async (args) => {
31172
+ if (!args.message_id && (!args.ids || args.ids.length === 0)) {
31173
+ return { content: [{ type: "text", text: "Provide message_id or ids" }], isError: true };
31174
+ }
31175
+ const ids = args.ids ?? (args.message_id ? [args.message_id] : []);
31176
+ const count = markUnreadByIds(ids);
31177
+ return { content: [{ type: "text", text: JSON.stringify({ marked_unread: count }) }] };
31178
+ });
31157
31179
  server.registerTool("mark_space_read", {
31158
31180
  description: "Mark ALL messages in a space as read without fetching them. Use this on busy spaces (200+ messages) where read_messages would overflow tokens.",
31159
31181
  inputSchema: {
@@ -31261,6 +31283,31 @@ server.registerTool("list_spaces", {
31261
31283
  content: [{ type: "text", text: JSON.stringify(spaces) }]
31262
31284
  };
31263
31285
  });
31286
+ server.registerTool("broadcast", {
31287
+ description: "Send the same message to multiple spaces at once. Useful for status updates, bug reports, or announcements that need to go to several spaces.",
31288
+ inputSchema: {
31289
+ spaces: exports_external.array(exports_external.string()).describe("List of space names to send to"),
31290
+ content: exports_external.string().describe("Message content"),
31291
+ from: exports_external.string().optional().describe("Sender agent name"),
31292
+ priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional()
31293
+ }
31294
+ }, async (args) => {
31295
+ const { spaces, content, from: fromParam, priority } = args;
31296
+ const from = resolveIdentity(fromParam);
31297
+ const results = [];
31298
+ const errors3 = [];
31299
+ for (const space of spaces) {
31300
+ try {
31301
+ const msg = sendMessage({ from, to: space, content, space, priority });
31302
+ results.push({ space, id: msg.id });
31303
+ } catch (e) {
31304
+ errors3.push(`${space}: ${e instanceof Error ? e.message : String(e)}`);
31305
+ }
31306
+ }
31307
+ return {
31308
+ content: [{ type: "text", text: JSON.stringify({ sent: results, errors: errors3, total: results.length }) }]
31309
+ };
31310
+ });
31264
31311
  server.registerTool("list_unread_counts", {
31265
31312
  description: "Get unread message counts per space without fetching message content. Use this at session start to triage which spaces need attention before calling read_messages.",
31266
31313
  inputSchema: {
@@ -88,3 +88,7 @@ export declare function getMessagesForAgent(agent: string, opts?: {
88
88
  }>;
89
89
  /** Mark mentions as notified (agent has seen them). */
90
90
  export declare function markMentionsRead(agent: string, space?: string): number;
91
+ /** Mark a specific message as unread (resets read_at to null). */
92
+ export declare function markUnread(messageId: number): number;
93
+ /** Mark multiple messages as unread. */
94
+ export declare function markUnreadByIds(ids: number[]): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.13",
3
+ "version": "0.2.15",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {