@hasna/conversations 0.1.5 → 0.1.6

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/mcp.js CHANGED
@@ -4,6 +4,7 @@ var __create = Object.create;
4
4
  var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
9
  var __toESM = (mod, isNodeMode, target) => {
9
10
  target = mod != null ? __create(__getProtoOf(mod)) : {};
@@ -16,6 +17,20 @@ var __toESM = (mod, isNodeMode, target) => {
16
17
  });
17
18
  return to;
18
19
  };
20
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
21
+ var __toCommonJS = (from) => {
22
+ var entry = __moduleCache.get(from), desc;
23
+ if (entry)
24
+ return entry;
25
+ entry = __defProp({}, "__esModule", { value: true });
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
+ }));
31
+ __moduleCache.set(from, entry);
32
+ return entry;
33
+ };
19
34
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
35
  var __export = (target, all) => {
21
36
  for (var name in all)
@@ -26,6 +41,7 @@ var __export = (target, all) => {
26
41
  set: (newValue) => all[name] = () => newValue
27
42
  });
28
43
  };
44
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
45
 
30
46
  // node_modules/ajv/dist/compile/codegen/code.js
31
47
  var require_code = __commonJS((exports) => {
@@ -6499,6 +6515,165 @@ var require_dist = __commonJS((exports, module) => {
6499
6515
  exports.default = formatsPlugin;
6500
6516
  });
6501
6517
 
6518
+ // src/lib/db.ts
6519
+ var exports_db = {};
6520
+ __export(exports_db, {
6521
+ getDbPath: () => getDbPath,
6522
+ getDb: () => getDb,
6523
+ closeDb: () => closeDb
6524
+ });
6525
+ import { Database } from "bun:sqlite";
6526
+ import { mkdirSync } from "fs";
6527
+ import { join, dirname } from "path";
6528
+ import { homedir } from "os";
6529
+ function getDbPath() {
6530
+ if (process.env.CONVERSATIONS_DB_PATH)
6531
+ return process.env.CONVERSATIONS_DB_PATH;
6532
+ return join(homedir(), ".conversations", "messages.db");
6533
+ }
6534
+ function getDb() {
6535
+ if (db)
6536
+ return db;
6537
+ const dbPath = getDbPath();
6538
+ mkdirSync(dirname(dbPath), { recursive: true });
6539
+ db = new Database(dbPath, { create: true });
6540
+ db.exec("PRAGMA journal_mode = WAL");
6541
+ db.exec("PRAGMA busy_timeout = 5000");
6542
+ db.exec(`
6543
+ CREATE TABLE IF NOT EXISTS messages (
6544
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6545
+ session_id TEXT NOT NULL,
6546
+ from_agent TEXT NOT NULL,
6547
+ to_agent TEXT NOT NULL,
6548
+ space TEXT,
6549
+ content TEXT NOT NULL,
6550
+ priority TEXT NOT NULL DEFAULT 'normal',
6551
+ working_dir TEXT,
6552
+ repository TEXT,
6553
+ branch TEXT,
6554
+ metadata TEXT,
6555
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
6556
+ read_at TEXT
6557
+ )
6558
+ `);
6559
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
6560
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
6561
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
6562
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_space ON messages(space)");
6563
+ db.exec(`
6564
+ CREATE TABLE IF NOT EXISTS projects (
6565
+ id TEXT PRIMARY KEY,
6566
+ name TEXT NOT NULL UNIQUE,
6567
+ description TEXT,
6568
+ path TEXT,
6569
+ created_by TEXT NOT NULL,
6570
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
6571
+ metadata TEXT,
6572
+ tags TEXT,
6573
+ status TEXT NOT NULL DEFAULT 'active',
6574
+ repository TEXT,
6575
+ settings TEXT
6576
+ )
6577
+ `);
6578
+ db.exec("CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name)");
6579
+ db.exec("CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status)");
6580
+ db.exec(`
6581
+ CREATE TABLE IF NOT EXISTS spaces (
6582
+ name TEXT PRIMARY KEY,
6583
+ description TEXT,
6584
+ parent_id TEXT REFERENCES spaces(name),
6585
+ project_id TEXT REFERENCES projects(id),
6586
+ created_by TEXT NOT NULL,
6587
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
6588
+ archived_at TEXT
6589
+ )
6590
+ `);
6591
+ db.exec("CREATE INDEX IF NOT EXISTS idx_spaces_parent ON spaces(parent_id)");
6592
+ db.exec("CREATE INDEX IF NOT EXISTS idx_spaces_project ON spaces(project_id)");
6593
+ db.exec(`
6594
+ CREATE TABLE IF NOT EXISTS space_members (
6595
+ space TEXT NOT NULL REFERENCES spaces(name),
6596
+ agent TEXT NOT NULL,
6597
+ joined_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
6598
+ PRIMARY KEY (space, agent)
6599
+ )
6600
+ `);
6601
+ db.exec(`
6602
+ CREATE TABLE IF NOT EXISTS agent_presence (
6603
+ agent TEXT PRIMARY KEY,
6604
+ status TEXT NOT NULL DEFAULT 'online',
6605
+ last_seen_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
6606
+ metadata TEXT
6607
+ )
6608
+ `);
6609
+ const existingTables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all();
6610
+ const tableNames = existingTables.map((t) => t.name);
6611
+ if (tableNames.includes("channels") && tableNames.includes("spaces")) {
6612
+ const spaceCount = db.prepare("SELECT COUNT(*) as c FROM spaces").get().c;
6613
+ const channelCount = db.prepare("SELECT COUNT(*) as c FROM channels").get().c;
6614
+ if (channelCount > 0 && spaceCount === 0) {
6615
+ db.exec("BEGIN");
6616
+ try {
6617
+ db.exec(`
6618
+ INSERT OR IGNORE INTO spaces (name, description, created_by, created_at)
6619
+ SELECT name, description, created_by, created_at FROM channels
6620
+ `);
6621
+ if (tableNames.includes("channel_members")) {
6622
+ db.exec(`
6623
+ INSERT OR IGNORE INTO space_members (space, agent, joined_at)
6624
+ SELECT channel, agent, joined_at FROM channel_members
6625
+ `);
6626
+ }
6627
+ db.exec("COMMIT");
6628
+ } catch (e) {
6629
+ db.exec("ROLLBACK");
6630
+ throw e;
6631
+ }
6632
+ }
6633
+ db.exec("DROP TABLE IF EXISTS channel_members");
6634
+ db.exec("DROP TABLE IF EXISTS channels");
6635
+ }
6636
+ const msgCols = db.prepare("PRAGMA table_info(messages)").all();
6637
+ const colNames = msgCols.map((c) => c.name);
6638
+ if (colNames.includes("channel") && !colNames.includes("space")) {
6639
+ db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
6640
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_space ON messages(space)");
6641
+ db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
6642
+ db.exec(`
6643
+ UPDATE messages
6644
+ SET session_id = 'space:' || substr(session_id, 9)
6645
+ WHERE session_id LIKE 'channel:%'
6646
+ `);
6647
+ }
6648
+ const spaceCols = db.prepare("PRAGMA table_info(spaces)").all();
6649
+ const spaceColNames = spaceCols.map((c) => c.name);
6650
+ if (!spaceColNames.includes("archived_at")) {
6651
+ db.exec("ALTER TABLE spaces ADD COLUMN archived_at TEXT");
6652
+ }
6653
+ const msgCols2 = db.prepare("PRAGMA table_info(messages)").all();
6654
+ const colNames2 = msgCols2.map((c) => c.name);
6655
+ if (!colNames2.includes("edited_at")) {
6656
+ db.exec("ALTER TABLE messages ADD COLUMN edited_at TEXT");
6657
+ }
6658
+ if (!colNames2.includes("pinned_at")) {
6659
+ db.exec("ALTER TABLE messages ADD COLUMN pinned_at TEXT");
6660
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_pinned ON messages(pinned_at)");
6661
+ }
6662
+ if (!colNames2.includes("blocking")) {
6663
+ db.exec("ALTER TABLE messages ADD COLUMN blocking INTEGER NOT NULL DEFAULT 0");
6664
+ db.exec("CREATE INDEX IF NOT EXISTS idx_messages_blocking ON messages(blocking)");
6665
+ }
6666
+ return db;
6667
+ }
6668
+ function closeDb() {
6669
+ if (db) {
6670
+ db.close();
6671
+ db = null;
6672
+ }
6673
+ }
6674
+ var db = null;
6675
+ var init_db = () => {};
6676
+
6502
6677
  // node_modules/zod/v3/helpers/util.js
6503
6678
  var util;
6504
6679
  (function(util2) {
@@ -28316,149 +28491,8 @@ class StdioServerTransport {
28316
28491
  }
28317
28492
  }
28318
28493
 
28319
- // src/lib/db.ts
28320
- import { Database } from "bun:sqlite";
28321
- import { mkdirSync } from "fs";
28322
- import { join, dirname } from "path";
28323
- import { homedir } from "os";
28324
- var db = null;
28325
- function getDbPath() {
28326
- if (process.env.CONVERSATIONS_DB_PATH)
28327
- return process.env.CONVERSATIONS_DB_PATH;
28328
- return join(homedir(), ".conversations", "messages.db");
28329
- }
28330
- function getDb() {
28331
- if (db)
28332
- return db;
28333
- const dbPath = getDbPath();
28334
- mkdirSync(dirname(dbPath), { recursive: true });
28335
- db = new Database(dbPath, { create: true });
28336
- db.exec("PRAGMA journal_mode = WAL");
28337
- db.exec("PRAGMA busy_timeout = 5000");
28338
- db.exec(`
28339
- CREATE TABLE IF NOT EXISTS messages (
28340
- id INTEGER PRIMARY KEY AUTOINCREMENT,
28341
- session_id TEXT NOT NULL,
28342
- from_agent TEXT NOT NULL,
28343
- to_agent TEXT NOT NULL,
28344
- space TEXT,
28345
- content TEXT NOT NULL,
28346
- priority TEXT NOT NULL DEFAULT 'normal',
28347
- working_dir TEXT,
28348
- repository TEXT,
28349
- branch TEXT,
28350
- metadata TEXT,
28351
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
28352
- read_at TEXT
28353
- )
28354
- `);
28355
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)");
28356
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_agent)");
28357
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)");
28358
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_space ON messages(space)");
28359
- db.exec(`
28360
- CREATE TABLE IF NOT EXISTS projects (
28361
- id TEXT PRIMARY KEY,
28362
- name TEXT NOT NULL UNIQUE,
28363
- description TEXT,
28364
- path TEXT,
28365
- created_by TEXT NOT NULL,
28366
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
28367
- metadata TEXT,
28368
- tags TEXT,
28369
- status TEXT NOT NULL DEFAULT 'active',
28370
- repository TEXT,
28371
- settings TEXT
28372
- )
28373
- `);
28374
- db.exec("CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name)");
28375
- db.exec("CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status)");
28376
- db.exec(`
28377
- CREATE TABLE IF NOT EXISTS spaces (
28378
- name TEXT PRIMARY KEY,
28379
- description TEXT,
28380
- parent_id TEXT REFERENCES spaces(name),
28381
- project_id TEXT REFERENCES projects(id),
28382
- created_by TEXT NOT NULL,
28383
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
28384
- archived_at TEXT
28385
- )
28386
- `);
28387
- db.exec("CREATE INDEX IF NOT EXISTS idx_spaces_parent ON spaces(parent_id)");
28388
- db.exec("CREATE INDEX IF NOT EXISTS idx_spaces_project ON spaces(project_id)");
28389
- db.exec(`
28390
- CREATE TABLE IF NOT EXISTS space_members (
28391
- space TEXT NOT NULL REFERENCES spaces(name),
28392
- agent TEXT NOT NULL,
28393
- joined_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
28394
- PRIMARY KEY (space, agent)
28395
- )
28396
- `);
28397
- db.exec(`
28398
- CREATE TABLE IF NOT EXISTS agent_presence (
28399
- agent TEXT PRIMARY KEY,
28400
- status TEXT NOT NULL DEFAULT 'online',
28401
- last_seen_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
28402
- metadata TEXT
28403
- )
28404
- `);
28405
- const existingTables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all();
28406
- const tableNames = existingTables.map((t) => t.name);
28407
- if (tableNames.includes("channels") && tableNames.includes("spaces")) {
28408
- const spaceCount = db.prepare("SELECT COUNT(*) as c FROM spaces").get().c;
28409
- const channelCount = db.prepare("SELECT COUNT(*) as c FROM channels").get().c;
28410
- if (channelCount > 0 && spaceCount === 0) {
28411
- db.exec("BEGIN");
28412
- try {
28413
- db.exec(`
28414
- INSERT OR IGNORE INTO spaces (name, description, created_by, created_at)
28415
- SELECT name, description, created_by, created_at FROM channels
28416
- `);
28417
- if (tableNames.includes("channel_members")) {
28418
- db.exec(`
28419
- INSERT OR IGNORE INTO space_members (space, agent, joined_at)
28420
- SELECT channel, agent, joined_at FROM channel_members
28421
- `);
28422
- }
28423
- db.exec("COMMIT");
28424
- } catch (e) {
28425
- db.exec("ROLLBACK");
28426
- throw e;
28427
- }
28428
- }
28429
- db.exec("DROP TABLE IF EXISTS channel_members");
28430
- db.exec("DROP TABLE IF EXISTS channels");
28431
- }
28432
- const msgCols = db.prepare("PRAGMA table_info(messages)").all();
28433
- const colNames = msgCols.map((c) => c.name);
28434
- if (colNames.includes("channel") && !colNames.includes("space")) {
28435
- db.exec("ALTER TABLE messages ADD COLUMN space TEXT");
28436
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_space ON messages(space)");
28437
- db.exec("UPDATE messages SET space = channel WHERE channel IS NOT NULL");
28438
- db.exec(`
28439
- UPDATE messages
28440
- SET session_id = 'space:' || substr(session_id, 9)
28441
- WHERE session_id LIKE 'channel:%'
28442
- `);
28443
- }
28444
- const spaceCols = db.prepare("PRAGMA table_info(spaces)").all();
28445
- const spaceColNames = spaceCols.map((c) => c.name);
28446
- if (!spaceColNames.includes("archived_at")) {
28447
- db.exec("ALTER TABLE spaces ADD COLUMN archived_at TEXT");
28448
- }
28449
- const msgCols2 = db.prepare("PRAGMA table_info(messages)").all();
28450
- const colNames2 = msgCols2.map((c) => c.name);
28451
- if (!colNames2.includes("edited_at")) {
28452
- db.exec("ALTER TABLE messages ADD COLUMN edited_at TEXT");
28453
- }
28454
- if (!colNames2.includes("pinned_at")) {
28455
- db.exec("ALTER TABLE messages ADD COLUMN pinned_at TEXT");
28456
- db.exec("CREATE INDEX IF NOT EXISTS idx_messages_pinned ON messages(pinned_at)");
28457
- }
28458
- return db;
28459
- }
28460
-
28461
28494
  // src/lib/messages.ts
28495
+ init_db();
28462
28496
  import { randomUUID } from "crypto";
28463
28497
  function parseMessage(row) {
28464
28498
  let metadata = null;
@@ -28471,7 +28505,8 @@ function parseMessage(row) {
28471
28505
  }
28472
28506
  return {
28473
28507
  ...row,
28474
- metadata
28508
+ metadata,
28509
+ blocking: !!row.blocking
28475
28510
  };
28476
28511
  }
28477
28512
  function sendMessage(opts) {
@@ -28480,12 +28515,13 @@ function sendMessage(opts) {
28480
28515
  const sessionId = explicitSession ?? (opts.space ? `space:${opts.space}` : `${[opts.from, opts.to].sort().join("-")}-${randomUUID().slice(0, 8)}`);
28481
28516
  const metadata = opts.metadata ? JSON.stringify(opts.metadata) : null;
28482
28517
  const normalizedPriority = opts.priority === "low" || opts.priority === "normal" || opts.priority === "high" || opts.priority === "urgent" ? opts.priority : "normal";
28518
+ const blocking = opts.blocking ? 1 : 0;
28483
28519
  const stmt = db2.prepare(`
28484
- INSERT INTO messages (session_id, from_agent, to_agent, space, content, priority, working_dir, repository, branch, metadata)
28485
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
28520
+ INSERT INTO messages (session_id, from_agent, to_agent, space, content, priority, working_dir, repository, branch, metadata, blocking)
28521
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
28486
28522
  RETURNING *
28487
28523
  `);
28488
- const row = stmt.get(sessionId, opts.from, opts.to, opts.space || null, opts.content, normalizedPriority, opts.working_dir || null, opts.repository || null, opts.branch || null, metadata);
28524
+ const row = stmt.get(sessionId, opts.from, opts.to, opts.space || null, opts.content, normalizedPriority, opts.working_dir || null, opts.repository || null, opts.branch || null, metadata, blocking);
28489
28525
  return parseMessage(row);
28490
28526
  }
28491
28527
  function readMessages(opts = {}) {
@@ -28642,6 +28678,19 @@ function getPinnedMessages(opts) {
28642
28678
  const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY pinned_at DESC, id DESC ${limit}`).all(...params);
28643
28679
  return rows.map(parseMessage);
28644
28680
  }
28681
+ function getUnreadBlockers(agent) {
28682
+ const db2 = getDb();
28683
+ const rows = db2.prepare(`
28684
+ SELECT * FROM messages
28685
+ WHERE blocking = 1 AND read_at IS NULL
28686
+ AND (
28687
+ to_agent = ?
28688
+ OR space IN (SELECT space FROM space_members WHERE agent = ?)
28689
+ )
28690
+ ORDER BY created_at ASC, id ASC
28691
+ `).all(agent, agent);
28692
+ return rows.map(parseMessage);
28693
+ }
28645
28694
  function searchMessages(opts) {
28646
28695
  const db2 = getDb();
28647
28696
  const conditions = ["content LIKE ?"];
@@ -28665,6 +28714,7 @@ function searchMessages(opts) {
28665
28714
  }
28666
28715
 
28667
28716
  // src/lib/sessions.ts
28717
+ init_db();
28668
28718
  function listSessions(agent) {
28669
28719
  const db2 = getDb();
28670
28720
  const agentFilter = agent ? "WHERE from_agent = ? OR to_agent = ?" : "";
@@ -28695,6 +28745,7 @@ function listSessions(agent) {
28695
28745
  }
28696
28746
 
28697
28747
  // src/lib/spaces.ts
28748
+ init_db();
28698
28749
  function getSpaceDepth(spaceName) {
28699
28750
  const db2 = getDb();
28700
28751
  let depth = 0;
@@ -28868,6 +28919,7 @@ function unarchiveSpace(name) {
28868
28919
  }
28869
28920
 
28870
28921
  // src/lib/projects.ts
28922
+ init_db();
28871
28923
  import { randomUUID as randomUUID2 } from "crypto";
28872
28924
  function parseProject(row) {
28873
28925
  let metadata = null;
@@ -29389,6 +29441,16 @@ var AGENT_NAMES = [
29389
29441
  // src/lib/identity.ts
29390
29442
  var AGENT_ID_FILE = join2(homedir2(), ".conversations", "agent-id");
29391
29443
  var cachedAutoName = null;
29444
+ function isNameTaken(name) {
29445
+ try {
29446
+ const { getDb: getDb2 } = (init_db(), __toCommonJS(exports_db));
29447
+ const db2 = getDb2();
29448
+ const row = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(name);
29449
+ return !!row;
29450
+ } catch {
29451
+ return false;
29452
+ }
29453
+ }
29392
29454
  function getAutoName() {
29393
29455
  if (cachedAutoName)
29394
29456
  return cachedAutoName;
@@ -29399,7 +29461,14 @@ function getAutoName() {
29399
29461
  return name2;
29400
29462
  }
29401
29463
  } catch {}
29402
- const name = AGENT_NAMES[Math.floor(Math.random() * AGENT_NAMES.length)];
29464
+ const shuffled = [...AGENT_NAMES].sort(() => Math.random() - 0.5);
29465
+ let name = shuffled[0];
29466
+ for (const candidate of shuffled) {
29467
+ if (!isNameTaken(candidate)) {
29468
+ name = candidate;
29469
+ break;
29470
+ }
29471
+ }
29403
29472
  cachedAutoName = name;
29404
29473
  try {
29405
29474
  mkdirSync2(dirname2(AGENT_ID_FILE), { recursive: true });
@@ -29419,6 +29488,7 @@ function resolveIdentity(explicit) {
29419
29488
  }
29420
29489
 
29421
29490
  // src/lib/presence.ts
29491
+ init_db();
29422
29492
  var ONLINE_THRESHOLD_SECONDS = 60;
29423
29493
  function parsePresence(row) {
29424
29494
  let metadata = null;
@@ -29484,12 +29554,13 @@ function renameAgent(oldName, newName) {
29484
29554
  // package.json
29485
29555
  var package_default = {
29486
29556
  name: "@hasna/conversations",
29487
- version: "0.1.5",
29557
+ version: "0.1.6",
29488
29558
  description: "Real-time CLI messaging for AI agents",
29489
29559
  type: "module",
29490
29560
  bin: {
29491
29561
  conversations: "bin/index.js",
29492
- "conversations-mcp": "bin/mcp.js"
29562
+ "conversations-mcp": "bin/mcp.js",
29563
+ "conversations-hook": "bin/hook.js"
29493
29564
  },
29494
29565
  exports: {
29495
29566
  ".": {
@@ -29507,7 +29578,7 @@ var package_default = {
29507
29578
  main: "./dist/index.js",
29508
29579
  types: "./dist/index.d.ts",
29509
29580
  scripts: {
29510
- build: "bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
29581
+ build: "bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/hooks/blocker-hook.ts --outfile ./bin/hook.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
29511
29582
  "build:dashboard": "cd dashboard && bun install && bun run build",
29512
29583
  test: "bun test",
29513
29584
  dev: "bun run ./src/cli/index.tsx",
@@ -29573,9 +29644,10 @@ server.registerTool("send_message", {
29573
29644
  working_dir: exports_external.string().optional().describe("Working directory context"),
29574
29645
  repository: exports_external.string().optional().describe("Repository context"),
29575
29646
  branch: exports_external.string().optional().describe("Branch context"),
29576
- metadata: exports_external.string().optional().describe("JSON metadata string")
29647
+ metadata: exports_external.string().optional().describe("JSON metadata string"),
29648
+ blocking: exports_external.boolean().optional().describe("Send as a blocking message. Recipients must acknowledge before continuing.")
29577
29649
  }
29578
- }, async ({ from: fromParam, to, content, session_id, priority, working_dir, repository, branch, metadata }) => {
29650
+ }, async ({ from: fromParam, to, content, session_id, priority, working_dir, repository, branch, metadata, blocking }) => {
29579
29651
  const from = resolveIdentity(fromParam);
29580
29652
  let parsedMetadata;
29581
29653
  if (metadata) {
@@ -29597,7 +29669,8 @@ server.registerTool("send_message", {
29597
29669
  working_dir,
29598
29670
  repository,
29599
29671
  branch,
29600
- metadata: parsedMetadata
29672
+ metadata: parsedMetadata,
29673
+ blocking
29601
29674
  });
29602
29675
  return {
29603
29676
  content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
@@ -29784,9 +29857,10 @@ server.registerTool("send_to_space", {
29784
29857
  from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
29785
29858
  space: exports_external.string().describe("Space name"),
29786
29859
  content: exports_external.string().describe("Message content"),
29787
- priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority")
29860
+ priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority"),
29861
+ blocking: exports_external.boolean().optional().describe("Send as a blocking message. All space members must acknowledge.")
29788
29862
  }
29789
- }, async ({ from: fromParam, space, content, priority }) => {
29863
+ }, async ({ from: fromParam, space, content, priority, blocking }) => {
29790
29864
  const from = resolveIdentity(fromParam);
29791
29865
  const sp = getSpace(space);
29792
29866
  if (!sp) {
@@ -29801,7 +29875,8 @@ server.registerTool("send_to_space", {
29801
29875
  content,
29802
29876
  space,
29803
29877
  session_id: `space:${space}`,
29804
- priority
29878
+ priority,
29879
+ blocking
29805
29880
  });
29806
29881
  return {
29807
29882
  content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
@@ -30240,6 +30315,19 @@ server.registerTool("list_agents", {
30240
30315
  content: [{ type: "text", text: JSON.stringify(agents, null, 2) }]
30241
30316
  };
30242
30317
  });
30318
+ server.registerTool("get_blockers", {
30319
+ title: "Get Blockers",
30320
+ description: "Check for unread blocking messages targeting you. Returns messages that must be acknowledged before continuing.",
30321
+ inputSchema: {
30322
+ from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var.")
30323
+ }
30324
+ }, async ({ from: fromParam }) => {
30325
+ const agent = resolveIdentity(fromParam);
30326
+ const blockers = getUnreadBlockers(agent);
30327
+ return {
30328
+ content: [{ type: "text", text: JSON.stringify(blockers, null, 2) }]
30329
+ };
30330
+ });
30243
30331
  server.registerTool("remove_agent", {
30244
30332
  title: "Remove Agent",
30245
30333
  description: "Remove an agent from the presence list. Only the agent itself should remove its own presence.",
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bun
2
+ export {};
package/dist/index.d.ts CHANGED
@@ -9,12 +9,12 @@
9
9
  * Or use the interactive TUI:
10
10
  * conversations
11
11
  */
12
- export { sendMessage, readMessages, markRead, markSessionRead, markSpaceRead, markAllRead, getMessageById, searchMessages, exportMessages, deleteMessage, editMessage, pinMessage, unpinMessage, getPinnedMessages, } from "./lib/messages.js";
12
+ export { sendMessage, readMessages, markRead, markSessionRead, markSpaceRead, markAllRead, getMessageById, searchMessages, exportMessages, deleteMessage, editMessage, pinMessage, unpinMessage, getPinnedMessages, getUnreadBlockers, } from "./lib/messages.js";
13
13
  export { listSessions, getSession, } from "./lib/sessions.js";
14
14
  export { createSpace, updateSpace, archiveSpace, unarchiveSpace, listSpaces, getSpace, joinSpace, leaveSpace, getSpaceMembers, isSpaceMember, getSpaceDepth, } from "./lib/spaces.js";
15
15
  export { createProject, listProjects, getProject, getProjectByName, updateProject, deleteProject, } from "./lib/projects.js";
16
16
  export { getDb, getDbPath, closeDb, } from "./lib/db.js";
17
17
  export { startPolling, useSpaceMessages, } from "./lib/poll.js";
18
18
  export { resolveIdentity, requireIdentity, } from "./lib/identity.js";
19
- export { heartbeat, getPresence, listAgents, removePresence, } from "./lib/presence.js";
19
+ export { heartbeat, getPresence, listAgents, removePresence, renameAgent, } from "./lib/presence.js";
20
20
  export type { Message, Session, Space, SpaceInfo, SpaceMember, Project, ProjectInfo, Priority, SendMessageOptions, ReadMessagesOptions, SearchMessagesOptions, AgentPresence, } from "./types.js";