@hasna/conversations 0.1.13 → 0.1.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.
Files changed (3) hide show
  1. package/bin/index.js +142 -56
  2. package/bin/mcp.js +6 -2
  3. package/package.json +6 -2
package/bin/index.js CHANGED
@@ -3133,11 +3133,105 @@ var init_presence = __esm(() => {
3133
3133
  init_db();
3134
3134
  });
3135
3135
 
3136
+ // src/lib/poll.ts
3137
+ var exports_poll = {};
3138
+ __export(exports_poll, {
3139
+ useSpaceMessages: () => useSpaceMessages,
3140
+ useMessages: () => useMessages,
3141
+ startPolling: () => startPolling
3142
+ });
3143
+ import { useState as useState4, useEffect as useEffect4 } from "react";
3144
+ function startPolling(opts) {
3145
+ const interval = opts.interval_ms ?? 200;
3146
+ let stopped = false;
3147
+ let inFlight = false;
3148
+ let lastSeenId = 0;
3149
+ const seedLastSeen = () => {
3150
+ const latest = readMessages({
3151
+ session_id: opts.session_id,
3152
+ to: opts.to_agent,
3153
+ space: opts.space,
3154
+ order: "desc",
3155
+ limit: 1
3156
+ });
3157
+ if (latest.length > 0) {
3158
+ lastSeenId = latest[0].id;
3159
+ }
3160
+ };
3161
+ const poll = () => {
3162
+ if (stopped || inFlight)
3163
+ return;
3164
+ inFlight = true;
3165
+ try {
3166
+ const messages = readMessages({
3167
+ session_id: opts.session_id,
3168
+ to: opts.to_agent,
3169
+ space: opts.space,
3170
+ since_id: lastSeenId,
3171
+ order: "asc"
3172
+ });
3173
+ if (messages.length > 0) {
3174
+ lastSeenId = messages[messages.length - 1].id;
3175
+ try {
3176
+ opts.on_messages(messages);
3177
+ } catch (error) {
3178
+ console.error("Polling callback error:", error);
3179
+ }
3180
+ }
3181
+ } finally {
3182
+ inFlight = false;
3183
+ }
3184
+ };
3185
+ seedLastSeen();
3186
+ const timer = setInterval(poll, interval);
3187
+ return {
3188
+ stop: () => {
3189
+ stopped = true;
3190
+ clearInterval(timer);
3191
+ }
3192
+ };
3193
+ }
3194
+ function useMessages(sessionId, agent) {
3195
+ const [messages, setMessages] = useState4([]);
3196
+ useEffect4(() => {
3197
+ const existing = readMessages({ session_id: sessionId });
3198
+ setMessages(existing);
3199
+ const { stop } = startPolling({
3200
+ session_id: sessionId,
3201
+ interval_ms: 200,
3202
+ on_messages: (newMessages) => {
3203
+ setMessages((prev) => [...prev, ...newMessages]);
3204
+ }
3205
+ });
3206
+ return stop;
3207
+ }, [sessionId, agent]);
3208
+ return messages;
3209
+ }
3210
+ function useSpaceMessages(spaceName) {
3211
+ const [messages, setMessages] = useState4([]);
3212
+ useEffect4(() => {
3213
+ const existing = readMessages({ space: spaceName });
3214
+ setMessages(existing);
3215
+ const { stop } = startPolling({
3216
+ space: spaceName,
3217
+ interval_ms: 200,
3218
+ on_messages: (newMessages) => {
3219
+ setMessages((prev) => [...prev, ...newMessages]);
3220
+ }
3221
+ });
3222
+ return stop;
3223
+ }, [spaceName]);
3224
+ return messages;
3225
+ }
3226
+ var init_poll = __esm(() => {
3227
+ init_messages();
3228
+ });
3229
+
3136
3230
  // package.json
3137
3231
  var require_package = __commonJS((exports, module) => {
3138
3232
  module.exports = {
3139
3233
  name: "@hasna/conversations",
3140
- version: "0.1.13",
3234
+ version: "0.1.15",
3141
3235
  description: "Real-time CLI messaging for AI agents",
3142
3236
  type: "module",
3143
3237
  bin: {
@@ -3207,7 +3301,11 @@ var require_package = __commonJS((exports, module) => {
3207
3301
  repository: {
3208
3302
  type: "git",
3209
3303
  url: "git+https://github.com/hasna/conversations.git"
3210
- }
3304
+ },
3305
+ bugs: {
3306
+ url: "https://github.com/hasna/conversations/issues"
3307
+ },
3308
+ homepage: "https://github.com/hasna/conversations#readme"
3211
3309
  };
3212
3310
  });
3213
3311
 
@@ -34043,60 +34141,7 @@ function SessionList({ agent, onSelect, onSelectSpace, onNew }) {
34043
34141
  import { useState as useState5, useEffect as useEffect5, useRef as useRef2 } from "react";
34044
34142
  import { Box as Box5, Text as Text6, useInput as useInput4 } from "ink";
34045
34143
  init_messages();
34046
-
34047
- // src/lib/poll.ts
34048
- init_messages();
34049
- import { useState as useState4, useEffect as useEffect4 } from "react";
34050
- function startPolling(opts) {
34051
- const interval = opts.interval_ms ?? 200;
34052
- let stopped = false;
34053
- let inFlight = false;
34054
- let lastSeenId = 0;
34055
- const seedLastSeen = () => {
34056
- const latest = readMessages({
34057
- session_id: opts.session_id,
34058
- to: opts.to_agent,
34059
- space: opts.space,
34060
- order: "desc",
34061
- limit: 1
34062
- });
34063
- if (latest.length > 0) {
34064
- lastSeenId = latest[0].id;
34065
- }
34066
- };
34067
- const poll = () => {
34068
- if (stopped || inFlight)
34069
- return;
34070
- inFlight = true;
34071
- try {
34072
- const messages = readMessages({
34073
- session_id: opts.session_id,
34074
- to: opts.to_agent,
34075
- space: opts.space,
34076
- since_id: lastSeenId,
34077
- order: "asc"
34078
- });
34079
- if (messages.length > 0) {
34080
- lastSeenId = messages[messages.length - 1].id;
34081
- try {
34082
- opts.on_messages(messages);
34083
- } catch (error) {
34084
- console.error("Polling callback error:", error);
34085
- }
34086
- }
34087
- } finally {
34088
- inFlight = false;
34089
- }
34090
- };
34091
- seedLastSeen();
34092
- const timer = setInterval(poll, interval);
34093
- return {
34094
- stop: () => {
34095
- stopped = true;
34096
- clearInterval(timer);
34097
- }
34098
- };
34099
- }
34144
+ init_poll();
34100
34145
 
34101
34146
  // src/cli/components/MessageBubble.tsx
34102
34147
  import { Box as Box4, Text as Text5 } from "ink";
@@ -35212,6 +35257,47 @@ Acknowledge with: conversations mark-read ${blockers.map((b) => b.id).join(" ")}
35212
35257
  }
35213
35258
  closeDb();
35214
35259
  });
35260
+ program2.command("watch").description("Watch for new messages with desktop notifications").option("--from <agent>", "Your agent identity").option("--space <name>", "Watch a specific space").option("--interval <ms>", "Poll interval in milliseconds", parseInt).action((opts) => {
35261
+ const agent = resolveIdentity(opts.from);
35262
+ heartbeat(agent);
35263
+ const interval = Number.isFinite(opts.interval) && opts.interval > 0 ? opts.interval : 1000;
35264
+ console.log(chalk2.cyan(`Watching as ${chalk2.bold(agent)}...`));
35265
+ console.log(chalk2.dim(`Poll interval: ${interval}ms. Press Ctrl+C to stop.
35266
+ `));
35267
+ const { startPolling: startPolling2 } = (init_poll(), __toCommonJS(exports_poll));
35268
+ const notify = (title, body) => {
35269
+ const time3 = new Date().toLocaleTimeString();
35270
+ console.log(`${chalk2.dim(time3)} ${chalk2.cyan(title)}: ${body}`);
35271
+ if (process.platform === "darwin") {
35272
+ try {
35273
+ const { execSync } = __require("child_process");
35274
+ const safeTitle = title.replace(/"/g, "\\\"");
35275
+ const safeBody = body.replace(/"/g, "\\\"").slice(0, 200);
35276
+ execSync(`osascript -e 'display notification "${safeBody}" with title "${safeTitle}"'`, { timeout: 3000 });
35277
+ } catch {}
35278
+ }
35279
+ };
35280
+ startPolling2({
35281
+ to_agent: opts.space ? undefined : agent,
35282
+ space: opts.space,
35283
+ interval_ms: interval,
35284
+ on_messages: (messages) => {
35285
+ for (const msg of messages) {
35286
+ if (msg.from_agent === agent)
35287
+ continue;
35288
+ const where = msg.space ? `#${msg.space}` : "DM";
35289
+ const preview = msg.content.length > 100 ? msg.content.slice(0, 100) + "..." : msg.content;
35290
+ notify(`${msg.from_agent} (${where})`, preview);
35291
+ }
35292
+ }
35293
+ });
35294
+ process.on("SIGINT", () => {
35295
+ console.log(chalk2.dim(`
35296
+ Stopped watching.`));
35297
+ closeDb();
35298
+ process.exit(0);
35299
+ });
35300
+ });
35215
35301
  program2.command("mcp").description("Start MCP server").action(async () => {
35216
35302
  const { startMcpServer: startMcpServer2 } = await Promise.resolve().then(() => (init_mcp2(), exports_mcp));
35217
35303
  await startMcpServer2();
package/bin/mcp.js CHANGED
@@ -29554,7 +29554,7 @@ function renameAgent(oldName, newName) {
29554
29554
  // package.json
29555
29555
  var package_default = {
29556
29556
  name: "@hasna/conversations",
29557
- version: "0.1.13",
29557
+ version: "0.1.15",
29558
29558
  description: "Real-time CLI messaging for AI agents",
29559
29559
  type: "module",
29560
29560
  bin: {
@@ -29624,7 +29624,11 @@ var package_default = {
29624
29624
  repository: {
29625
29625
  type: "git",
29626
29626
  url: "git+https://github.com/hasna/conversations.git"
29627
- }
29627
+ },
29628
+ bugs: {
29629
+ url: "https://github.com/hasna/conversations/issues"
29630
+ },
29631
+ homepage: "https://github.com/hasna/conversations#readme"
29628
29632
  };
29629
29633
 
29630
29634
  // src/mcp/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -70,5 +70,9 @@
70
70
  "repository": {
71
71
  "type": "git",
72
72
  "url": "git+https://github.com/hasna/conversations.git"
73
- }
73
+ },
74
+ "bugs": {
75
+ "url": "https://github.com/hasna/conversations/issues"
76
+ },
77
+ "homepage": "https://github.com/hasna/conversations#readme"
74
78
  }