@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/hook.js +626 -0
- package/bin/index.js +114 -16
- package/bin/mcp.js +244 -156
- package/dist/hooks/blocker-hook.d.ts +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +243 -153
- package/dist/lib/identity.d.ts +1 -1
- package/dist/lib/messages.d.ts +1 -0
- package/dist/types.d.ts +2 -0
- package/package.json +4 -3
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
|
|
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.
|
|
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.",
|
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";
|