@hasna/conversations 0.2.20 → 0.2.22

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 (6) hide show
  1. package/README.md +23 -508
  2. package/bin/hook.js +3449 -2894
  3. package/bin/index.js +4352 -3067
  4. package/bin/mcp.js +4120 -2914
  5. package/dist/index.js +3475 -2920
  6. package/package.json +6 -5
package/README.md CHANGED
@@ -1,536 +1,51 @@
1
1
  # @hasna/conversations
2
2
 
3
- Real-time messaging for AI agents on the same machine. Send direct messages between Claude Code, Codex, Gemini, and other agents, or broadcast to shared spaces -- all backed by a single SQLite database with 200ms polling.
3
+ Real-time CLI messaging for AI agents
4
4
 
5
- ## Features
5
+ [![npm](https://img.shields.io/npm/v/@hasna/conversations)](https://www.npmjs.com/package/@hasna/conversations)
6
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)
6
7
 
7
- - **Direct messages** -- point-to-point messaging between any two agents
8
- - **Spaces** -- broadcast channels where any member can post and all members can read, with up to 3 levels of nesting
9
- - **Projects** -- organize spaces under projects with metadata, tags, status, and settings
10
- - **Sessions** -- derived automatically from messages, no manual session management
11
- - **Priorities** -- four levels: `low`, `normal`, `high`, `urgent`
12
- - **Read tracking** -- per-message read receipts with bulk mark-read support
13
- - **Message threading** -- `reply_to` field links replies to parent messages; `getThreadReplies()` fetches full threads
14
- - **Emoji reactions** -- add/remove emoji reactions on any message; `getReactionSummary()` aggregates counts
15
- - **Message pinning** -- pin important messages per space or session
16
- - **Agent presence** -- heartbeat, online/offline status, 30-min conflict detection for concurrent sessions
17
- - **Resource locks** -- advisory and exclusive locks with configurable TTL for coordination
18
- - **Focus mode** -- scope an agent session to a project; all read tools auto-filter by project
19
- - **Webhooks** -- async POST notifications to Slack/Discord/email on DM, blocker, space, or @mention
20
- - **200ms polling** -- near-instant message delivery via indexed SQLite queries
21
- - **Three surfaces** -- CLI, MCP server (37 tools), and TypeScript library
22
- - **Interactive TUI** -- Ink-based terminal UI for browsing sessions and chatting
23
- - **Web dashboard** -- built-in HTTP dashboard for browser-based monitoring
24
- - **Health check** -- `conversations doctor` validates setup and catches common issues
25
- - **Self-updating** -- `conversations update` checks npm and installs the latest version
26
-
27
- ## Installation
8
+ ## Install
28
9
 
29
10
  ```bash
30
- # Global install (recommended)
31
- bun install -g @hasna/conversations
32
-
33
- # Or use npx (no install needed)
34
- npx @hasna/conversations
35
- ```
36
-
37
- ## Quick Start
38
-
39
- ```bash
40
- # Send a direct message
41
- conversations send --to claude-code "Can you review the auth module?" --from codex
42
-
43
- # Read messages
44
- conversations read --to codex --unread --json
45
-
46
- # Create a space and broadcast
47
- conversations space create deployments --description "Deploy notifications"
48
- conversations space send deployments "v1.2 deployed to staging" --from ops
49
-
50
- # Launch the interactive TUI
51
- conversations
11
+ npm install -g @hasna/conversations
52
12
  ```
53
13
 
54
- ## Direct Messages
55
-
56
- Direct messages are point-to-point: one sender, one recipient. Sessions are auto-generated from the sorted agent pair plus a random suffix (e.g. `claude-code-codex-a1b2c3d4`).
14
+ ## CLI Usage
57
15
 
58
16
  ```bash
59
- # Basic message
60
- conversations send --to claude-code "Hello from codex" --from codex
61
-
62
- # With full context
63
- conversations send --to claude-code "Check this branch" \
64
- --from codex \
65
- --priority high \
66
- --working-dir /path/to/project \
67
- --repository my-app \
68
- --branch feature/auth
69
-
70
- # With arbitrary metadata
71
- conversations send --to gemini "Deploy ready" --metadata '{"env":"staging"}'
72
-
73
- # Read messages for an agent
74
- conversations read --to codex
75
-
76
- # Unread only, as JSON
77
- conversations read --to codex --unread --json
78
-
79
- # Read and mark as read in one step
80
- conversations read --to codex --unread --mark-read
81
-
82
- # Reply to a message (auto-resolves session and recipient)
83
- conversations reply --to 42 "Got it, working on it now"
17
+ conversations-hook --help
84
18
  ```
85
19
 
86
- ## Spaces
87
-
88
- Spaces are broadcast groups -- any agent can post, all members can read. Spaces support nesting up to 3 levels deep and can optionally belong to a project.
89
-
90
- ```bash
91
- # Create a space
92
- conversations space create deployments --description "Deployment notifications"
93
-
94
- # Create a nested space
95
- conversations space create deployments-staging --parent deployments
96
-
97
- # List spaces
98
- conversations space list
99
- conversations space list --top-level
100
- conversations space list --project <project-id>
101
-
102
- # Join / leave
103
- conversations space join deployments --from codex
104
- conversations space leave deployments --from codex
105
-
106
- # Send to a space
107
- conversations space send deployments "v1.2 deployed to staging" --from ops
108
-
109
- # Read space messages
110
- conversations space read deployments
111
- conversations space read deployments --since 2025-01-01T00:00:00 --limit 50
112
-
113
- # List members
114
- conversations space members deployments
115
- ```
116
-
117
- ## Sessions
118
-
119
- Sessions are derived from messages (no separate table). They track participants, message count, and unread count.
120
-
121
- ```bash
122
- # List all sessions
123
- conversations sessions
124
-
125
- # Sessions for a specific agent
126
- conversations sessions --agent claude-code --json
127
- ```
128
-
129
- ## Projects
130
-
131
- Projects organize spaces and provide context for agent collaboration. They support metadata, tags, status (active/archived), repository URLs, and arbitrary settings.
132
-
133
- ```bash
134
- # Create a project
135
- conversations project create my-app \
136
- --description "Main application" \
137
- --path /path/to/project \
138
- --repository https://github.com/org/my-app \
139
- --tags '["backend","api"]'
140
-
141
- # List projects
142
- conversations project list
143
- conversations project list --status active
144
-
145
- # Get project details
146
- conversations project get my-app
147
-
148
- # Update a project
149
- conversations project update <id> --status archived
150
-
151
- # Delete a project (fails if spaces still reference it)
152
- conversations project delete <id>
153
- ```
154
-
155
- ## Mark Read
156
-
157
- ```bash
158
- # Mark specific messages
159
- conversations mark-read 1 2 3 --agent codex
160
-
161
- # Mark entire session
162
- conversations mark-read --session abc123 --agent codex
163
-
164
- # Mark entire space
165
- conversations mark-read --space deployments --agent codex
166
- ```
167
-
168
- ## Status
169
-
170
- ```bash
171
- conversations status
172
- # Conversations Status
173
- # DB Path: ~/.conversations/messages.db
174
- # Messages: 47
175
- # Sessions: 5
176
- # Spaces: 3
177
- # Projects: 2
178
- # Unread: 3
179
- ```
180
-
181
- ## Interactive TUI
182
-
183
- ```bash
184
- conversations
185
- ```
186
-
187
- Arrow keys to navigate sessions, Enter to open, `n` for new conversation, `q` to quit, Esc to go back.
188
-
189
- ## Web Dashboard
190
-
191
- ```bash
192
- conversations dashboard # Start on default port 3456
193
- conversations dashboard --port 8080 # Custom port
194
- conversations dashboard --host 0.0.0.0 # Bind to all interfaces
195
- ```
20
+ - `conversations-hook send`
21
+ - `conversations-hook read`
22
+ - `conversations-hook digest`
23
+ - `conversations-hook search`
24
+ - `conversations-hook graph build`
25
+ - `conversations-hook agent`
196
26
 
197
27
  ## MCP Server
198
28
 
199
- The MCP server exposes 16 tools for native AI agent integration via the Model Context Protocol over stdio.
200
-
201
- ### Agent Configuration
202
-
203
- Add to your agent's MCP config (Claude Code, Codex, etc.):
204
-
205
- ```json
206
- {
207
- "mcpServers": {
208
- "conversations": {
209
- "command": "bunx",
210
- "args": ["@hasna/conversations", "mcp"],
211
- "env": { "CONVERSATIONS_AGENT_ID": "claude-code" }
212
- }
213
- }
214
- }
215
- ```
216
-
217
- ### MCP Tools
218
-
219
- | Tool | Category | Description |
220
- |------|----------|-------------|
221
- | `send_message` | DM | Send a direct message (sender auto-resolved from env) |
222
- | `read_messages` | DM | Read messages with filters (session, agent, space, time, unread) |
223
- | `list_sessions` | DM | List conversation sessions, optionally filtered by agent |
224
- | `reply` | DM | Reply to a message by ID (auto-resolves session and recipient) |
225
- | `mark_read` | DM | Mark message IDs as read for the current agent |
226
- | `create_space` | Space | Create a new space (creator auto-joined, supports nesting and projects) |
227
- | `list_spaces` | Space | List spaces with member/message counts, filter by project or parent |
228
- | `send_to_space` | Space | Send a message to a space (all members can see it) |
229
- | `read_space` | Space | Read messages from a space |
230
- | `join_space` | Space | Join a space to receive messages |
231
- | `leave_space` | Space | Leave a space |
232
- | `create_project` | Project | Create a new project with metadata, tags, and settings |
233
- | `list_projects` | Project | List all registered projects, optionally filter by status |
234
- | `get_project` | Project | Get full project details by ID or name |
235
- | `update_project` | Project | Update any project field |
236
- | `delete_project` | Project | Delete a project (fails if spaces still reference it) |
237
-
238
- ## Programmatic API
239
-
240
- ```typescript
241
- import {
242
- sendMessage,
243
- readMessages,
244
- markRead,
245
- markSessionRead,
246
- markSpaceRead,
247
- listSessions,
248
- createSpace,
249
- listSpaces,
250
- joinSpace,
251
- leaveSpace,
252
- createProject,
253
- listProjects,
254
- startPolling,
255
- resolveIdentity,
256
- } from "@hasna/conversations";
257
-
258
- // Send a direct message
259
- const msg = sendMessage({
260
- from: "my-agent",
261
- to: "claude-code",
262
- content: "Hello!",
263
- priority: "high",
264
- });
265
-
266
- // Read unread messages
267
- const messages = readMessages({ to: "my-agent", unread_only: true });
268
-
269
- // Poll for new messages (200ms default interval)
270
- const { stop } = startPolling({
271
- to_agent: "my-agent",
272
- on_messages: (msgs) => console.log("New:", msgs),
273
- });
274
-
275
- // Spaces
276
- createSpace("deploys", "my-agent", { description: "Deploy notifications" });
277
- joinSpace("deploys", "claude-code");
278
- sendMessage({
279
- from: "my-agent",
280
- to: "deploys",
281
- content: "v2.0 shipped",
282
- space: "deploys",
283
- session_id: "space:deploys",
284
- });
285
- const channelMsgs = readMessages({ space: "deploys" });
286
-
287
- // Projects
288
- const project = createProject({
289
- name: "my-app",
290
- created_by: "my-agent",
291
- description: "Main application",
292
- tags: ["backend", "api"],
293
- });
294
-
295
- // Clean up
296
- stop();
297
- ```
298
-
299
- ### React Hooks (for Ink TUI)
300
-
301
- ```typescript
302
- import { useMessages, useSpaceMessages } from "@hasna/conversations";
303
-
304
- // Poll session messages (200ms interval)
305
- const messages = useMessages(sessionId, agent);
306
-
307
- // Poll space messages (200ms interval)
308
- const spaceMessages = useSpaceMessages("deployments");
309
- ```
310
-
311
- ## Environment Variables
312
-
313
- | Variable | Description | Default |
314
- |----------|-------------|---------|
315
- | `CONVERSATIONS_AGENT_ID` | Agent identity for MCP server and CLI `--from` fallback | `"user"` |
316
- | `CONVERSATIONS_DB_PATH` | Override database file location | `~/.conversations/messages.db` |
317
-
318
- ## Architecture
319
-
320
- ```
321
- ┌──────────────────┐ ┌─────────────────────┐ ┌──────────────────────┐
322
- │ Ink TUI │ │ CLI (headless) │ │ MCP Server │
323
- │ `conversations` │ │ `conversations send` │ │ `conversations mcp` │
324
- └────────┬─────────┘ └──────────┬──────────┘ └──────────┬───────────┘
325
- │ │ │
326
- └───────────┬───────────┴────────────────────────┘
327
-
328
- ┌───────▼────────┐
329
- │ Core Library │
330
- │ src/lib/* │
331
- └───────┬────────┘
332
-
333
- ┌───────▼────────┐
334
- │ bun:sqlite │
335
- │ WAL mode │
336
- │ 200ms polling │
337
- └───────┬────────┘
338
-
339
- ~/.conversations/messages.db
340
- ```
341
-
342
- - **SQLite WAL mode** for concurrent read/write across processes
343
- - **200ms `setInterval` polling** on indexed `created_at`/`id` columns -- microsecond-fast queries
344
- - **Single shared database** at `~/.conversations/messages.db`
345
- - **Sessions derived from messages** -- no separate sessions table
346
- - **Agent identity resolution**: explicit `--from` flag > `CONVERSATIONS_AGENT_ID` env var > `"user"` fallback
347
-
348
- ## Emoji Reactions
349
-
350
- Add emoji reactions to any message. Reactions are aggregated by emoji with agent lists.
351
-
352
29
  ```bash
353
- # Add a reaction
354
- conversations react 42 👍
355
-
356
- # Remove a reaction
357
- conversations unreact 42 👍
358
-
359
- # Show reaction counts for a message
360
- conversations reactions 42
361
-
362
- # TypeScript library
363
- import { addReaction, removeReaction, getReactionSummary } from "@hasna/conversations";
364
-
365
- addReaction(42, "codex", "✅");
366
- const summary = getReactionSummary(42);
367
- // [{ emoji: "✅", count: 1, agents: ["codex"] }]
30
+ conversations-mcp
368
31
  ```
369
32
 
370
- ## Message Threading
33
+ 1 tools available.
371
34
 
372
- Replies link to a parent message via `reply_to`. Use `getThreadReplies()` to fetch all replies.
35
+ ## Cloud Sync
373
36
 
374
- ```bash
375
- # Reply to message #42 (CLI)
376
- conversations reply --to 42 "Got it!"
377
-
378
- # MCP tool
379
- { "tool": "reply", "message_id": 42, "content": "Got it!" }
380
- { "tool": "get_thread_replies", "message_id": 42 }
381
- ```
382
-
383
- ```typescript
384
- import { readMessages, getThreadReplies } from "@hasna/conversations";
385
-
386
- const replies = getThreadReplies(42);
387
- ```
388
-
389
- ## Agent Presence
390
-
391
- Agents announce their presence via heartbeat. The system detects duplicate sessions (30-min conflict window) and supports graceful takeover of stale sessions.
37
+ This package supports cloud sync via `@hasna/cloud`:
392
38
 
393
39
  ```bash
394
- # Register agent (with conflict detection)
395
- conversations agents list
396
- conversations agents list --online
397
-
398
- # MCP tools
399
- { "tool": "register_agent", "name": "codex", "session_id": "sess-abc123", "role": "agent" }
400
- { "tool": "heartbeat", "from": "codex", "status": "working on auth module" }
401
- { "tool": "list_agents" }
40
+ cloud setup
41
+ cloud sync push --service conversations
42
+ cloud sync pull --service conversations
402
43
  ```
403
44
 
404
- ```typescript
405
- import { registerAgent, heartbeat, listAgents, isAgentConflict } from "@hasna/conversations";
45
+ ## Data Directory
406
46
 
407
- const result = registerAgent("codex", "sess-abc123", "agent");
408
- if (isAgentConflict(result)) {
409
- console.log(`Conflict: ${result.existing_session_id} active since ${result.last_seen_at}`);
410
- }
411
- ```
412
-
413
- ## Resource Locks
414
-
415
- Coordinate concurrent agent access with advisory or exclusive locks. Locks expire automatically (default 5 minutes).
416
-
417
- ```typescript
418
- import { acquireLock, releaseLock, checkLock } from "@hasna/conversations";
419
-
420
- // Advisory lock (multiple readers allowed, writers coordinate)
421
- const result = acquireLock("space", "deployments", "codex", "advisory");
422
- if (!result.acquired) {
423
- console.log(`Locked by ${result.held_by}`);
424
- }
425
-
426
- // Exclusive lock (only one writer)
427
- acquireLock("pinned_message", "42", "codex", "exclusive", 60_000); // 1 min TTL
428
- releaseLock("pinned_message", "42", "codex");
429
- ```
430
-
431
- ```bash
432
- # MCP tools
433
- { "tool": "acquire_lock", "resource_type": "space", "resource_id": "deployments", "lock_type": "advisory" }
434
- { "tool": "check_lock", "resource_type": "space", "resource_id": "deployments" }
435
- { "tool": "release_lock", "resource_type": "space", "resource_id": "deployments" }
436
- { "tool": "list_locks" }
437
- ```
438
-
439
- ## Focus Mode
440
-
441
- Scope an agent session to a project. All read-heavy MCP tools auto-filter to the focused project.
442
-
443
- ```bash
444
- # MCP tools
445
- { "tool": "set_focus", "project_id": "proj-abc123", "from": "codex" }
446
- { "tool": "get_focus", "from": "codex" }
447
- { "tool": "unfocus", "from": "codex" }
448
- ```
449
-
450
- Priority: explicit `project_id` param > session focus > `register_agent` project > no filter.
451
-
452
- ## Webhooks
453
-
454
- Get notified on Slack, Discord, or any HTTP endpoint when messages arrive.
455
-
456
- Create `~/.conversations/config.json`:
457
-
458
- ```json
459
- {
460
- "webhooks": [
461
- {
462
- "url": "https://hooks.slack.com/services/...",
463
- "events": ["dm", "blocker", "space", "mention"],
464
- "agent": "andrei"
465
- }
466
- ]
467
- }
468
- ```
469
-
470
- Event types: `dm` (direct messages), `blocker` (blocking messages), `space` (space messages), `mention` (@name matches).
471
-
472
- Webhooks fire asynchronously — they never slow down message delivery. Failed deliveries are silently ignored.
473
-
474
- ## Health Check
475
-
476
- ```bash
477
- conversations doctor
478
- ```
479
-
480
- Checks: database accessibility, WAL mode, MCP binary on PATH, npm version, webhook config validity.
481
-
482
- ## CLI Commands
483
-
484
- | Command | Description |
485
- |---------|-------------|
486
- | `conversations` | Launch interactive TUI |
487
- | `conversations send` | Send a direct message |
488
- | `conversations read` | Read messages with filters |
489
- | `conversations reply` | Reply to a message by ID |
490
- | `conversations search <query>` | Full-text search across messages |
491
- | `conversations since <duration>` | Activity feed since 30m/2h/1d ago |
492
- | `conversations context` | Session boot context for agents |
493
- | `conversations sessions` | List conversation sessions |
494
- | `conversations mark-read` | Mark messages as read |
495
- | `conversations pin <id>` | Pin a message |
496
- | `conversations unpin <id>` | Unpin a message |
497
- | `conversations pinned` | List pinned messages |
498
- | `conversations react <id> <emoji>` | Add emoji reaction |
499
- | `conversations unreact <id> <emoji>` | Remove emoji reaction |
500
- | `conversations reactions <id>` | Show reaction summary |
501
- | `conversations status` | Show database stats |
502
- | `conversations doctor` | Health check |
503
- | `conversations update` | Check for and install updates |
504
- | `conversations space create` | Create a new space |
505
- | `conversations space list` | List all spaces |
506
- | `conversations space send` | Send a message to a space |
507
- | `conversations space read` | Read messages from a space |
508
- | `conversations space join` | Join a space |
509
- | `conversations space leave` | Leave a space |
510
- | `conversations space members` | List space members |
511
- | `conversations project create` | Create a new project |
512
- | `conversations project list` | List all projects |
513
- | `conversations project get` | Get project details |
514
- | `conversations project update` | Update a project |
515
- | `conversations project delete` | Delete a project |
516
- | `conversations agents list` | List agents with presence |
517
- | `conversations mcp` | Start MCP server on stdio |
518
- | `conversations dashboard` | Start web dashboard |
519
-
520
- All commands support `--json` for machine-readable output.
521
-
522
- ## Development
523
-
524
- ```bash
525
- git clone https://github.com/hasna/conversations.git
526
- cd conversations
527
- bun install
528
- bun run dev # Run CLI in dev mode
529
- bun test # Run tests
530
- bun run typecheck # Type-check
531
- bun run build # Build everything
532
- ```
47
+ Data is stored in `~/.hasna/conversations/`.
533
48
 
534
49
  ## License
535
50
 
536
- [Apache-2.0](./LICENSE)
51
+ Apache-2.0 -- see [LICENSE](LICENSE)