@hasna/conversations 0.2.2 → 0.2.3

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
@@ -2644,6 +2644,39 @@ function searchMessages(opts) {
2644
2644
  return { ...msg, snippet: null, relevance_score: 0 };
2645
2645
  });
2646
2646
  }
2647
+ function listUnreadCounts(agent) {
2648
+ const db2 = getDb();
2649
+ if (agent) {
2650
+ const rows2 = db2.prepare(`
2651
+ SELECT
2652
+ space,
2653
+ COUNT(CASE WHEN read_at IS NULL AND (to_agent = ? OR to_agent IS NULL OR to_agent = '') THEN 1 END) AS unread_count,
2654
+ MAX(created_at) AS latest_message_at
2655
+ FROM messages
2656
+ WHERE space IN (
2657
+ SELECT DISTINCT space FROM space_members WHERE agent = ?
2658
+ UNION
2659
+ SELECT DISTINCT space FROM messages WHERE to_agent = ? AND space IS NOT NULL
2660
+ )
2661
+ GROUP BY space
2662
+ HAVING COUNT(*) > 0
2663
+ ORDER BY unread_count DESC, latest_message_at DESC
2664
+ `).all(agent, agent, agent);
2665
+ return rows2;
2666
+ }
2667
+ const rows = db2.prepare(`
2668
+ SELECT
2669
+ space,
2670
+ COUNT(CASE WHEN read_at IS NULL THEN 1 END) AS unread_count,
2671
+ MAX(created_at) AS latest_message_at
2672
+ FROM messages
2673
+ WHERE space IS NOT NULL
2674
+ GROUP BY space
2675
+ HAVING COUNT(*) > 0
2676
+ ORDER BY unread_count DESC, latest_message_at DESC
2677
+ `).all();
2678
+ return rows;
2679
+ }
2647
2680
  var init_messages = __esm(() => {
2648
2681
  init_db();
2649
2682
  init_webhooks();
@@ -4283,7 +4316,7 @@ var init_poll = __esm(() => {
4283
4316
  var require_package = __commonJS((exports, module) => {
4284
4317
  module.exports = {
4285
4318
  name: "@hasna/conversations",
4286
- version: "0.2.2",
4319
+ version: "0.2.3",
4287
4320
  description: "Real-time CLI messaging for AI agents",
4288
4321
  type: "module",
4289
4322
  bin: {
@@ -33704,6 +33737,17 @@ var init_mcp2 = __esm(() => {
33704
33737
  content: [{ type: "text", text: JSON.stringify(spaces) }]
33705
33738
  };
33706
33739
  });
33740
+ server.registerTool("list_unread_counts", {
33741
+ 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.",
33742
+ inputSchema: {
33743
+ agent: exports_external.string().optional().describe("Filter to spaces the agent is a member of or has received messages in. Omit for global unread counts.")
33744
+ }
33745
+ }, async (args) => {
33746
+ const counts = listUnreadCounts(args.agent);
33747
+ return {
33748
+ content: [{ type: "text", text: JSON.stringify(counts) }]
33749
+ };
33750
+ });
33707
33751
  server.registerTool("send_to_space", {
33708
33752
  description: "Post a message to a space.",
33709
33753
  inputSchema: {
@@ -34656,6 +34700,7 @@ var init_mcp2 = __esm(() => {
34656
34700
  search_messages: "Full-text search messages. Required: query. Optional: space?, from?, to?, limit?",
34657
34701
  export_messages: "Export messages as JSON or CSV. Optional: space?, session_id?, from?, since?, until?, format?(json|csv)",
34658
34702
  create_space: "Create space and auto-join. Required: name. Optional: from?, description?, parent_id?(max 3 levels), project_id?",
34703
+ list_unread_counts: "Get unread message counts per space (no content). Ideal for session start triage. Optional: agent?(filter to agent's spaces)",
34659
34704
  list_spaces: "List spaces with member/message counts. Optional: project_id?, parent_id?(use 'null' for top-level), include_archived?",
34660
34705
  send_to_space: "Post message to space. Required: space, content. Optional: from?, priority?(low|normal|high|urgent), blocking?",
34661
34706
  read_space: "Read messages in a space. Required: space. Optional: since?(ISO), limit?, mark_read?(default true \u2014 auto-marks returned messages as read)",
package/bin/mcp.js CHANGED
@@ -29141,6 +29141,39 @@ function searchMessages(opts) {
29141
29141
  return { ...msg, snippet: null, relevance_score: 0 };
29142
29142
  });
29143
29143
  }
29144
+ function listUnreadCounts(agent) {
29145
+ const db2 = getDb();
29146
+ if (agent) {
29147
+ const rows2 = db2.prepare(`
29148
+ SELECT
29149
+ space,
29150
+ COUNT(CASE WHEN read_at IS NULL AND (to_agent = ? OR to_agent IS NULL OR to_agent = '') THEN 1 END) AS unread_count,
29151
+ MAX(created_at) AS latest_message_at
29152
+ FROM messages
29153
+ WHERE space IN (
29154
+ SELECT DISTINCT space FROM space_members WHERE agent = ?
29155
+ UNION
29156
+ SELECT DISTINCT space FROM messages WHERE to_agent = ? AND space IS NOT NULL
29157
+ )
29158
+ GROUP BY space
29159
+ HAVING COUNT(*) > 0
29160
+ ORDER BY unread_count DESC, latest_message_at DESC
29161
+ `).all(agent, agent, agent);
29162
+ return rows2;
29163
+ }
29164
+ const rows = db2.prepare(`
29165
+ SELECT
29166
+ space,
29167
+ COUNT(CASE WHEN read_at IS NULL THEN 1 END) AS unread_count,
29168
+ MAX(created_at) AS latest_message_at
29169
+ FROM messages
29170
+ WHERE space IS NOT NULL
29171
+ GROUP BY space
29172
+ HAVING COUNT(*) > 0
29173
+ ORDER BY unread_count DESC, latest_message_at DESC
29174
+ `).all();
29175
+ return rows;
29176
+ }
29144
29177
 
29145
29178
  // src/lib/sessions.ts
29146
29179
  init_db();
@@ -30767,7 +30800,7 @@ function getGraphStats() {
30767
30800
  // package.json
30768
30801
  var package_default = {
30769
30802
  name: "@hasna/conversations",
30770
- version: "0.2.2",
30803
+ version: "0.2.3",
30771
30804
  description: "Real-time CLI messaging for AI agents",
30772
30805
  type: "module",
30773
30806
  bin: {
@@ -31067,6 +31100,17 @@ server.registerTool("list_spaces", {
31067
31100
  content: [{ type: "text", text: JSON.stringify(spaces) }]
31068
31101
  };
31069
31102
  });
31103
+ server.registerTool("list_unread_counts", {
31104
+ 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.",
31105
+ inputSchema: {
31106
+ agent: exports_external.string().optional().describe("Filter to spaces the agent is a member of or has received messages in. Omit for global unread counts.")
31107
+ }
31108
+ }, async (args) => {
31109
+ const counts = listUnreadCounts(args.agent);
31110
+ return {
31111
+ content: [{ type: "text", text: JSON.stringify(counts) }]
31112
+ };
31113
+ });
31070
31114
  server.registerTool("send_to_space", {
31071
31115
  description: "Post a message to a space.",
31072
31116
  inputSchema: {
@@ -32019,6 +32063,7 @@ server.registerTool("describe_tools", {
32019
32063
  search_messages: "Full-text search messages. Required: query. Optional: space?, from?, to?, limit?",
32020
32064
  export_messages: "Export messages as JSON or CSV. Optional: space?, session_id?, from?, since?, until?, format?(json|csv)",
32021
32065
  create_space: "Create space and auto-join. Required: name. Optional: from?, description?, parent_id?(max 3 levels), project_id?",
32066
+ list_unread_counts: "Get unread message counts per space (no content). Ideal for session start triage. Optional: agent?(filter to agent's spaces)",
32022
32067
  list_spaces: "List spaces with member/message counts. Optional: project_id?, parent_id?(use 'null' for top-level), include_archived?",
32023
32068
  send_to_space: "Post message to space. Required: space, content. Optional: from?, priority?(low|normal|high|urgent), blocking?",
32024
32069
  read_space: "Read messages in a space. Required: space. Optional: since?(ISO), limit?, mark_read?(default true \u2014 auto-marks returned messages as read)",
@@ -56,3 +56,14 @@ export declare function getPinnedMessages(opts?: {
56
56
  export declare function getUnreadBlockers(agent: string): Message[];
57
57
  export declare function getThreadReplies(messageId: number): Message[];
58
58
  export declare function searchMessages(opts: SearchMessagesOptions): SearchResult[];
59
+ export interface UnreadCount {
60
+ space: string;
61
+ unread_count: number;
62
+ latest_message_at: string | null;
63
+ }
64
+ /**
65
+ * Get unread message counts per space — lightweight alternative to read_messages.
66
+ * Returns only spaces where the agent is a member (via space_members) or has received messages.
67
+ * If agent is omitted, returns counts for all spaces.
68
+ */
69
+ export declare function listUnreadCounts(agent?: string): UnreadCount[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {