@hasna/conversations 0.1.18 → 0.1.20
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 +37 -0
- package/bin/index.js +533 -298
- package/bin/mcp.js +312 -95
- package/dashboard/dist/assets/index-Bw0wMcXE.js +186 -0
- package/dashboard/dist/assets/index-CF_GDtNp.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +168 -16
- package/dist/lib/messages.d.ts +3 -0
- package/dist/lib/terminal-markdown.d.ts +11 -0
- package/dist/lib/webhooks.d.ts +11 -0
- package/dist/lib/webhooks.test.d.ts +1 -0
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/index-CCdh63JU.js +0 -186
- package/dashboard/dist/assets/index-VFT0_0LI.css +0 -1
package/bin/index.js
CHANGED
|
@@ -2045,6 +2045,43 @@ function getDb() {
|
|
|
2045
2045
|
if (!colNames2.includes("attachments")) {
|
|
2046
2046
|
db.exec("ALTER TABLE messages ADD COLUMN attachments TEXT");
|
|
2047
2047
|
}
|
|
2048
|
+
if (!colNames2.includes("reply_to")) {
|
|
2049
|
+
db.exec("ALTER TABLE messages ADD COLUMN reply_to INTEGER REFERENCES messages(id)");
|
|
2050
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_messages_reply_to ON messages(reply_to)");
|
|
2051
|
+
}
|
|
2052
|
+
const ftsExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='messages_fts'").get();
|
|
2053
|
+
if (!ftsExists) {
|
|
2054
|
+
db.exec(`
|
|
2055
|
+
CREATE VIRTUAL TABLE messages_fts USING fts5(
|
|
2056
|
+
content, from_agent, to_agent, space,
|
|
2057
|
+
content_rowid='id', content='messages'
|
|
2058
|
+
)
|
|
2059
|
+
`);
|
|
2060
|
+
db.exec(`
|
|
2061
|
+
INSERT INTO messages_fts(rowid, content, from_agent, to_agent, space)
|
|
2062
|
+
SELECT id, content, from_agent, to_agent, space FROM messages
|
|
2063
|
+
`);
|
|
2064
|
+
db.exec(`
|
|
2065
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON messages BEGIN
|
|
2066
|
+
INSERT INTO messages_fts(rowid, content, from_agent, to_agent, space)
|
|
2067
|
+
VALUES (new.id, new.content, new.from_agent, new.to_agent, new.space);
|
|
2068
|
+
END
|
|
2069
|
+
`);
|
|
2070
|
+
db.exec(`
|
|
2071
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_delete AFTER DELETE ON messages BEGIN
|
|
2072
|
+
INSERT INTO messages_fts(messages_fts, rowid, content, from_agent, to_agent, space)
|
|
2073
|
+
VALUES ('delete', old.id, old.content, old.from_agent, old.to_agent, old.space);
|
|
2074
|
+
END
|
|
2075
|
+
`);
|
|
2076
|
+
db.exec(`
|
|
2077
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE OF content ON messages BEGIN
|
|
2078
|
+
INSERT INTO messages_fts(messages_fts, rowid, content, from_agent, to_agent, space)
|
|
2079
|
+
VALUES ('delete', old.id, old.content, old.from_agent, old.to_agent, old.space);
|
|
2080
|
+
INSERT INTO messages_fts(rowid, content, from_agent, to_agent, space)
|
|
2081
|
+
VALUES (new.id, new.content, new.from_agent, new.to_agent, new.space);
|
|
2082
|
+
END
|
|
2083
|
+
`);
|
|
2084
|
+
}
|
|
2048
2085
|
return db;
|
|
2049
2086
|
}
|
|
2050
2087
|
function closeDb() {
|
|
@@ -2056,11 +2093,84 @@ function closeDb() {
|
|
|
2056
2093
|
var db = null;
|
|
2057
2094
|
var init_db = () => {};
|
|
2058
2095
|
|
|
2096
|
+
// src/lib/webhooks.ts
|
|
2097
|
+
import { readFileSync } from "fs";
|
|
2098
|
+
import { join as join2 } from "path";
|
|
2099
|
+
import { homedir as homedir2 } from "os";
|
|
2100
|
+
function getConfigPath() {
|
|
2101
|
+
return process.env.CONVERSATIONS_CONFIG_PATH || join2(homedir2(), ".conversations", "config.json");
|
|
2102
|
+
}
|
|
2103
|
+
function loadConfig() {
|
|
2104
|
+
const now = Date.now();
|
|
2105
|
+
if (cachedConfig && now - configLoadedAt < CONFIG_CACHE_MS)
|
|
2106
|
+
return cachedConfig;
|
|
2107
|
+
try {
|
|
2108
|
+
const raw = readFileSync(getConfigPath(), "utf-8");
|
|
2109
|
+
cachedConfig = JSON.parse(raw);
|
|
2110
|
+
configLoadedAt = now;
|
|
2111
|
+
return cachedConfig;
|
|
2112
|
+
} catch {
|
|
2113
|
+
cachedConfig = {};
|
|
2114
|
+
configLoadedAt = now;
|
|
2115
|
+
return cachedConfig;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
function matchesEvent(webhook, msg) {
|
|
2119
|
+
for (const event of webhook.events) {
|
|
2120
|
+
if (event === "dm" && !msg.space)
|
|
2121
|
+
return true;
|
|
2122
|
+
if (event === "blocker" && msg.blocking)
|
|
2123
|
+
return true;
|
|
2124
|
+
if (event === "space" && msg.space)
|
|
2125
|
+
return true;
|
|
2126
|
+
if (event === "mention" && webhook.agent && msg.content.includes(`@${webhook.agent}`))
|
|
2127
|
+
return true;
|
|
2128
|
+
}
|
|
2129
|
+
return false;
|
|
2130
|
+
}
|
|
2131
|
+
function fireWebhooks(msg) {
|
|
2132
|
+
const config = loadConfig();
|
|
2133
|
+
if (!config.webhooks || config.webhooks.length === 0)
|
|
2134
|
+
return;
|
|
2135
|
+
for (const webhook of config.webhooks) {
|
|
2136
|
+
if (webhook.agent && msg.to_agent !== webhook.agent && !msg.space)
|
|
2137
|
+
continue;
|
|
2138
|
+
if (!matchesEvent(webhook, msg))
|
|
2139
|
+
continue;
|
|
2140
|
+
fetch(webhook.url, {
|
|
2141
|
+
method: "POST",
|
|
2142
|
+
headers: { "Content-Type": "application/json" },
|
|
2143
|
+
body: JSON.stringify({
|
|
2144
|
+
id: msg.id,
|
|
2145
|
+
from: msg.from_agent,
|
|
2146
|
+
to: msg.to_agent,
|
|
2147
|
+
space: msg.space,
|
|
2148
|
+
content: msg.content,
|
|
2149
|
+
priority: msg.priority,
|
|
2150
|
+
blocking: msg.blocking,
|
|
2151
|
+
created_at: msg.created_at
|
|
2152
|
+
})
|
|
2153
|
+
}).catch(() => {});
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
var cachedConfig = null, configLoadedAt = 0, CONFIG_CACHE_MS = 1e4;
|
|
2157
|
+
var init_webhooks = () => {};
|
|
2158
|
+
|
|
2059
2159
|
// src/lib/messages.ts
|
|
2060
2160
|
import { randomUUID } from "crypto";
|
|
2061
2161
|
import { mkdirSync as mkdirSync2, copyFileSync, statSync } from "fs";
|
|
2062
|
-
import { join as
|
|
2063
|
-
import { homedir as
|
|
2162
|
+
import { join as join3 } from "path";
|
|
2163
|
+
import { homedir as homedir3 } from "os";
|
|
2164
|
+
function compactMessage(msg) {
|
|
2165
|
+
const result = {};
|
|
2166
|
+
for (const key of Object.keys(msg)) {
|
|
2167
|
+
const val = msg[key];
|
|
2168
|
+
if (val !== null && val !== undefined) {
|
|
2169
|
+
result[key] = val;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
return result;
|
|
2173
|
+
}
|
|
2064
2174
|
function parseMessage(row) {
|
|
2065
2175
|
let metadata = null;
|
|
2066
2176
|
if (row.metadata) {
|
|
@@ -2082,13 +2192,14 @@ function parseMessage(row) {
|
|
|
2082
2192
|
...row,
|
|
2083
2193
|
metadata,
|
|
2084
2194
|
attachments,
|
|
2085
|
-
blocking: !!row.blocking
|
|
2195
|
+
blocking: !!row.blocking,
|
|
2196
|
+
reply_to: row.reply_to || null
|
|
2086
2197
|
};
|
|
2087
2198
|
}
|
|
2088
2199
|
function getAttachmentsDir() {
|
|
2089
2200
|
if (process.env.CONVERSATIONS_ATTACHMENTS_DIR)
|
|
2090
2201
|
return process.env.CONVERSATIONS_ATTACHMENTS_DIR;
|
|
2091
|
-
return
|
|
2202
|
+
return join3(homedir3(), ".conversations", "attachments");
|
|
2092
2203
|
}
|
|
2093
2204
|
function guessMimeType(name) {
|
|
2094
2205
|
const ext = name.split(".").pop()?.toLowerCase();
|
|
@@ -2124,19 +2235,20 @@ function sendMessage(opts) {
|
|
|
2124
2235
|
const metadata = opts.metadata ? JSON.stringify(opts.metadata) : null;
|
|
2125
2236
|
const normalizedPriority = opts.priority === "low" || opts.priority === "normal" || opts.priority === "high" || opts.priority === "urgent" ? opts.priority : "normal";
|
|
2126
2237
|
const blocking = opts.blocking ? 1 : 0;
|
|
2238
|
+
const replyTo = opts.reply_to || null;
|
|
2127
2239
|
const stmt = db2.prepare(`
|
|
2128
|
-
INSERT INTO messages (session_id, from_agent, to_agent, space, content, priority, working_dir, repository, branch, metadata, blocking)
|
|
2129
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2240
|
+
INSERT INTO messages (session_id, from_agent, to_agent, space, content, priority, working_dir, repository, branch, metadata, blocking, reply_to)
|
|
2241
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2130
2242
|
RETURNING *
|
|
2131
2243
|
`);
|
|
2132
|
-
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);
|
|
2244
|
+
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, replyTo);
|
|
2133
2245
|
const message = parseMessage(row);
|
|
2134
2246
|
if (opts.attachments && opts.attachments.length > 0) {
|
|
2135
|
-
const attachmentsDir =
|
|
2247
|
+
const attachmentsDir = join3(getAttachmentsDir(), String(message.id));
|
|
2136
2248
|
mkdirSync2(attachmentsDir, { recursive: true });
|
|
2137
2249
|
const attachmentInfos = [];
|
|
2138
2250
|
for (const att of opts.attachments) {
|
|
2139
|
-
const destPath =
|
|
2251
|
+
const destPath = join3(attachmentsDir, att.name);
|
|
2140
2252
|
copyFileSync(att.source_path, destPath);
|
|
2141
2253
|
const stat = statSync(destPath);
|
|
2142
2254
|
attachmentInfos.push({
|
|
@@ -2150,6 +2262,7 @@ function sendMessage(opts) {
|
|
|
2150
2262
|
db2.prepare("UPDATE messages SET attachments = ? WHERE id = ?").run(attachmentsJson, message.id);
|
|
2151
2263
|
message.attachments = attachmentInfos;
|
|
2152
2264
|
}
|
|
2265
|
+
fireWebhooks(message);
|
|
2153
2266
|
return message;
|
|
2154
2267
|
}
|
|
2155
2268
|
function readMessages(opts = {}) {
|
|
@@ -2184,10 +2297,13 @@ function readMessages(opts = {}) {
|
|
|
2184
2297
|
conditions.push("read_at IS NULL");
|
|
2185
2298
|
}
|
|
2186
2299
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2187
|
-
const
|
|
2300
|
+
const resolvedLimit = Number.isFinite(opts.limit) && opts.limit > 0 ? Math.floor(opts.limit) : 20;
|
|
2188
2301
|
const order = opts.order?.toLowerCase() === "desc" ? "DESC" : "ASC";
|
|
2189
|
-
const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY created_at ${order}, id ${order} ${
|
|
2190
|
-
|
|
2302
|
+
const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY created_at ${order}, id ${order} LIMIT ${resolvedLimit}`).all(...params);
|
|
2303
|
+
const messages = rows.map(parseMessage);
|
|
2304
|
+
if (opts.compact)
|
|
2305
|
+
return messages.map(compactMessage);
|
|
2306
|
+
return messages;
|
|
2191
2307
|
}
|
|
2192
2308
|
function markRead(ids, reader) {
|
|
2193
2309
|
const db2 = getDb();
|
|
@@ -2333,6 +2449,33 @@ function getUnreadBlockers(agent) {
|
|
|
2333
2449
|
}
|
|
2334
2450
|
function searchMessages(opts) {
|
|
2335
2451
|
const db2 = getDb();
|
|
2452
|
+
const limit = Number.isFinite(opts.limit) && opts.limit > 0 ? Math.floor(opts.limit) : 20;
|
|
2453
|
+
try {
|
|
2454
|
+
const ftsConditions = [];
|
|
2455
|
+
const ftsParams = [];
|
|
2456
|
+
const words = opts.query.trim().split(/\s+/).filter(Boolean);
|
|
2457
|
+
const ftsQuery = words.map((w) => `"${w.replace(/"/g, '""')}"`).join(" ");
|
|
2458
|
+
ftsConditions.push("messages_fts MATCH ?");
|
|
2459
|
+
ftsParams.push(ftsQuery);
|
|
2460
|
+
let extraWhere = "";
|
|
2461
|
+
if (opts.space) {
|
|
2462
|
+
extraWhere += " AND m.space = ?";
|
|
2463
|
+
ftsParams.push(opts.space);
|
|
2464
|
+
}
|
|
2465
|
+
if (opts.from) {
|
|
2466
|
+
extraWhere += " AND m.from_agent = ?";
|
|
2467
|
+
ftsParams.push(opts.from);
|
|
2468
|
+
}
|
|
2469
|
+
if (opts.to) {
|
|
2470
|
+
extraWhere += " AND m.to_agent = ?";
|
|
2471
|
+
ftsParams.push(opts.to);
|
|
2472
|
+
}
|
|
2473
|
+
const rows2 = db2.prepare(`SELECT m.* FROM messages m
|
|
2474
|
+
JOIN messages_fts ON messages_fts.rowid = m.id
|
|
2475
|
+
WHERE ${ftsConditions.join(" AND ")}${extraWhere}
|
|
2476
|
+
ORDER BY m.created_at DESC, m.id DESC LIMIT ${limit}`).all(...ftsParams);
|
|
2477
|
+
return rows2.map(parseMessage);
|
|
2478
|
+
} catch {}
|
|
2336
2479
|
const conditions = ["content LIKE ?"];
|
|
2337
2480
|
const params = [`%${opts.query}%`];
|
|
2338
2481
|
if (opts.space) {
|
|
@@ -2347,13 +2490,13 @@ function searchMessages(opts) {
|
|
|
2347
2490
|
conditions.push("to_agent = ?");
|
|
2348
2491
|
params.push(opts.to);
|
|
2349
2492
|
}
|
|
2350
|
-
const limit = Number.isFinite(opts.limit) && opts.limit > 0 ? Math.floor(opts.limit) : 50;
|
|
2351
2493
|
const where = `WHERE ${conditions.join(" AND ")}`;
|
|
2352
2494
|
const rows = db2.prepare(`SELECT * FROM messages ${where} ORDER BY created_at DESC, id DESC LIMIT ${limit}`).all(...params);
|
|
2353
2495
|
return rows.map(parseMessage);
|
|
2354
2496
|
}
|
|
2355
2497
|
var init_messages = __esm(() => {
|
|
2356
2498
|
init_db();
|
|
2499
|
+
init_webhooks();
|
|
2357
2500
|
});
|
|
2358
2501
|
|
|
2359
2502
|
// src/lib/sessions.ts
|
|
@@ -3090,9 +3233,9 @@ var init_names = __esm(() => {
|
|
|
3090
3233
|
});
|
|
3091
3234
|
|
|
3092
3235
|
// src/lib/identity.ts
|
|
3093
|
-
import { readFileSync, writeFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
3094
|
-
import { join as
|
|
3095
|
-
import { homedir as
|
|
3236
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
3237
|
+
import { join as join4, dirname as dirname2 } from "path";
|
|
3238
|
+
import { homedir as homedir4 } from "os";
|
|
3096
3239
|
function isNameTaken(name) {
|
|
3097
3240
|
try {
|
|
3098
3241
|
const { getDb: getDb2 } = (init_db(), __toCommonJS(exports_db));
|
|
@@ -3107,7 +3250,7 @@ function getAutoName() {
|
|
|
3107
3250
|
if (cachedAutoName)
|
|
3108
3251
|
return cachedAutoName;
|
|
3109
3252
|
try {
|
|
3110
|
-
const name2 =
|
|
3253
|
+
const name2 = readFileSync2(AGENT_ID_FILE, "utf-8").trim();
|
|
3111
3254
|
if (name2) {
|
|
3112
3255
|
cachedAutoName = name2;
|
|
3113
3256
|
return name2;
|
|
@@ -3141,7 +3284,7 @@ function resolveIdentity(explicit) {
|
|
|
3141
3284
|
var AGENT_ID_FILE, cachedAutoName = null;
|
|
3142
3285
|
var init_identity = __esm(() => {
|
|
3143
3286
|
init_names();
|
|
3144
|
-
AGENT_ID_FILE =
|
|
3287
|
+
AGENT_ID_FILE = join4(homedir4(), ".conversations", "agent-id");
|
|
3145
3288
|
});
|
|
3146
3289
|
|
|
3147
3290
|
// src/lib/presence.ts
|
|
@@ -3216,6 +3359,52 @@ var init_presence = __esm(() => {
|
|
|
3216
3359
|
init_db();
|
|
3217
3360
|
});
|
|
3218
3361
|
|
|
3362
|
+
// src/lib/terminal-markdown.ts
|
|
3363
|
+
var exports_terminal_markdown = {};
|
|
3364
|
+
__export(exports_terminal_markdown, {
|
|
3365
|
+
renderInline: () => renderInline,
|
|
3366
|
+
renderContent: () => renderContent
|
|
3367
|
+
});
|
|
3368
|
+
import chalk from "chalk";
|
|
3369
|
+
var renderInline = (text) => {
|
|
3370
|
+
return text.replace(/`([^`]+)`/g, (_, code) => chalk.bgGray.white(` ${code} `)).replace(/\*\*\*(.+?)\*\*\*/g, (_, t) => chalk.bold.italic(t)).replace(/\*\*(.+?)\*\*/g, (_, t) => chalk.bold(t)).replace(/\*(.+?)\*/g, (_, t) => chalk.italic(t)).replace(/~~(.+?)~~/g, (_, t) => chalk.strikethrough(t));
|
|
3371
|
+
}, renderContent = (content) => {
|
|
3372
|
+
const lines = content.split(`
|
|
3373
|
+
`);
|
|
3374
|
+
const rendered = [];
|
|
3375
|
+
for (const line of lines) {
|
|
3376
|
+
let l = line;
|
|
3377
|
+
const h = l.match(/^(#{1,3})\s+(.+)/);
|
|
3378
|
+
if (h) {
|
|
3379
|
+
rendered.push(chalk.bold(h[2]));
|
|
3380
|
+
continue;
|
|
3381
|
+
}
|
|
3382
|
+
if (/^\s*[-*+]\s/.test(l)) {
|
|
3383
|
+
rendered.push(" " + chalk.dim("\u2022") + " " + renderInline(l.replace(/^\s*[-*+]\s/, "")));
|
|
3384
|
+
continue;
|
|
3385
|
+
}
|
|
3386
|
+
const ol = l.match(/^\s*(\d+)[.)]\s(.*)/);
|
|
3387
|
+
if (ol) {
|
|
3388
|
+
rendered.push(" " + chalk.dim(ol[1] + ".") + " " + renderInline(ol[2]));
|
|
3389
|
+
continue;
|
|
3390
|
+
}
|
|
3391
|
+
if (l.startsWith(">")) {
|
|
3392
|
+
rendered.push(chalk.dim(" \u2502 ") + chalk.italic(renderInline(l.replace(/^>\s?/, ""))));
|
|
3393
|
+
continue;
|
|
3394
|
+
}
|
|
3395
|
+
if (l.trimStart().startsWith("```"))
|
|
3396
|
+
continue;
|
|
3397
|
+
if (l.trim() === "") {
|
|
3398
|
+
rendered.push("");
|
|
3399
|
+
continue;
|
|
3400
|
+
}
|
|
3401
|
+
rendered.push(renderInline(l));
|
|
3402
|
+
}
|
|
3403
|
+
return rendered.join(`
|
|
3404
|
+
`);
|
|
3405
|
+
};
|
|
3406
|
+
var init_terminal_markdown = () => {};
|
|
3407
|
+
|
|
3219
3408
|
// src/lib/poll.ts
|
|
3220
3409
|
var exports_poll = {};
|
|
3221
3410
|
__export(exports_poll, {
|
|
@@ -3314,7 +3503,7 @@ var init_poll = __esm(() => {
|
|
|
3314
3503
|
var require_package = __commonJS((exports, module) => {
|
|
3315
3504
|
module.exports = {
|
|
3316
3505
|
name: "@hasna/conversations",
|
|
3317
|
-
version: "0.1.
|
|
3506
|
+
version: "0.1.20",
|
|
3318
3507
|
description: "Real-time CLI messaging for AI agents",
|
|
3319
3508
|
type: "module",
|
|
3320
3509
|
bin: {
|
|
@@ -32286,9 +32475,9 @@ var init_mcp2 = __esm(() => {
|
|
|
32286
32475
|
});
|
|
32287
32476
|
server.registerTool("send_message", {
|
|
32288
32477
|
title: "Send Message",
|
|
32289
|
-
description: "Send a direct message to another agent.
|
|
32478
|
+
description: "Send a direct message to another agent.",
|
|
32290
32479
|
inputSchema: {
|
|
32291
|
-
from: exports_external.string().optional().describe("Your agent ID
|
|
32480
|
+
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32292
32481
|
to: exports_external.string().describe("Recipient agent ID"),
|
|
32293
32482
|
content: exports_external.string().describe("Message content"),
|
|
32294
32483
|
session_id: exports_external.string().optional().describe("Session ID (auto-generated if omitted)"),
|
|
@@ -32297,7 +32486,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32297
32486
|
repository: exports_external.string().optional().describe("Repository context"),
|
|
32298
32487
|
branch: exports_external.string().optional().describe("Branch context"),
|
|
32299
32488
|
metadata: exports_external.string().optional().describe("JSON metadata string"),
|
|
32300
|
-
blocking: exports_external.boolean().optional().describe("
|
|
32489
|
+
blocking: exports_external.boolean().optional().describe("Blocking message \u2014 recipients must acknowledge before continuing")
|
|
32301
32490
|
}
|
|
32302
32491
|
}, async ({ from: fromParam, to, content, session_id, priority, working_dir, repository, branch, metadata, blocking }) => {
|
|
32303
32492
|
const from = resolveIdentity(fromParam);
|
|
@@ -32307,7 +32496,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32307
32496
|
parsedMetadata = JSON.parse(metadata);
|
|
32308
32497
|
} catch {
|
|
32309
32498
|
return {
|
|
32310
|
-
content: [{ type: "text", text: "
|
|
32499
|
+
content: [{ type: "text", text: "invalid JSON" }],
|
|
32311
32500
|
isError: true
|
|
32312
32501
|
};
|
|
32313
32502
|
}
|
|
@@ -32330,15 +32519,15 @@ var init_mcp2 = __esm(() => {
|
|
|
32330
32519
|
});
|
|
32331
32520
|
server.registerTool("read_messages", {
|
|
32332
32521
|
title: "Read Messages",
|
|
32333
|
-
description: "Read messages with
|
|
32522
|
+
description: "Read messages with filters, newest first.",
|
|
32334
32523
|
inputSchema: {
|
|
32335
32524
|
session_id: exports_external.string().optional().describe("Filter by session ID"),
|
|
32336
|
-
from: exports_external.string().optional().describe("Filter by sender
|
|
32337
|
-
to: exports_external.string().optional().describe("Filter by recipient
|
|
32525
|
+
from: exports_external.string().optional().describe("Filter by sender"),
|
|
32526
|
+
to: exports_external.string().optional().describe("Filter by recipient"),
|
|
32338
32527
|
space: exports_external.string().optional().describe("Filter by space name"),
|
|
32339
|
-
since: exports_external.string().optional().describe("
|
|
32340
|
-
limit: exports_external.number().optional().describe("Max messages to return"),
|
|
32341
|
-
unread_only: exports_external.boolean().optional().describe("Only
|
|
32528
|
+
since: exports_external.string().optional().describe("ISO timestamp lower bound"),
|
|
32529
|
+
limit: exports_external.number().optional().describe("Max messages to return (default 20)"),
|
|
32530
|
+
unread_only: exports_external.boolean().optional().describe("Only unread messages")
|
|
32342
32531
|
}
|
|
32343
32532
|
}, async (opts) => {
|
|
32344
32533
|
const messages = readMessages(opts);
|
|
@@ -32348,7 +32537,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32348
32537
|
});
|
|
32349
32538
|
server.registerTool("list_sessions", {
|
|
32350
32539
|
title: "List Sessions",
|
|
32351
|
-
description: "List
|
|
32540
|
+
description: "List sessions, optionally filtered by agent.",
|
|
32352
32541
|
inputSchema: {
|
|
32353
32542
|
agent: exports_external.string().optional().describe("Filter sessions involving this agent")
|
|
32354
32543
|
}
|
|
@@ -32360,7 +32549,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32360
32549
|
});
|
|
32361
32550
|
server.registerTool("reply", {
|
|
32362
32551
|
title: "Reply to Message",
|
|
32363
|
-
description: "Reply to a message
|
|
32552
|
+
description: "Reply to a message (same session, original sender).",
|
|
32364
32553
|
inputSchema: {
|
|
32365
32554
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32366
32555
|
message_id: exports_external.number().describe("ID of the message to reply to"),
|
|
@@ -32392,7 +32581,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32392
32581
|
});
|
|
32393
32582
|
server.registerTool("mark_read", {
|
|
32394
32583
|
title: "Mark Read",
|
|
32395
|
-
description: "Mark
|
|
32584
|
+
description: "Mark messages as read. Provide IDs or set 'all' to true.",
|
|
32396
32585
|
inputSchema: {
|
|
32397
32586
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32398
32587
|
ids: exports_external.array(exports_external.number()).optional().describe("Message IDs to mark as read"),
|
|
@@ -32407,7 +32596,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32407
32596
|
count = markRead(ids, agent);
|
|
32408
32597
|
} else {
|
|
32409
32598
|
return {
|
|
32410
|
-
content: [{ type: "text", text: "
|
|
32599
|
+
content: [{ type: "text", text: "provide ids or set all=true" }],
|
|
32411
32600
|
isError: true
|
|
32412
32601
|
};
|
|
32413
32602
|
}
|
|
@@ -32417,13 +32606,13 @@ var init_mcp2 = __esm(() => {
|
|
|
32417
32606
|
});
|
|
32418
32607
|
server.registerTool("search_messages", {
|
|
32419
32608
|
title: "Search Messages",
|
|
32420
|
-
description: "Full-text search across message content
|
|
32609
|
+
description: "Full-text search across message content, newest first.",
|
|
32421
32610
|
inputSchema: {
|
|
32422
|
-
query: exports_external.string().describe("Search query
|
|
32423
|
-
space: exports_external.string().optional().describe("Filter by space
|
|
32424
|
-
from: exports_external.string().optional().describe("Filter by sender
|
|
32425
|
-
to: exports_external.string().optional().describe("Filter by recipient
|
|
32426
|
-
limit: exports_external.number().optional().describe("Max results
|
|
32611
|
+
query: exports_external.string().describe("Search query"),
|
|
32612
|
+
space: exports_external.string().optional().describe("Filter by space"),
|
|
32613
|
+
from: exports_external.string().optional().describe("Filter by sender"),
|
|
32614
|
+
to: exports_external.string().optional().describe("Filter by recipient"),
|
|
32615
|
+
limit: exports_external.number().optional().describe("Max results (default 20)")
|
|
32427
32616
|
}
|
|
32428
32617
|
}, async ({ query, space, from, to, limit }) => {
|
|
32429
32618
|
const messages = searchMessages({ query, space, from, to, limit });
|
|
@@ -32435,11 +32624,11 @@ var init_mcp2 = __esm(() => {
|
|
|
32435
32624
|
title: "Export Messages",
|
|
32436
32625
|
description: "Export messages as JSON or CSV with optional filters.",
|
|
32437
32626
|
inputSchema: {
|
|
32438
|
-
space: exports_external.string().optional().describe("Filter by space
|
|
32627
|
+
space: exports_external.string().optional().describe("Filter by space"),
|
|
32439
32628
|
session_id: exports_external.string().optional().describe("Filter by session ID"),
|
|
32440
|
-
from: exports_external.string().optional().describe("Filter by sender
|
|
32441
|
-
since: exports_external.string().optional().describe("
|
|
32442
|
-
until: exports_external.string().optional().describe("
|
|
32629
|
+
from: exports_external.string().optional().describe("Filter by sender"),
|
|
32630
|
+
since: exports_external.string().optional().describe("ISO date lower bound"),
|
|
32631
|
+
until: exports_external.string().optional().describe("ISO date upper bound"),
|
|
32443
32632
|
format: exports_external.enum(["json", "csv"]).optional().describe("Output format (default: json)")
|
|
32444
32633
|
}
|
|
32445
32634
|
}, async ({ space, session_id, from, since, until, format }) => {
|
|
@@ -32450,13 +32639,13 @@ var init_mcp2 = __esm(() => {
|
|
|
32450
32639
|
});
|
|
32451
32640
|
server.registerTool("create_space", {
|
|
32452
32641
|
title: "Create Space",
|
|
32453
|
-
description: "Create a
|
|
32642
|
+
description: "Create a space. Auto-joined. Supports nesting and projects.",
|
|
32454
32643
|
inputSchema: {
|
|
32455
32644
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32456
|
-
name: exports_external.string().describe("Space name
|
|
32645
|
+
name: exports_external.string().describe("Space name"),
|
|
32457
32646
|
description: exports_external.string().optional().describe("Space description"),
|
|
32458
|
-
parent_id: exports_external.string().optional().describe("Parent space name
|
|
32459
|
-
project_id: exports_external.string().optional().describe("Project ID to associate
|
|
32647
|
+
parent_id: exports_external.string().optional().describe("Parent space name (max 3 levels deep)"),
|
|
32648
|
+
project_id: exports_external.string().optional().describe("Project ID to associate with")
|
|
32460
32649
|
}
|
|
32461
32650
|
}, async ({ from: fromParam, name, description, parent_id, project_id }) => {
|
|
32462
32651
|
const agent = resolveIdentity(fromParam);
|
|
@@ -32468,7 +32657,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32468
32657
|
} catch (e) {
|
|
32469
32658
|
if (e.message?.includes("UNIQUE constraint")) {
|
|
32470
32659
|
return {
|
|
32471
|
-
content: [{ type: "text", text: `
|
|
32660
|
+
content: [{ type: "text", text: `space "${name}" already exists` }],
|
|
32472
32661
|
isError: true
|
|
32473
32662
|
};
|
|
32474
32663
|
}
|
|
@@ -32480,11 +32669,11 @@ var init_mcp2 = __esm(() => {
|
|
|
32480
32669
|
});
|
|
32481
32670
|
server.registerTool("list_spaces", {
|
|
32482
32671
|
title: "List Spaces",
|
|
32483
|
-
description: "List
|
|
32672
|
+
description: "List spaces with member/message counts.",
|
|
32484
32673
|
inputSchema: {
|
|
32485
32674
|
project_id: exports_external.string().optional().describe("Filter by project ID"),
|
|
32486
|
-
parent_id: exports_external.string().optional().describe("Filter by parent space
|
|
32487
|
-
include_archived: exports_external.boolean().optional().describe("Include archived spaces
|
|
32675
|
+
parent_id: exports_external.string().optional().describe("Filter by parent space. Use 'null' for top-level only."),
|
|
32676
|
+
include_archived: exports_external.boolean().optional().describe("Include archived spaces")
|
|
32488
32677
|
}
|
|
32489
32678
|
}, async ({ project_id, parent_id, include_archived }) => {
|
|
32490
32679
|
const opts = {};
|
|
@@ -32510,14 +32699,14 @@ var init_mcp2 = __esm(() => {
|
|
|
32510
32699
|
space: exports_external.string().describe("Space name"),
|
|
32511
32700
|
content: exports_external.string().describe("Message content"),
|
|
32512
32701
|
priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority"),
|
|
32513
|
-
blocking: exports_external.boolean().optional().describe("
|
|
32702
|
+
blocking: exports_external.boolean().optional().describe("Blocking message \u2014 all space members must acknowledge")
|
|
32514
32703
|
}
|
|
32515
32704
|
}, async ({ from: fromParam, space, content, priority, blocking }) => {
|
|
32516
32705
|
const from = resolveIdentity(fromParam);
|
|
32517
32706
|
const sp = getSpace(space);
|
|
32518
32707
|
if (!sp) {
|
|
32519
32708
|
return {
|
|
32520
|
-
content: [{ type: "text", text: `
|
|
32709
|
+
content: [{ type: "text", text: `space "${space}" not found` }],
|
|
32521
32710
|
isError: true
|
|
32522
32711
|
};
|
|
32523
32712
|
}
|
|
@@ -32539,7 +32728,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32539
32728
|
description: "Read messages from a space.",
|
|
32540
32729
|
inputSchema: {
|
|
32541
32730
|
space: exports_external.string().describe("Space name"),
|
|
32542
|
-
since: exports_external.string().optional().describe("
|
|
32731
|
+
since: exports_external.string().optional().describe("ISO timestamp lower bound"),
|
|
32543
32732
|
limit: exports_external.number().optional().describe("Max messages to return")
|
|
32544
32733
|
}
|
|
32545
32734
|
}, async ({ space, since, limit }) => {
|
|
@@ -32560,7 +32749,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32560
32749
|
const ok = joinSpace(space, agent);
|
|
32561
32750
|
if (!ok) {
|
|
32562
32751
|
return {
|
|
32563
|
-
content: [{ type: "text", text: `
|
|
32752
|
+
content: [{ type: "text", text: `space "${space}" not found` }],
|
|
32564
32753
|
isError: true
|
|
32565
32754
|
};
|
|
32566
32755
|
}
|
|
@@ -32584,12 +32773,12 @@ var init_mcp2 = __esm(() => {
|
|
|
32584
32773
|
});
|
|
32585
32774
|
server.registerTool("update_space", {
|
|
32586
32775
|
title: "Update Space",
|
|
32587
|
-
description: "Update a space's description, parent, or project
|
|
32776
|
+
description: "Update a space's description, parent, or project.",
|
|
32588
32777
|
inputSchema: {
|
|
32589
|
-
name: exports_external.string().describe("Space name
|
|
32778
|
+
name: exports_external.string().describe("Space name"),
|
|
32590
32779
|
description: exports_external.string().optional().describe("New description"),
|
|
32591
|
-
parent_id: exports_external.string().optional().describe("New parent space
|
|
32592
|
-
project_id: exports_external.string().optional().describe("New project ID (use 'null' to remove
|
|
32780
|
+
parent_id: exports_external.string().optional().describe("New parent space (use 'null' to remove)"),
|
|
32781
|
+
project_id: exports_external.string().optional().describe("New project ID (use 'null' to remove)")
|
|
32593
32782
|
}
|
|
32594
32783
|
}, async ({ name, description, parent_id, project_id }) => {
|
|
32595
32784
|
const updates = {};
|
|
@@ -32613,7 +32802,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32613
32802
|
});
|
|
32614
32803
|
server.registerTool("archive_space", {
|
|
32615
32804
|
title: "Archive Space",
|
|
32616
|
-
description: "Archive a space.
|
|
32805
|
+
description: "Archive a space. Hidden from list by default.",
|
|
32617
32806
|
inputSchema: {
|
|
32618
32807
|
name: exports_external.string().describe("Space name to archive")
|
|
32619
32808
|
}
|
|
@@ -32651,16 +32840,16 @@ var init_mcp2 = __esm(() => {
|
|
|
32651
32840
|
});
|
|
32652
32841
|
server.registerTool("create_project", {
|
|
32653
32842
|
title: "Create Project",
|
|
32654
|
-
description: "Create a
|
|
32843
|
+
description: "Create a project for spaces and agent collaboration.",
|
|
32655
32844
|
inputSchema: {
|
|
32656
32845
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32657
32846
|
name: exports_external.string().describe("Project name (unique)"),
|
|
32658
32847
|
description: exports_external.string().optional().describe("Project description"),
|
|
32659
|
-
path: exports_external.string().optional().describe("Absolute path
|
|
32848
|
+
path: exports_external.string().optional().describe("Absolute path on disk"),
|
|
32660
32849
|
repository: exports_external.string().optional().describe("Repository URL"),
|
|
32661
|
-
tags: exports_external.string().optional().describe(
|
|
32662
|
-
metadata: exports_external.string().optional().describe("JSON metadata
|
|
32663
|
-
settings: exports_external.string().optional().describe("JSON settings
|
|
32850
|
+
tags: exports_external.string().optional().describe("JSON array of tags"),
|
|
32851
|
+
metadata: exports_external.string().optional().describe("JSON metadata"),
|
|
32852
|
+
settings: exports_external.string().optional().describe("JSON settings")
|
|
32664
32853
|
}
|
|
32665
32854
|
}, async ({ from: fromParam, name, description, path, repository, tags, metadata, settings }) => {
|
|
32666
32855
|
const agent = resolveIdentity(fromParam);
|
|
@@ -32670,7 +32859,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32670
32859
|
parsedTags = JSON.parse(tags);
|
|
32671
32860
|
} catch {
|
|
32672
32861
|
return {
|
|
32673
|
-
content: [{ type: "text", text: "
|
|
32862
|
+
content: [{ type: "text", text: "invalid tags JSON (expected array)" }],
|
|
32674
32863
|
isError: true
|
|
32675
32864
|
};
|
|
32676
32865
|
}
|
|
@@ -32681,7 +32870,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32681
32870
|
parsedMetadata = JSON.parse(metadata);
|
|
32682
32871
|
} catch {
|
|
32683
32872
|
return {
|
|
32684
|
-
content: [{ type: "text", text: "
|
|
32873
|
+
content: [{ type: "text", text: "invalid JSON" }],
|
|
32685
32874
|
isError: true
|
|
32686
32875
|
};
|
|
32687
32876
|
}
|
|
@@ -32692,7 +32881,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32692
32881
|
parsedSettings = JSON.parse(settings);
|
|
32693
32882
|
} catch {
|
|
32694
32883
|
return {
|
|
32695
|
-
content: [{ type: "text", text: "
|
|
32884
|
+
content: [{ type: "text", text: "invalid JSON" }],
|
|
32696
32885
|
isError: true
|
|
32697
32886
|
};
|
|
32698
32887
|
}
|
|
@@ -32714,7 +32903,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32714
32903
|
} catch (e) {
|
|
32715
32904
|
if (e.message?.includes("UNIQUE constraint")) {
|
|
32716
32905
|
return {
|
|
32717
|
-
content: [{ type: "text", text: `
|
|
32906
|
+
content: [{ type: "text", text: `project "${name}" already exists` }],
|
|
32718
32907
|
isError: true
|
|
32719
32908
|
};
|
|
32720
32909
|
}
|
|
@@ -32728,7 +32917,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32728
32917
|
title: "List Projects",
|
|
32729
32918
|
description: "List all registered projects.",
|
|
32730
32919
|
inputSchema: {
|
|
32731
|
-
status: exports_external.enum(["active", "archived"]).optional().describe("Filter by
|
|
32920
|
+
status: exports_external.enum(["active", "archived"]).optional().describe("Filter by status")
|
|
32732
32921
|
}
|
|
32733
32922
|
}, async ({ status }) => {
|
|
32734
32923
|
const projects = listProjects(status ? { status } : undefined);
|
|
@@ -32749,7 +32938,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32749
32938
|
}
|
|
32750
32939
|
if (!project) {
|
|
32751
32940
|
return {
|
|
32752
|
-
content: [{ type: "text", text: `
|
|
32941
|
+
content: [{ type: "text", text: `project "${id}" not found` }],
|
|
32753
32942
|
isError: true
|
|
32754
32943
|
};
|
|
32755
32944
|
}
|
|
@@ -32762,14 +32951,14 @@ var init_mcp2 = __esm(() => {
|
|
|
32762
32951
|
description: "Update a project's fields.",
|
|
32763
32952
|
inputSchema: {
|
|
32764
32953
|
id: exports_external.string().describe("Project ID (UUID)"),
|
|
32765
|
-
name: exports_external.string().optional().describe("New
|
|
32954
|
+
name: exports_external.string().optional().describe("New name"),
|
|
32766
32955
|
description: exports_external.string().optional().describe("New description"),
|
|
32767
32956
|
path: exports_external.string().optional().describe("New path"),
|
|
32768
32957
|
status: exports_external.enum(["active", "archived"]).optional().describe("New status"),
|
|
32769
32958
|
repository: exports_external.string().optional().describe("New repository URL"),
|
|
32770
32959
|
tags: exports_external.string().optional().describe("JSON array of tags"),
|
|
32771
|
-
metadata: exports_external.string().optional().describe("JSON metadata
|
|
32772
|
-
settings: exports_external.string().optional().describe("JSON settings
|
|
32960
|
+
metadata: exports_external.string().optional().describe("JSON metadata"),
|
|
32961
|
+
settings: exports_external.string().optional().describe("JSON settings")
|
|
32773
32962
|
}
|
|
32774
32963
|
}, async ({ id, name, description, path, status, repository, tags, metadata, settings }) => {
|
|
32775
32964
|
const updates = {};
|
|
@@ -32788,7 +32977,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32788
32977
|
updates.tags = JSON.parse(tags);
|
|
32789
32978
|
} catch {
|
|
32790
32979
|
return {
|
|
32791
|
-
content: [{ type: "text", text: "
|
|
32980
|
+
content: [{ type: "text", text: "invalid tags JSON" }],
|
|
32792
32981
|
isError: true
|
|
32793
32982
|
};
|
|
32794
32983
|
}
|
|
@@ -32798,7 +32987,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32798
32987
|
updates.metadata = JSON.parse(metadata);
|
|
32799
32988
|
} catch {
|
|
32800
32989
|
return {
|
|
32801
|
-
content: [{ type: "text", text: "
|
|
32990
|
+
content: [{ type: "text", text: "invalid JSON" }],
|
|
32802
32991
|
isError: true
|
|
32803
32992
|
};
|
|
32804
32993
|
}
|
|
@@ -32808,7 +32997,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32808
32997
|
updates.settings = JSON.parse(settings);
|
|
32809
32998
|
} catch {
|
|
32810
32999
|
return {
|
|
32811
|
-
content: [{ type: "text", text: "
|
|
33000
|
+
content: [{ type: "text", text: "invalid JSON" }],
|
|
32812
33001
|
isError: true
|
|
32813
33002
|
};
|
|
32814
33003
|
}
|
|
@@ -32827,7 +33016,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32827
33016
|
});
|
|
32828
33017
|
server.registerTool("delete_project", {
|
|
32829
33018
|
title: "Delete Project",
|
|
32830
|
-
description: "Delete a project permanently. Fails if spaces
|
|
33019
|
+
description: "Delete a project permanently. Fails if spaces reference it.",
|
|
32831
33020
|
inputSchema: {
|
|
32832
33021
|
id: exports_external.string().describe("Project ID (UUID)")
|
|
32833
33022
|
}
|
|
@@ -32836,7 +33025,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32836
33025
|
const deleted = deleteProject(id);
|
|
32837
33026
|
if (!deleted) {
|
|
32838
33027
|
return {
|
|
32839
|
-
content: [{ type: "text", text: `
|
|
33028
|
+
content: [{ type: "text", text: `project "${id}" not found` }],
|
|
32840
33029
|
isError: true
|
|
32841
33030
|
};
|
|
32842
33031
|
}
|
|
@@ -32852,7 +33041,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32852
33041
|
});
|
|
32853
33042
|
server.registerTool("delete_message", {
|
|
32854
33043
|
title: "Delete Message",
|
|
32855
|
-
description: "Delete a message.
|
|
33044
|
+
description: "Delete a message. Sender only.",
|
|
32856
33045
|
inputSchema: {
|
|
32857
33046
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32858
33047
|
id: exports_external.number().describe("Message ID to delete")
|
|
@@ -32862,7 +33051,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32862
33051
|
const deleted = deleteMessage(id, agent);
|
|
32863
33052
|
if (!deleted) {
|
|
32864
33053
|
return {
|
|
32865
|
-
content: [{ type: "text", text: `
|
|
33054
|
+
content: [{ type: "text", text: `not found or forbidden` }],
|
|
32866
33055
|
isError: true
|
|
32867
33056
|
};
|
|
32868
33057
|
}
|
|
@@ -32872,7 +33061,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32872
33061
|
});
|
|
32873
33062
|
server.registerTool("edit_message", {
|
|
32874
33063
|
title: "Edit Message",
|
|
32875
|
-
description: "Edit a message's content.
|
|
33064
|
+
description: "Edit a message's content. Sender only.",
|
|
32876
33065
|
inputSchema: {
|
|
32877
33066
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32878
33067
|
id: exports_external.number().describe("Message ID to edit"),
|
|
@@ -32883,7 +33072,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32883
33072
|
const msg = editMessage(id, agent, content);
|
|
32884
33073
|
if (!msg) {
|
|
32885
33074
|
return {
|
|
32886
|
-
content: [{ type: "text", text: `
|
|
33075
|
+
content: [{ type: "text", text: `not found or forbidden` }],
|
|
32887
33076
|
isError: true
|
|
32888
33077
|
};
|
|
32889
33078
|
}
|
|
@@ -32893,7 +33082,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32893
33082
|
});
|
|
32894
33083
|
server.registerTool("pin_message", {
|
|
32895
33084
|
title: "Pin Message",
|
|
32896
|
-
description: "Pin a message
|
|
33085
|
+
description: "Pin a message in a space or session.",
|
|
32897
33086
|
inputSchema: {
|
|
32898
33087
|
id: exports_external.number().describe("Message ID to pin")
|
|
32899
33088
|
}
|
|
@@ -32901,7 +33090,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32901
33090
|
const msg = pinMessage(id);
|
|
32902
33091
|
if (!msg) {
|
|
32903
33092
|
return {
|
|
32904
|
-
content: [{ type: "text", text: `
|
|
33093
|
+
content: [{ type: "text", text: `message #${id} not found` }],
|
|
32905
33094
|
isError: true
|
|
32906
33095
|
};
|
|
32907
33096
|
}
|
|
@@ -32919,7 +33108,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32919
33108
|
const msg = unpinMessage(id);
|
|
32920
33109
|
if (!msg) {
|
|
32921
33110
|
return {
|
|
32922
|
-
content: [{ type: "text", text: `
|
|
33111
|
+
content: [{ type: "text", text: `message #${id} not found` }],
|
|
32923
33112
|
isError: true
|
|
32924
33113
|
};
|
|
32925
33114
|
}
|
|
@@ -32929,9 +33118,9 @@ var init_mcp2 = __esm(() => {
|
|
|
32929
33118
|
});
|
|
32930
33119
|
server.registerTool("get_pinned_messages", {
|
|
32931
33120
|
title: "Get Pinned Messages",
|
|
32932
|
-
description: "
|
|
33121
|
+
description: "Get pinned messages, filtered by space or session.",
|
|
32933
33122
|
inputSchema: {
|
|
32934
|
-
space: exports_external.string().optional().describe("Filter by space
|
|
33123
|
+
space: exports_external.string().optional().describe("Filter by space"),
|
|
32935
33124
|
session_id: exports_external.string().optional().describe("Filter by session ID"),
|
|
32936
33125
|
limit: exports_external.number().optional().describe("Max messages to return")
|
|
32937
33126
|
}
|
|
@@ -32943,7 +33132,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32943
33132
|
});
|
|
32944
33133
|
server.registerTool("heartbeat", {
|
|
32945
33134
|
title: "Heartbeat",
|
|
32946
|
-
description: "Send
|
|
33135
|
+
description: "Send heartbeat. Optionally set agent status.",
|
|
32947
33136
|
inputSchema: {
|
|
32948
33137
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32949
33138
|
status: exports_external.string().optional().describe("Agent status (e.g. 'online', 'busy', 'idle'). Defaults to 'online'.")
|
|
@@ -32957,9 +33146,9 @@ var init_mcp2 = __esm(() => {
|
|
|
32957
33146
|
});
|
|
32958
33147
|
server.registerTool("list_agents", {
|
|
32959
33148
|
title: "List Agents",
|
|
32960
|
-
description: "List
|
|
33149
|
+
description: "List agents with presence status.",
|
|
32961
33150
|
inputSchema: {
|
|
32962
|
-
online_only: exports_external.boolean().optional().describe("Only return agents
|
|
33151
|
+
online_only: exports_external.boolean().optional().describe("Only return agents online within last 60s")
|
|
32963
33152
|
}
|
|
32964
33153
|
}, async ({ online_only }) => {
|
|
32965
33154
|
const agents = listAgents({ online_only });
|
|
@@ -32969,7 +33158,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32969
33158
|
});
|
|
32970
33159
|
server.registerTool("get_blockers", {
|
|
32971
33160
|
title: "Get Blockers",
|
|
32972
|
-
description: "Check for unread blocking messages
|
|
33161
|
+
description: "Check for unread blocking messages. Must acknowledge.",
|
|
32973
33162
|
inputSchema: {
|
|
32974
33163
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var.")
|
|
32975
33164
|
}
|
|
@@ -32982,7 +33171,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32982
33171
|
});
|
|
32983
33172
|
server.registerTool("remove_agent", {
|
|
32984
33173
|
title: "Remove Agent",
|
|
32985
|
-
description: "Remove an agent from the presence list.
|
|
33174
|
+
description: "Remove an agent from the presence list.",
|
|
32986
33175
|
inputSchema: {
|
|
32987
33176
|
from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
32988
33177
|
agent: exports_external.string().optional().describe("Agent to remove (defaults to yourself)")
|
|
@@ -32993,7 +33182,7 @@ var init_mcp2 = __esm(() => {
|
|
|
32993
33182
|
const removed = removePresence(agent);
|
|
32994
33183
|
if (!removed) {
|
|
32995
33184
|
return {
|
|
32996
|
-
content: [{ type: "text", text: `
|
|
33185
|
+
content: [{ type: "text", text: `agent "${agent}" not found` }],
|
|
32997
33186
|
isError: true
|
|
32998
33187
|
};
|
|
32999
33188
|
}
|
|
@@ -33003,7 +33192,7 @@ var init_mcp2 = __esm(() => {
|
|
|
33003
33192
|
});
|
|
33004
33193
|
server.registerTool("rename_agent", {
|
|
33005
33194
|
title: "Rename Agent",
|
|
33006
|
-
description: "Rename an agent in the presence list.
|
|
33195
|
+
description: "Rename an agent in the presence list.",
|
|
33007
33196
|
inputSchema: {
|
|
33008
33197
|
from: exports_external.string().optional().describe("Your current agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
|
|
33009
33198
|
new_name: exports_external.string().describe("The new name for the agent")
|
|
@@ -33013,7 +33202,7 @@ var init_mcp2 = __esm(() => {
|
|
|
33013
33202
|
const newName = new_name.trim();
|
|
33014
33203
|
if (!newName) {
|
|
33015
33204
|
return {
|
|
33016
|
-
content: [{ type: "text", text: "
|
|
33205
|
+
content: [{ type: "text", text: "new name cannot be empty" }],
|
|
33017
33206
|
isError: true
|
|
33018
33207
|
};
|
|
33019
33208
|
}
|
|
@@ -33021,7 +33210,7 @@ var init_mcp2 = __esm(() => {
|
|
|
33021
33210
|
const renamed = renameAgent(oldName, newName);
|
|
33022
33211
|
if (!renamed) {
|
|
33023
33212
|
return {
|
|
33024
|
-
content: [{ type: "text", text: `
|
|
33213
|
+
content: [{ type: "text", text: `agent "${oldName}" not found` }],
|
|
33025
33214
|
isError: true
|
|
33026
33215
|
};
|
|
33027
33216
|
}
|
|
@@ -33035,6 +33224,78 @@ var init_mcp2 = __esm(() => {
|
|
|
33035
33224
|
};
|
|
33036
33225
|
}
|
|
33037
33226
|
});
|
|
33227
|
+
server.registerTool("search_tools", {
|
|
33228
|
+
title: "Search Tools",
|
|
33229
|
+
description: "List tool names, optionally filtered by keyword.",
|
|
33230
|
+
inputSchema: {
|
|
33231
|
+
query: exports_external.string().optional().describe("Keyword filter")
|
|
33232
|
+
}
|
|
33233
|
+
}, async ({ query }) => {
|
|
33234
|
+
const all = [
|
|
33235
|
+
"send_message",
|
|
33236
|
+
"read_messages",
|
|
33237
|
+
"list_sessions",
|
|
33238
|
+
"reply",
|
|
33239
|
+
"mark_read",
|
|
33240
|
+
"search_messages",
|
|
33241
|
+
"export_messages",
|
|
33242
|
+
"create_space",
|
|
33243
|
+
"list_spaces",
|
|
33244
|
+
"send_to_space",
|
|
33245
|
+
"read_space",
|
|
33246
|
+
"join_space",
|
|
33247
|
+
"leave_space",
|
|
33248
|
+
"update_space",
|
|
33249
|
+
"archive_space",
|
|
33250
|
+
"unarchive_space",
|
|
33251
|
+
"create_project",
|
|
33252
|
+
"list_projects",
|
|
33253
|
+
"get_project",
|
|
33254
|
+
"update_project",
|
|
33255
|
+
"delete_project",
|
|
33256
|
+
"delete_message",
|
|
33257
|
+
"edit_message",
|
|
33258
|
+
"pin_message",
|
|
33259
|
+
"unpin_message",
|
|
33260
|
+
"get_pinned_messages",
|
|
33261
|
+
"heartbeat",
|
|
33262
|
+
"list_agents",
|
|
33263
|
+
"get_blockers",
|
|
33264
|
+
"remove_agent",
|
|
33265
|
+
"rename_agent",
|
|
33266
|
+
"search_tools",
|
|
33267
|
+
"describe_tools"
|
|
33268
|
+
];
|
|
33269
|
+
const q = query?.toLowerCase();
|
|
33270
|
+
const matches = q ? all.filter((n) => n.includes(q)) : all;
|
|
33271
|
+
return { content: [{ type: "text", text: matches.join(", ") }] };
|
|
33272
|
+
});
|
|
33273
|
+
server.registerTool("describe_tools", {
|
|
33274
|
+
title: "Describe Tools",
|
|
33275
|
+
description: "Get descriptions for specific tools by name.",
|
|
33276
|
+
inputSchema: {
|
|
33277
|
+
names: exports_external.array(exports_external.string()).describe("Tool names from search_tools")
|
|
33278
|
+
}
|
|
33279
|
+
}, async ({ names }) => {
|
|
33280
|
+
const descriptions = {
|
|
33281
|
+
send_message: "Send DM to agent. Params: to, content, from?, priority?",
|
|
33282
|
+
read_messages: "Read messages. Params: space?, from?, to?, unread_only?, limit?",
|
|
33283
|
+
list_sessions: "List sessions. Params: agent?",
|
|
33284
|
+
reply: "Reply to message. Params: id, content, from?",
|
|
33285
|
+
send_to_space: "Send message to space. Params: space, content, from?",
|
|
33286
|
+
read_space: "Read space messages. Params: space, limit?, since?",
|
|
33287
|
+
join_space: "Join a space. Params: space, from?",
|
|
33288
|
+
create_space: "Create space. Params: name, description?, parent_id?",
|
|
33289
|
+
list_spaces: "List spaces with counts. No required params.",
|
|
33290
|
+
heartbeat: "Send heartbeat. Params: from?, status?",
|
|
33291
|
+
list_agents: "List agents with presence. No required params.",
|
|
33292
|
+
get_blockers: "Check for blocking messages. Params: name?",
|
|
33293
|
+
search_messages: "Search messages. Params: query, space?, limit?"
|
|
33294
|
+
};
|
|
33295
|
+
const result = names.map((n) => `${n}: ${descriptions[n] || "See tool schema"}`).join(`
|
|
33296
|
+
`);
|
|
33297
|
+
return { content: [{ type: "text", text: result }] };
|
|
33298
|
+
});
|
|
33038
33299
|
isDirectRun = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("mcp.js") || process.argv[1]?.endsWith("mcp.ts");
|
|
33039
33300
|
if (isDirectRun) {
|
|
33040
33301
|
startMcpServer().catch((error48) => {
|
|
@@ -33049,7 +33310,7 @@ var exports_serve = {};
|
|
|
33049
33310
|
__export(exports_serve, {
|
|
33050
33311
|
startDashboardServer: () => startDashboardServer
|
|
33051
33312
|
});
|
|
33052
|
-
import { join as
|
|
33313
|
+
import { join as join5, resolve, sep } from "path";
|
|
33053
33314
|
import { existsSync } from "fs";
|
|
33054
33315
|
function securityHeaders(base) {
|
|
33055
33316
|
const headers = new Headers(base);
|
|
@@ -33120,7 +33381,7 @@ function isSameOrigin(req) {
|
|
|
33120
33381
|
function startDashboardServer(port = 0, host) {
|
|
33121
33382
|
const resolvedPort = normalizePort(port, 0);
|
|
33122
33383
|
const resolvedHost = normalizeHost(host ?? process.env.CONVERSATIONS_DASHBOARD_HOST);
|
|
33123
|
-
const dashboardDist =
|
|
33384
|
+
const dashboardDist = join5(import.meta.dir, "../../dashboard/dist");
|
|
33124
33385
|
const hasDist = existsSync(dashboardDist);
|
|
33125
33386
|
const server2 = Bun.serve({
|
|
33126
33387
|
port: resolvedPort,
|
|
@@ -33504,7 +33765,7 @@ function startDashboardServer(port = 0, host) {
|
|
|
33504
33765
|
headers.set("Content-Type", file2.type);
|
|
33505
33766
|
return new Response(file2, { headers });
|
|
33506
33767
|
}
|
|
33507
|
-
file2 = Bun.file(
|
|
33768
|
+
file2 = Bun.file(join5(dashboardDist, "index.html"));
|
|
33508
33769
|
if (await file2.exists()) {
|
|
33509
33770
|
const headers = securityHeaders();
|
|
33510
33771
|
if (file2.type)
|
|
@@ -33560,7 +33821,8 @@ init_projects();
|
|
|
33560
33821
|
init_db();
|
|
33561
33822
|
init_identity();
|
|
33562
33823
|
init_presence();
|
|
33563
|
-
|
|
33824
|
+
init_terminal_markdown();
|
|
33825
|
+
import chalk3 from "chalk";
|
|
33564
33826
|
import { render } from "ink";
|
|
33565
33827
|
import React8 from "react";
|
|
33566
33828
|
|
|
@@ -33571,7 +33833,7 @@ import { Box as Box6, Text as Text7, useApp, useInput as useInput5 } from "ink";
|
|
|
33571
33833
|
// node_modules/ink-text-input/build/index.js
|
|
33572
33834
|
import React, { useState, useEffect } from "react";
|
|
33573
33835
|
import { Text, useInput } from "ink";
|
|
33574
|
-
import
|
|
33836
|
+
import chalk2 from "chalk";
|
|
33575
33837
|
function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
|
|
33576
33838
|
const [state, setState] = useState({
|
|
33577
33839
|
cursorOffset: (originalValue || "").length,
|
|
@@ -33596,17 +33858,17 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
|
|
|
33596
33858
|
const cursorActualWidth = highlightPastedText ? cursorWidth : 0;
|
|
33597
33859
|
const value = mask ? mask.repeat(originalValue.length) : originalValue;
|
|
33598
33860
|
let renderedValue = value;
|
|
33599
|
-
let renderedPlaceholder = placeholder ?
|
|
33861
|
+
let renderedPlaceholder = placeholder ? chalk2.grey(placeholder) : undefined;
|
|
33600
33862
|
if (showCursor && focus) {
|
|
33601
|
-
renderedPlaceholder = placeholder.length > 0 ?
|
|
33602
|
-
renderedValue = value.length > 0 ? "" :
|
|
33863
|
+
renderedPlaceholder = placeholder.length > 0 ? chalk2.inverse(placeholder[0]) + chalk2.grey(placeholder.slice(1)) : chalk2.inverse(" ");
|
|
33864
|
+
renderedValue = value.length > 0 ? "" : chalk2.inverse(" ");
|
|
33603
33865
|
let i = 0;
|
|
33604
33866
|
for (const char of value) {
|
|
33605
|
-
renderedValue += i >= cursorOffset - cursorActualWidth && i <= cursorOffset ?
|
|
33867
|
+
renderedValue += i >= cursorOffset - cursorActualWidth && i <= cursorOffset ? chalk2.inverse(char) : char;
|
|
33606
33868
|
i++;
|
|
33607
33869
|
}
|
|
33608
33870
|
if (value.length > 0 && cursorOffset === value.length) {
|
|
33609
|
-
renderedValue +=
|
|
33871
|
+
renderedValue += chalk2.inverse(" ");
|
|
33610
33872
|
}
|
|
33611
33873
|
}
|
|
33612
33874
|
useInput((input, key) => {
|
|
@@ -34507,15 +34769,15 @@ program2.command("send").description("Send a message to an agent").argument("<me
|
|
|
34507
34769
|
const content = typeof message === "string" ? message : "";
|
|
34508
34770
|
const session = typeof opts.session === "string" && opts.session.trim() ? opts.session.trim() : undefined;
|
|
34509
34771
|
if (!from) {
|
|
34510
|
-
console.error(
|
|
34772
|
+
console.error(chalk3.red("Sender identity is required."));
|
|
34511
34773
|
process.exit(1);
|
|
34512
34774
|
}
|
|
34513
34775
|
if (!to) {
|
|
34514
|
-
console.error(
|
|
34776
|
+
console.error(chalk3.red("Recipient is required."));
|
|
34515
34777
|
process.exit(1);
|
|
34516
34778
|
}
|
|
34517
34779
|
if (!content.trim()) {
|
|
34518
|
-
console.error(
|
|
34780
|
+
console.error(chalk3.red("Message content cannot be empty."));
|
|
34519
34781
|
process.exit(1);
|
|
34520
34782
|
}
|
|
34521
34783
|
let metadata;
|
|
@@ -34523,7 +34785,7 @@ program2.command("send").description("Send a message to an agent").argument("<me
|
|
|
34523
34785
|
try {
|
|
34524
34786
|
metadata = JSON.parse(opts.metadata);
|
|
34525
34787
|
} catch {
|
|
34526
|
-
console.error(
|
|
34788
|
+
console.error(chalk3.red("Invalid --metadata JSON."));
|
|
34527
34789
|
process.exit(1);
|
|
34528
34790
|
}
|
|
34529
34791
|
}
|
|
@@ -34542,7 +34804,7 @@ program2.command("send").description("Send a message to an agent").argument("<me
|
|
|
34542
34804
|
if (opts.json) {
|
|
34543
34805
|
console.log(JSON.stringify(msg, null, 2));
|
|
34544
34806
|
} else {
|
|
34545
|
-
console.log(
|
|
34807
|
+
console.log(chalk3.green(`Message sent`) + chalk3.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
|
|
34546
34808
|
}
|
|
34547
34809
|
closeDb();
|
|
34548
34810
|
});
|
|
@@ -34572,15 +34834,20 @@ program2.command("read").description("Read messages").option("--session <id>", "
|
|
|
34572
34834
|
console.log(JSON.stringify(messages, null, 2));
|
|
34573
34835
|
} else {
|
|
34574
34836
|
if (messages.length === 0) {
|
|
34575
|
-
console.log(
|
|
34837
|
+
console.log(chalk3.dim("No messages found."));
|
|
34576
34838
|
} else {
|
|
34577
34839
|
for (const msg of messages) {
|
|
34578
|
-
const time3 =
|
|
34579
|
-
const from =
|
|
34580
|
-
const to = msg.space ?
|
|
34581
|
-
const priority = msg.priority !== "normal" ?
|
|
34582
|
-
const unread = !msg.read_at ?
|
|
34583
|
-
console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}
|
|
34840
|
+
const time3 = chalk3.dim(msg.created_at.slice(11, 19));
|
|
34841
|
+
const from = chalk3.cyan(msg.from_agent);
|
|
34842
|
+
const to = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow(msg.to_agent);
|
|
34843
|
+
const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
|
|
34844
|
+
const unread = !msg.read_at ? chalk3.green(" *") : "";
|
|
34845
|
+
console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}`);
|
|
34846
|
+
const rendered = renderContent(msg.content);
|
|
34847
|
+
const indented = rendered.split(`
|
|
34848
|
+
`).map((l) => " " + l).join(`
|
|
34849
|
+
`);
|
|
34850
|
+
console.log(indented);
|
|
34584
34851
|
}
|
|
34585
34852
|
}
|
|
34586
34853
|
}
|
|
@@ -34589,7 +34856,7 @@ program2.command("read").description("Read messages").option("--session <id>", "
|
|
|
34589
34856
|
program2.command("search").description("Search messages by content").argument("<query>", "Search query string").option("--space <name>", "Filter by space").option("--from <agent>", "Filter by sender").option("--to <agent>", "Filter by recipient").option("--limit <n>", "Max results to return", parseInt).option("--json", "Output as JSON").action((query, opts) => {
|
|
34590
34857
|
const q = typeof query === "string" ? query.trim() : "";
|
|
34591
34858
|
if (!q) {
|
|
34592
|
-
console.error(
|
|
34859
|
+
console.error(chalk3.red("Search query cannot be empty."));
|
|
34593
34860
|
process.exit(1);
|
|
34594
34861
|
}
|
|
34595
34862
|
const messages = searchMessages({
|
|
@@ -34603,16 +34870,16 @@ program2.command("search").description("Search messages by content").argument("<
|
|
|
34603
34870
|
console.log(JSON.stringify(messages, null, 2));
|
|
34604
34871
|
} else {
|
|
34605
34872
|
if (messages.length === 0) {
|
|
34606
|
-
console.log(
|
|
34873
|
+
console.log(chalk3.dim("No messages found."));
|
|
34607
34874
|
} else {
|
|
34608
|
-
console.log(
|
|
34875
|
+
console.log(chalk3.dim(`Found ${messages.length} result(s) for "${q}":
|
|
34609
34876
|
`));
|
|
34610
34877
|
for (const msg of messages) {
|
|
34611
|
-
const time3 =
|
|
34612
|
-
const from =
|
|
34613
|
-
const to = msg.space ?
|
|
34614
|
-
const priority = msg.priority !== "normal" ?
|
|
34615
|
-
const unread = !msg.read_at ?
|
|
34878
|
+
const time3 = chalk3.dim(msg.created_at.slice(11, 19));
|
|
34879
|
+
const from = chalk3.cyan(msg.from_agent);
|
|
34880
|
+
const to = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow(msg.to_agent);
|
|
34881
|
+
const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
|
|
34882
|
+
const unread = !msg.read_at ? chalk3.green(" *") : "";
|
|
34616
34883
|
console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}: ${msg.content}`);
|
|
34617
34884
|
}
|
|
34618
34885
|
}
|
|
@@ -34625,12 +34892,12 @@ program2.command("sessions").description("List conversation sessions").option("-
|
|
|
34625
34892
|
console.log(JSON.stringify(sessions, null, 2));
|
|
34626
34893
|
} else {
|
|
34627
34894
|
if (sessions.length === 0) {
|
|
34628
|
-
console.log(
|
|
34895
|
+
console.log(chalk3.dim("No sessions found."));
|
|
34629
34896
|
} else {
|
|
34630
34897
|
for (const s of sessions) {
|
|
34631
|
-
const unread = s.unread_count > 0 ?
|
|
34898
|
+
const unread = s.unread_count > 0 ? chalk3.green(` (${s.unread_count} unread)`) : "";
|
|
34632
34899
|
const participants = s.participants.join(", ");
|
|
34633
|
-
console.log(`${
|
|
34900
|
+
console.log(`${chalk3.bold(s.session_id)} \u2014 ${participants} \u2014 ${s.message_count} messages${unread}`);
|
|
34634
34901
|
}
|
|
34635
34902
|
}
|
|
34636
34903
|
}
|
|
@@ -34639,17 +34906,17 @@ program2.command("sessions").description("List conversation sessions").option("-
|
|
|
34639
34906
|
program2.command("reply").description("Reply to a message (uses same session)").argument("<message>", "Reply content").requiredOption("--to <message-id>", "Message ID to reply to", parseInt).option("--from <agent>", "Sender agent ID").option("--priority <level>", "Priority: low, normal, high, urgent", "normal").option("--json", "Output as JSON").action((message, opts) => {
|
|
34640
34907
|
const original = getMessageById(opts.to);
|
|
34641
34908
|
if (!original) {
|
|
34642
|
-
console.error(
|
|
34909
|
+
console.error(chalk3.red(`Message #${opts.to} not found.`));
|
|
34643
34910
|
process.exit(1);
|
|
34644
34911
|
}
|
|
34645
34912
|
const from = resolveIdentity(opts.from).trim();
|
|
34646
34913
|
const content = typeof message === "string" ? message : "";
|
|
34647
34914
|
if (!from) {
|
|
34648
|
-
console.error(
|
|
34915
|
+
console.error(chalk3.red("Sender identity is required."));
|
|
34649
34916
|
process.exit(1);
|
|
34650
34917
|
}
|
|
34651
34918
|
if (!content.trim()) {
|
|
34652
|
-
console.error(
|
|
34919
|
+
console.error(chalk3.red("Reply content cannot be empty."));
|
|
34653
34920
|
process.exit(1);
|
|
34654
34921
|
}
|
|
34655
34922
|
const space = original.space || (original.session_id?.startsWith("space:") ? original.session_id.slice(6) : undefined);
|
|
@@ -34665,7 +34932,7 @@ program2.command("reply").description("Reply to a message (uses same session)").
|
|
|
34665
34932
|
if (opts.json) {
|
|
34666
34933
|
console.log(JSON.stringify(msg, null, 2));
|
|
34667
34934
|
} else {
|
|
34668
|
-
console.log(
|
|
34935
|
+
console.log(chalk3.green(`Reply sent`) + chalk3.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
|
|
34669
34936
|
}
|
|
34670
34937
|
closeDb();
|
|
34671
34938
|
});
|
|
@@ -34681,13 +34948,13 @@ program2.command("mark-read").description("Mark messages as read").argument("[id
|
|
|
34681
34948
|
} else if (ids.length > 0) {
|
|
34682
34949
|
count = markRead(ids.map(Number), agent);
|
|
34683
34950
|
} else {
|
|
34684
|
-
console.error(
|
|
34951
|
+
console.error(chalk3.red("Provide message IDs, --all, --session, or --space flag."));
|
|
34685
34952
|
process.exit(1);
|
|
34686
34953
|
}
|
|
34687
34954
|
if (opts.json) {
|
|
34688
34955
|
console.log(JSON.stringify({ marked_read: count }));
|
|
34689
34956
|
} else {
|
|
34690
|
-
console.log(
|
|
34957
|
+
console.log(chalk3.green(`Marked ${count} message(s) as read.`));
|
|
34691
34958
|
}
|
|
34692
34959
|
closeDb();
|
|
34693
34960
|
});
|
|
@@ -34723,7 +34990,7 @@ program2.command("status").description("Show database stats").option("--json", "
|
|
|
34723
34990
|
if (opts.json) {
|
|
34724
34991
|
console.log(JSON.stringify(stats, null, 2));
|
|
34725
34992
|
} else {
|
|
34726
|
-
console.log(
|
|
34993
|
+
console.log(chalk3.bold("Conversations Status"));
|
|
34727
34994
|
console.log(` DB Path: ${stats.db_path}`);
|
|
34728
34995
|
console.log(` Messages: ${stats.total_messages}`);
|
|
34729
34996
|
console.log(` Sessions: ${stats.total_sessions}`);
|
|
@@ -34745,7 +35012,7 @@ program2.command("update").description("Check for and install updates").option("
|
|
|
34745
35012
|
if (opts.json) {
|
|
34746
35013
|
console.log(JSON.stringify({ error: "Failed to check npm registry" }));
|
|
34747
35014
|
} else {
|
|
34748
|
-
console.error(
|
|
35015
|
+
console.error(chalk3.red("Failed to check npm registry for updates."));
|
|
34749
35016
|
}
|
|
34750
35017
|
process.exit(1);
|
|
34751
35018
|
}
|
|
@@ -34754,18 +35021,18 @@ program2.command("update").description("Check for and install updates").option("
|
|
|
34754
35021
|
if (opts.json) {
|
|
34755
35022
|
console.log(JSON.stringify({ current, latest, updateAvailable }));
|
|
34756
35023
|
} else if (updateAvailable) {
|
|
34757
|
-
console.log(`Current version: ${
|
|
34758
|
-
console.log(`Latest version: ${
|
|
34759
|
-
console.log(
|
|
35024
|
+
console.log(`Current version: ${chalk3.yellow(current)}`);
|
|
35025
|
+
console.log(`Latest version: ${chalk3.green(latest)}`);
|
|
35026
|
+
console.log(chalk3.cyan(`Run ${chalk3.bold("conversations update")} to install.`));
|
|
34760
35027
|
} else {
|
|
34761
|
-
console.log(
|
|
35028
|
+
console.log(chalk3.green(`Already on latest version (${current})`));
|
|
34762
35029
|
}
|
|
34763
35030
|
return;
|
|
34764
35031
|
}
|
|
34765
35032
|
if (opts.json) {
|
|
34766
35033
|
console.log(JSON.stringify({ current, latest, updateAvailable, status: "updating" }));
|
|
34767
35034
|
} else {
|
|
34768
|
-
console.log(`Updating from ${
|
|
35035
|
+
console.log(`Updating from ${chalk3.yellow(current)} to ${chalk3.green(latest)}...`);
|
|
34769
35036
|
}
|
|
34770
35037
|
const proc = Bun.spawn(["bun", "install", "-g", `@hasna/conversations@${latest}`], {
|
|
34771
35038
|
stdout: "inherit",
|
|
@@ -34774,14 +35041,14 @@ program2.command("update").description("Check for and install updates").option("
|
|
|
34774
35041
|
const exitCode = await proc.exited;
|
|
34775
35042
|
if (exitCode === 0) {
|
|
34776
35043
|
if (!opts.json) {
|
|
34777
|
-
console.log(
|
|
35044
|
+
console.log(chalk3.green(`
|
|
34778
35045
|
Successfully updated to v${latest}`));
|
|
34779
35046
|
}
|
|
34780
35047
|
} else {
|
|
34781
35048
|
if (opts.json) {
|
|
34782
35049
|
console.log(JSON.stringify({ error: "Update failed", exitCode }));
|
|
34783
35050
|
} else {
|
|
34784
|
-
console.error(
|
|
35051
|
+
console.error(chalk3.red(`
|
|
34785
35052
|
Update failed (exit code ${exitCode})`));
|
|
34786
35053
|
}
|
|
34787
35054
|
process.exit(1);
|
|
@@ -34792,11 +35059,11 @@ space.command("create").description("Create a new space").argument("<name>", "Sp
|
|
|
34792
35059
|
const agent = resolveIdentity(opts.from).trim();
|
|
34793
35060
|
const spaceName = typeof name === "string" ? name.trim() : "";
|
|
34794
35061
|
if (!agent) {
|
|
34795
|
-
console.error(
|
|
35062
|
+
console.error(chalk3.red("Creator identity is required."));
|
|
34796
35063
|
process.exit(1);
|
|
34797
35064
|
}
|
|
34798
35065
|
if (!spaceName) {
|
|
34799
|
-
console.error(
|
|
35066
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34800
35067
|
process.exit(1);
|
|
34801
35068
|
}
|
|
34802
35069
|
try {
|
|
@@ -34809,14 +35076,14 @@ space.command("create").description("Create a new space").argument("<name>", "Sp
|
|
|
34809
35076
|
if (opts.json) {
|
|
34810
35077
|
console.log(JSON.stringify(sp, null, 2));
|
|
34811
35078
|
} else {
|
|
34812
|
-
console.log(
|
|
35079
|
+
console.log(chalk3.green(`Space #${sp.name} created`) + (sp.description ? chalk3.dim(` \u2014 ${sp.description}`) : ""));
|
|
34813
35080
|
}
|
|
34814
35081
|
} catch (e) {
|
|
34815
35082
|
if (e.message?.includes("UNIQUE constraint")) {
|
|
34816
|
-
console.error(
|
|
35083
|
+
console.error(chalk3.red(`Space #${spaceName} already exists.`));
|
|
34817
35084
|
process.exit(1);
|
|
34818
35085
|
}
|
|
34819
|
-
console.error(
|
|
35086
|
+
console.error(chalk3.red(e.message));
|
|
34820
35087
|
process.exit(1);
|
|
34821
35088
|
}
|
|
34822
35089
|
closeDb();
|
|
@@ -34837,13 +35104,13 @@ space.command("list").description("List all spaces").option("--project <id>", "F
|
|
|
34837
35104
|
console.log(JSON.stringify(spaces, null, 2));
|
|
34838
35105
|
} else {
|
|
34839
35106
|
if (spaces.length === 0) {
|
|
34840
|
-
console.log(
|
|
35107
|
+
console.log(chalk3.dim("No spaces found."));
|
|
34841
35108
|
} else {
|
|
34842
35109
|
for (const sp of spaces) {
|
|
34843
|
-
const desc = sp.description ?
|
|
34844
|
-
const parent = sp.parent_id ?
|
|
34845
|
-
const archived = sp.archived_at ?
|
|
34846
|
-
console.log(`${
|
|
35110
|
+
const desc = sp.description ? chalk3.dim(` \u2014 ${sp.description}`) : "";
|
|
35111
|
+
const parent = sp.parent_id ? chalk3.dim(` (child of ${sp.parent_id})`) : "";
|
|
35112
|
+
const archived = sp.archived_at ? chalk3.yellow(" [archived]") : "";
|
|
35113
|
+
console.log(`${chalk3.magenta(`#${sp.name}`)}${desc}${parent}${archived} ${sp.member_count} members, ${sp.message_count} messages`);
|
|
34847
35114
|
}
|
|
34848
35115
|
}
|
|
34849
35116
|
}
|
|
@@ -34852,7 +35119,7 @@ space.command("list").description("List all spaces").option("--project <id>", "F
|
|
|
34852
35119
|
space.command("update").description("Update a space").argument("<name>", "Space name").option("--description <text>", "New description").option("--parent <name>", "New parent space name").option("--project <id>", "New project ID").option("--json", "Output as JSON").action((name, opts) => {
|
|
34853
35120
|
const spaceName = typeof name === "string" ? name.trim() : "";
|
|
34854
35121
|
if (!spaceName) {
|
|
34855
|
-
console.error(
|
|
35122
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34856
35123
|
process.exit(1);
|
|
34857
35124
|
}
|
|
34858
35125
|
const updates = {};
|
|
@@ -34867,10 +35134,10 @@ space.command("update").description("Update a space").argument("<name>", "Space
|
|
|
34867
35134
|
if (opts.json) {
|
|
34868
35135
|
console.log(JSON.stringify(sp, null, 2));
|
|
34869
35136
|
} else {
|
|
34870
|
-
console.log(
|
|
35137
|
+
console.log(chalk3.green(`Space #${sp.name} updated.`));
|
|
34871
35138
|
}
|
|
34872
35139
|
} catch (e) {
|
|
34873
|
-
console.error(
|
|
35140
|
+
console.error(chalk3.red(e.message));
|
|
34874
35141
|
process.exit(1);
|
|
34875
35142
|
}
|
|
34876
35143
|
closeDb();
|
|
@@ -34878,7 +35145,7 @@ space.command("update").description("Update a space").argument("<name>", "Space
|
|
|
34878
35145
|
space.command("archive").description("Archive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
|
|
34879
35146
|
const spaceName = typeof name === "string" ? name.trim() : "";
|
|
34880
35147
|
if (!spaceName) {
|
|
34881
|
-
console.error(
|
|
35148
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34882
35149
|
process.exit(1);
|
|
34883
35150
|
}
|
|
34884
35151
|
try {
|
|
@@ -34886,10 +35153,10 @@ space.command("archive").description("Archive a space").argument("<name>", "Spac
|
|
|
34886
35153
|
if (opts.json) {
|
|
34887
35154
|
console.log(JSON.stringify(sp, null, 2));
|
|
34888
35155
|
} else {
|
|
34889
|
-
console.log(
|
|
35156
|
+
console.log(chalk3.green(`Space #${sp.name} archived.`));
|
|
34890
35157
|
}
|
|
34891
35158
|
} catch (e) {
|
|
34892
|
-
console.error(
|
|
35159
|
+
console.error(chalk3.red(e.message));
|
|
34893
35160
|
process.exit(1);
|
|
34894
35161
|
}
|
|
34895
35162
|
closeDb();
|
|
@@ -34897,7 +35164,7 @@ space.command("archive").description("Archive a space").argument("<name>", "Spac
|
|
|
34897
35164
|
space.command("unarchive").description("Unarchive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
|
|
34898
35165
|
const spaceName = typeof name === "string" ? name.trim() : "";
|
|
34899
35166
|
if (!spaceName) {
|
|
34900
|
-
console.error(
|
|
35167
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34901
35168
|
process.exit(1);
|
|
34902
35169
|
}
|
|
34903
35170
|
try {
|
|
@@ -34905,10 +35172,10 @@ space.command("unarchive").description("Unarchive a space").argument("<name>", "
|
|
|
34905
35172
|
if (opts.json) {
|
|
34906
35173
|
console.log(JSON.stringify(sp, null, 2));
|
|
34907
35174
|
} else {
|
|
34908
|
-
console.log(
|
|
35175
|
+
console.log(chalk3.green(`Space #${sp.name} unarchived.`));
|
|
34909
35176
|
}
|
|
34910
35177
|
} catch (e) {
|
|
34911
|
-
console.error(
|
|
35178
|
+
console.error(chalk3.red(e.message));
|
|
34912
35179
|
process.exit(1);
|
|
34913
35180
|
}
|
|
34914
35181
|
closeDb();
|
|
@@ -34918,20 +35185,20 @@ space.command("send").description("Send a message to a space").argument("<space>
|
|
|
34918
35185
|
const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
|
|
34919
35186
|
const content = typeof message === "string" ? message : "";
|
|
34920
35187
|
if (!from) {
|
|
34921
|
-
console.error(
|
|
35188
|
+
console.error(chalk3.red("Sender identity is required."));
|
|
34922
35189
|
process.exit(1);
|
|
34923
35190
|
}
|
|
34924
35191
|
if (!spaceArg) {
|
|
34925
|
-
console.error(
|
|
35192
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34926
35193
|
process.exit(1);
|
|
34927
35194
|
}
|
|
34928
35195
|
if (!content.trim()) {
|
|
34929
|
-
console.error(
|
|
35196
|
+
console.error(chalk3.red("Message content cannot be empty."));
|
|
34930
35197
|
process.exit(1);
|
|
34931
35198
|
}
|
|
34932
35199
|
const sp = getSpace(spaceArg);
|
|
34933
35200
|
if (!sp) {
|
|
34934
|
-
console.error(
|
|
35201
|
+
console.error(chalk3.red(`Space #${spaceArg} not found.`));
|
|
34935
35202
|
process.exit(1);
|
|
34936
35203
|
}
|
|
34937
35204
|
const msg = sendMessage({
|
|
@@ -34945,14 +35212,14 @@ space.command("send").description("Send a message to a space").argument("<space>
|
|
|
34945
35212
|
if (opts.json) {
|
|
34946
35213
|
console.log(JSON.stringify(msg, null, 2));
|
|
34947
35214
|
} else {
|
|
34948
|
-
console.log(
|
|
35215
|
+
console.log(chalk3.green(`Message sent to #${spaceArg}`) + chalk3.dim(` (id: ${msg.id})`));
|
|
34949
35216
|
}
|
|
34950
35217
|
closeDb();
|
|
34951
35218
|
});
|
|
34952
35219
|
space.command("read").description("Read messages from a space").argument("<space>", "Space name").option("--since <timestamp>", "Messages after this ISO timestamp").option("--limit <n>", "Max messages to return", parseInt).option("--json", "Output as JSON").action((spaceName, opts) => {
|
|
34953
35220
|
const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
|
|
34954
35221
|
if (!spaceArg) {
|
|
34955
|
-
console.error(
|
|
35222
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34956
35223
|
process.exit(1);
|
|
34957
35224
|
}
|
|
34958
35225
|
const messages = readMessages({
|
|
@@ -34964,13 +35231,18 @@ space.command("read").description("Read messages from a space").argument("<space
|
|
|
34964
35231
|
console.log(JSON.stringify(messages, null, 2));
|
|
34965
35232
|
} else {
|
|
34966
35233
|
if (messages.length === 0) {
|
|
34967
|
-
console.log(
|
|
35234
|
+
console.log(chalk3.dim(`No messages in #${spaceArg}.`));
|
|
34968
35235
|
} else {
|
|
34969
35236
|
for (const msg of messages) {
|
|
34970
|
-
const time3 =
|
|
34971
|
-
const from =
|
|
34972
|
-
const priority = msg.priority !== "normal" ?
|
|
34973
|
-
console.log(`${time3} ${from} \u2192 ${
|
|
35237
|
+
const time3 = chalk3.dim(msg.created_at.slice(11, 19));
|
|
35238
|
+
const from = chalk3.cyan(msg.from_agent);
|
|
35239
|
+
const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
|
|
35240
|
+
console.log(`${time3} ${from} \u2192 ${chalk3.magenta(`#${spaceArg}`)}${priority}`);
|
|
35241
|
+
const rendered = renderContent(msg.content);
|
|
35242
|
+
const indented = rendered.split(`
|
|
35243
|
+
`).map((l) => " " + l).join(`
|
|
35244
|
+
`);
|
|
35245
|
+
console.log(indented);
|
|
34974
35246
|
}
|
|
34975
35247
|
}
|
|
34976
35248
|
}
|
|
@@ -34980,22 +35252,22 @@ space.command("join").description("Join a space").argument("<space>", "Space nam
|
|
|
34980
35252
|
const agent = resolveIdentity(opts.from).trim();
|
|
34981
35253
|
const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
|
|
34982
35254
|
if (!agent) {
|
|
34983
|
-
console.error(
|
|
35255
|
+
console.error(chalk3.red("Agent identity is required."));
|
|
34984
35256
|
process.exit(1);
|
|
34985
35257
|
}
|
|
34986
35258
|
if (!spaceArg) {
|
|
34987
|
-
console.error(
|
|
35259
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
34988
35260
|
process.exit(1);
|
|
34989
35261
|
}
|
|
34990
35262
|
const ok = joinSpace(spaceArg, agent);
|
|
34991
35263
|
if (!ok) {
|
|
34992
|
-
console.error(
|
|
35264
|
+
console.error(chalk3.red(`Space #${spaceArg} not found.`));
|
|
34993
35265
|
process.exit(1);
|
|
34994
35266
|
}
|
|
34995
35267
|
if (opts.json) {
|
|
34996
35268
|
console.log(JSON.stringify({ space: spaceArg, agent, joined: true }));
|
|
34997
35269
|
} else {
|
|
34998
|
-
console.log(
|
|
35270
|
+
console.log(chalk3.green(`${agent} joined #${spaceArg}`));
|
|
34999
35271
|
}
|
|
35000
35272
|
closeDb();
|
|
35001
35273
|
});
|
|
@@ -35003,11 +35275,11 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
|
|
|
35003
35275
|
const agent = resolveIdentity(opts.from).trim();
|
|
35004
35276
|
const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
|
|
35005
35277
|
if (!agent) {
|
|
35006
|
-
console.error(
|
|
35278
|
+
console.error(chalk3.red("Agent identity is required."));
|
|
35007
35279
|
process.exit(1);
|
|
35008
35280
|
}
|
|
35009
35281
|
if (!spaceArg) {
|
|
35010
|
-
console.error(
|
|
35282
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
35011
35283
|
process.exit(1);
|
|
35012
35284
|
}
|
|
35013
35285
|
const ok = leaveSpace(spaceArg, agent);
|
|
@@ -35015,9 +35287,9 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
|
|
|
35015
35287
|
console.log(JSON.stringify({ space: spaceArg, agent, left: ok }));
|
|
35016
35288
|
} else {
|
|
35017
35289
|
if (ok) {
|
|
35018
|
-
console.log(
|
|
35290
|
+
console.log(chalk3.green(`${agent} left #${spaceArg}`));
|
|
35019
35291
|
} else {
|
|
35020
|
-
console.log(
|
|
35292
|
+
console.log(chalk3.dim(`${agent} was not a member of #${spaceArg}`));
|
|
35021
35293
|
}
|
|
35022
35294
|
}
|
|
35023
35295
|
closeDb();
|
|
@@ -35025,7 +35297,7 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
|
|
|
35025
35297
|
space.command("members").description("List space members").argument("<space>", "Space name").option("--json", "Output as JSON").action((spaceName, opts) => {
|
|
35026
35298
|
const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
|
|
35027
35299
|
if (!spaceArg) {
|
|
35028
|
-
console.error(
|
|
35300
|
+
console.error(chalk3.red("Space name cannot be empty."));
|
|
35029
35301
|
process.exit(1);
|
|
35030
35302
|
}
|
|
35031
35303
|
const members = getSpaceMembers(spaceArg);
|
|
@@ -35033,11 +35305,11 @@ space.command("members").description("List space members").argument("<space>", "
|
|
|
35033
35305
|
console.log(JSON.stringify(members, null, 2));
|
|
35034
35306
|
} else {
|
|
35035
35307
|
if (members.length === 0) {
|
|
35036
|
-
console.log(
|
|
35308
|
+
console.log(chalk3.dim(`No members in #${spaceArg}.`));
|
|
35037
35309
|
} else {
|
|
35038
|
-
console.log(
|
|
35310
|
+
console.log(chalk3.magenta(`#${spaceArg}`) + chalk3.dim(` \u2014 ${members.length} member(s)`));
|
|
35039
35311
|
for (const m of members) {
|
|
35040
|
-
console.log(` ${
|
|
35312
|
+
console.log(` ${chalk3.cyan(m.agent)} ${chalk3.dim(`joined ${m.joined_at.slice(0, 10)}`)}`);
|
|
35041
35313
|
}
|
|
35042
35314
|
}
|
|
35043
35315
|
}
|
|
@@ -35048,11 +35320,11 @@ project.command("create").description("Create a new project").argument("<name>",
|
|
|
35048
35320
|
const agent = resolveIdentity(opts.from).trim();
|
|
35049
35321
|
const projectName = typeof name === "string" ? name.trim() : "";
|
|
35050
35322
|
if (!agent) {
|
|
35051
|
-
console.error(
|
|
35323
|
+
console.error(chalk3.red("Creator identity is required."));
|
|
35052
35324
|
process.exit(1);
|
|
35053
35325
|
}
|
|
35054
35326
|
if (!projectName) {
|
|
35055
|
-
console.error(
|
|
35327
|
+
console.error(chalk3.red("Project name cannot be empty."));
|
|
35056
35328
|
process.exit(1);
|
|
35057
35329
|
}
|
|
35058
35330
|
let tags;
|
|
@@ -35060,7 +35332,7 @@ project.command("create").description("Create a new project").argument("<name>",
|
|
|
35060
35332
|
try {
|
|
35061
35333
|
tags = JSON.parse(opts.tags);
|
|
35062
35334
|
} catch {
|
|
35063
|
-
console.error(
|
|
35335
|
+
console.error(chalk3.red("Invalid --tags JSON. Expected array of strings."));
|
|
35064
35336
|
process.exit(1);
|
|
35065
35337
|
}
|
|
35066
35338
|
}
|
|
@@ -35076,14 +35348,14 @@ project.command("create").description("Create a new project").argument("<name>",
|
|
|
35076
35348
|
if (opts.json) {
|
|
35077
35349
|
console.log(JSON.stringify(p, null, 2));
|
|
35078
35350
|
} else {
|
|
35079
|
-
console.log(
|
|
35351
|
+
console.log(chalk3.green(`Project "${p.name}" created`) + chalk3.dim(` (id: ${p.id})`));
|
|
35080
35352
|
}
|
|
35081
35353
|
} catch (e) {
|
|
35082
35354
|
if (e.message?.includes("UNIQUE constraint")) {
|
|
35083
|
-
console.error(
|
|
35355
|
+
console.error(chalk3.red(`Project "${projectName}" already exists.`));
|
|
35084
35356
|
process.exit(1);
|
|
35085
35357
|
}
|
|
35086
|
-
console.error(
|
|
35358
|
+
console.error(chalk3.red(e.message));
|
|
35087
35359
|
process.exit(1);
|
|
35088
35360
|
}
|
|
35089
35361
|
closeDb();
|
|
@@ -35095,12 +35367,12 @@ project.command("list").description("List all projects").option("--status <statu
|
|
|
35095
35367
|
console.log(JSON.stringify(projects, null, 2));
|
|
35096
35368
|
} else {
|
|
35097
35369
|
if (projects.length === 0) {
|
|
35098
|
-
console.log(
|
|
35370
|
+
console.log(chalk3.dim("No projects found."));
|
|
35099
35371
|
} else {
|
|
35100
35372
|
for (const p of projects) {
|
|
35101
|
-
const desc = p.description ?
|
|
35102
|
-
const statusBadge = p.status === "archived" ?
|
|
35103
|
-
console.log(`${
|
|
35373
|
+
const desc = p.description ? chalk3.dim(` \u2014 ${p.description}`) : "";
|
|
35374
|
+
const statusBadge = p.status === "archived" ? chalk3.yellow(" [archived]") : "";
|
|
35375
|
+
console.log(`${chalk3.bold(p.name)}${desc}${statusBadge} ${p.space_count} spaces`);
|
|
35104
35376
|
}
|
|
35105
35377
|
}
|
|
35106
35378
|
}
|
|
@@ -35111,13 +35383,13 @@ project.command("get").description("Get project details").argument("<id-or-name>
|
|
|
35111
35383
|
if (!p)
|
|
35112
35384
|
p = getProjectByName(idOrName);
|
|
35113
35385
|
if (!p) {
|
|
35114
|
-
console.error(
|
|
35386
|
+
console.error(chalk3.red(`Project "${idOrName}" not found.`));
|
|
35115
35387
|
process.exit(1);
|
|
35116
35388
|
}
|
|
35117
35389
|
if (opts.json) {
|
|
35118
35390
|
console.log(JSON.stringify(p, null, 2));
|
|
35119
35391
|
} else {
|
|
35120
|
-
console.log(
|
|
35392
|
+
console.log(chalk3.bold(p.name));
|
|
35121
35393
|
if (p.description)
|
|
35122
35394
|
console.log(` Description: ${p.description}`);
|
|
35123
35395
|
if (p.path)
|
|
@@ -35148,7 +35420,7 @@ project.command("update").description("Update a project").argument("<id>", "Proj
|
|
|
35148
35420
|
try {
|
|
35149
35421
|
updates.tags = JSON.parse(opts.tags);
|
|
35150
35422
|
} catch {
|
|
35151
|
-
console.error(
|
|
35423
|
+
console.error(chalk3.red("Invalid --tags JSON."));
|
|
35152
35424
|
process.exit(1);
|
|
35153
35425
|
}
|
|
35154
35426
|
}
|
|
@@ -35157,10 +35429,10 @@ project.command("update").description("Update a project").argument("<id>", "Proj
|
|
|
35157
35429
|
if (opts.json) {
|
|
35158
35430
|
console.log(JSON.stringify(p, null, 2));
|
|
35159
35431
|
} else {
|
|
35160
|
-
console.log(
|
|
35432
|
+
console.log(chalk3.green(`Project "${p.name}" updated.`));
|
|
35161
35433
|
}
|
|
35162
35434
|
} catch (e) {
|
|
35163
|
-
console.error(
|
|
35435
|
+
console.error(chalk3.red(e.message));
|
|
35164
35436
|
process.exit(1);
|
|
35165
35437
|
}
|
|
35166
35438
|
closeDb();
|
|
@@ -35169,16 +35441,16 @@ project.command("delete").description("Delete a project").argument("<id>", "Proj
|
|
|
35169
35441
|
try {
|
|
35170
35442
|
const deleted = deleteProject(id);
|
|
35171
35443
|
if (!deleted) {
|
|
35172
|
-
console.error(
|
|
35444
|
+
console.error(chalk3.red(`Project "${id}" not found.`));
|
|
35173
35445
|
process.exit(1);
|
|
35174
35446
|
}
|
|
35175
35447
|
if (opts.json) {
|
|
35176
35448
|
console.log(JSON.stringify({ id, deleted: true }));
|
|
35177
35449
|
} else {
|
|
35178
|
-
console.log(
|
|
35450
|
+
console.log(chalk3.green(`Project deleted.`));
|
|
35179
35451
|
}
|
|
35180
35452
|
} catch (e) {
|
|
35181
|
-
console.error(
|
|
35453
|
+
console.error(chalk3.red(e.message));
|
|
35182
35454
|
process.exit(1);
|
|
35183
35455
|
}
|
|
35184
35456
|
closeDb();
|
|
@@ -35186,7 +35458,7 @@ project.command("delete").description("Delete a project").argument("<id>", "Proj
|
|
|
35186
35458
|
program2.command("delete").description("Delete a message (only sender can delete)").argument("<id>", "Message ID", parseInt).option("--from <agent>", "Sender agent ID").option("--json", "Output as JSON").action((id, opts) => {
|
|
35187
35459
|
const agent = resolveIdentity(opts.from).trim();
|
|
35188
35460
|
if (!agent) {
|
|
35189
|
-
console.error(
|
|
35461
|
+
console.error(chalk3.red("Agent identity is required."));
|
|
35190
35462
|
process.exit(1);
|
|
35191
35463
|
}
|
|
35192
35464
|
const result = deleteMessage(id, agent);
|
|
@@ -35194,9 +35466,9 @@ program2.command("delete").description("Delete a message (only sender can delete
|
|
|
35194
35466
|
console.log(JSON.stringify({ id, deleted: result }));
|
|
35195
35467
|
} else {
|
|
35196
35468
|
if (result) {
|
|
35197
|
-
console.log(
|
|
35469
|
+
console.log(chalk3.green(`Message #${id} deleted.`));
|
|
35198
35470
|
} else {
|
|
35199
|
-
console.error(
|
|
35471
|
+
console.error(chalk3.red(`Message #${id} not found or not your message.`));
|
|
35200
35472
|
process.exit(1);
|
|
35201
35473
|
}
|
|
35202
35474
|
}
|
|
@@ -35206,11 +35478,11 @@ program2.command("edit").description("Edit a message (only sender can edit)").ar
|
|
|
35206
35478
|
const agent = resolveIdentity(opts.from).trim();
|
|
35207
35479
|
const content = typeof newContent === "string" ? newContent : "";
|
|
35208
35480
|
if (!agent) {
|
|
35209
|
-
console.error(
|
|
35481
|
+
console.error(chalk3.red("Agent identity is required."));
|
|
35210
35482
|
process.exit(1);
|
|
35211
35483
|
}
|
|
35212
35484
|
if (!content.trim()) {
|
|
35213
|
-
console.error(
|
|
35485
|
+
console.error(chalk3.red("New content cannot be empty."));
|
|
35214
35486
|
process.exit(1);
|
|
35215
35487
|
}
|
|
35216
35488
|
const msg = editMessage(id, agent, content);
|
|
@@ -35218,9 +35490,9 @@ program2.command("edit").description("Edit a message (only sender can edit)").ar
|
|
|
35218
35490
|
console.log(JSON.stringify(msg, null, 2));
|
|
35219
35491
|
} else {
|
|
35220
35492
|
if (msg) {
|
|
35221
|
-
console.log(
|
|
35493
|
+
console.log(chalk3.green(`Message #${id} edited.`));
|
|
35222
35494
|
} else {
|
|
35223
|
-
console.error(
|
|
35495
|
+
console.error(chalk3.red(`Message #${id} not found or not your message.`));
|
|
35224
35496
|
process.exit(1);
|
|
35225
35497
|
}
|
|
35226
35498
|
}
|
|
@@ -35232,9 +35504,9 @@ program2.command("pin").description("Pin a message").argument("<id>", "Message I
|
|
|
35232
35504
|
console.log(JSON.stringify(msg, null, 2));
|
|
35233
35505
|
} else {
|
|
35234
35506
|
if (msg) {
|
|
35235
|
-
console.log(
|
|
35507
|
+
console.log(chalk3.green(`Message #${id} pinned.`));
|
|
35236
35508
|
} else {
|
|
35237
|
-
console.error(
|
|
35509
|
+
console.error(chalk3.red(`Message #${id} not found.`));
|
|
35238
35510
|
process.exit(1);
|
|
35239
35511
|
}
|
|
35240
35512
|
}
|
|
@@ -35246,9 +35518,9 @@ program2.command("unpin").description("Unpin a message").argument("<id>", "Messa
|
|
|
35246
35518
|
console.log(JSON.stringify(msg, null, 2));
|
|
35247
35519
|
} else {
|
|
35248
35520
|
if (msg) {
|
|
35249
|
-
console.log(
|
|
35521
|
+
console.log(chalk3.green(`Message #${id} unpinned.`));
|
|
35250
35522
|
} else {
|
|
35251
|
-
console.error(
|
|
35523
|
+
console.error(chalk3.red(`Message #${id} not found.`));
|
|
35252
35524
|
process.exit(1);
|
|
35253
35525
|
}
|
|
35254
35526
|
}
|
|
@@ -35263,13 +35535,13 @@ agents.command("list").description("List all agents with their presence status")
|
|
|
35263
35535
|
console.log(JSON.stringify(agentsList, null, 2));
|
|
35264
35536
|
} else {
|
|
35265
35537
|
if (agentsList.length === 0) {
|
|
35266
|
-
console.log(
|
|
35538
|
+
console.log(chalk3.dim("No agents found."));
|
|
35267
35539
|
} else {
|
|
35268
35540
|
for (const a of agentsList) {
|
|
35269
|
-
const status = a.online ?
|
|
35270
|
-
const lastSeen =
|
|
35271
|
-
const agentName = a.agent === agent ?
|
|
35272
|
-
console.log(` ${agentName} ${status} ${
|
|
35541
|
+
const status = a.online ? chalk3.green("online") : chalk3.dim("offline");
|
|
35542
|
+
const lastSeen = chalk3.dim(a.last_seen_at.slice(0, 19));
|
|
35543
|
+
const agentName = a.agent === agent ? chalk3.cyan(`${a.agent} (you)`) : chalk3.cyan(a.agent);
|
|
35544
|
+
console.log(` ${agentName} ${status} ${chalk3.dim(a.status)} ${lastSeen}`);
|
|
35273
35545
|
}
|
|
35274
35546
|
}
|
|
35275
35547
|
}
|
|
@@ -35278,7 +35550,7 @@ agents.command("list").description("List all agents with their presence status")
|
|
|
35278
35550
|
agents.command("remove").description("Remove an agent from the presence list").argument("<name>", "Agent name to remove").option("--json", "Output as JSON").action((name, opts) => {
|
|
35279
35551
|
const agentName = typeof name === "string" ? name.trim() : "";
|
|
35280
35552
|
if (!agentName) {
|
|
35281
|
-
console.error(
|
|
35553
|
+
console.error(chalk3.red("Agent name cannot be empty."));
|
|
35282
35554
|
process.exit(1);
|
|
35283
35555
|
}
|
|
35284
35556
|
const removed = removePresence(agentName);
|
|
@@ -35286,9 +35558,9 @@ agents.command("remove").description("Remove an agent from the presence list").a
|
|
|
35286
35558
|
console.log(JSON.stringify({ agent: agentName, removed }));
|
|
35287
35559
|
} else {
|
|
35288
35560
|
if (removed) {
|
|
35289
|
-
console.log(
|
|
35561
|
+
console.log(chalk3.green(`Agent "${agentName}" removed.`));
|
|
35290
35562
|
} else {
|
|
35291
|
-
console.error(
|
|
35563
|
+
console.error(chalk3.red(`Agent "${agentName}" not found.`));
|
|
35292
35564
|
process.exit(1);
|
|
35293
35565
|
}
|
|
35294
35566
|
}
|
|
@@ -35298,22 +35570,22 @@ agents.command("rename").description("Rename an agent in the presence list").arg
|
|
|
35298
35570
|
const old = typeof oldName === "string" ? oldName.trim() : "";
|
|
35299
35571
|
const renamed = typeof newName === "string" ? newName.trim() : "";
|
|
35300
35572
|
if (!old || !renamed) {
|
|
35301
|
-
console.error(
|
|
35573
|
+
console.error(chalk3.red("Both old and new names are required."));
|
|
35302
35574
|
process.exit(1);
|
|
35303
35575
|
}
|
|
35304
35576
|
try {
|
|
35305
35577
|
const ok = renameAgent(old, renamed);
|
|
35306
35578
|
if (!ok) {
|
|
35307
|
-
console.error(
|
|
35579
|
+
console.error(chalk3.red(`Agent "${old}" not found.`));
|
|
35308
35580
|
process.exit(1);
|
|
35309
35581
|
}
|
|
35310
35582
|
if (opts.json) {
|
|
35311
35583
|
console.log(JSON.stringify({ old_name: old, new_name: renamed, renamed: true }));
|
|
35312
35584
|
} else {
|
|
35313
|
-
console.log(
|
|
35585
|
+
console.log(chalk3.green(`Agent "${old}" renamed to "${renamed}".`));
|
|
35314
35586
|
}
|
|
35315
35587
|
} catch (e) {
|
|
35316
|
-
console.error(
|
|
35588
|
+
console.error(chalk3.red(e.message));
|
|
35317
35589
|
process.exit(1);
|
|
35318
35590
|
}
|
|
35319
35591
|
closeDb();
|
|
@@ -35327,9 +35599,9 @@ program2.command("whoami").description("Show current agent identity and online s
|
|
|
35327
35599
|
} else if (envValue) {
|
|
35328
35600
|
source = "env var (CONVERSATIONS_AGENT_ID)";
|
|
35329
35601
|
} else {
|
|
35330
|
-
const { join:
|
|
35331
|
-
const { homedir:
|
|
35332
|
-
const agentIdFile =
|
|
35602
|
+
const { join: join6 } = __require("path");
|
|
35603
|
+
const { homedir: homedir5 } = __require("os");
|
|
35604
|
+
const agentIdFile = join6(homedir5(), ".conversations", "agent-id");
|
|
35333
35605
|
source = `auto-generated (${agentIdFile})`;
|
|
35334
35606
|
}
|
|
35335
35607
|
const presence = getPresence(agent);
|
|
@@ -35339,15 +35611,15 @@ program2.command("whoami").description("Show current agent identity and online s
|
|
|
35339
35611
|
const agoMs = Date.now() - lastSeenMs;
|
|
35340
35612
|
const agoSec = Math.floor(agoMs / 1000);
|
|
35341
35613
|
const agoStr = agoSec < 60 ? `${agoSec}s ago` : `${Math.floor(agoSec / 60)}m ago`;
|
|
35342
|
-
onlineStatus =
|
|
35614
|
+
onlineStatus = chalk3.green(`yes`) + chalk3.dim(` (last seen ${agoStr})`);
|
|
35343
35615
|
} else if (presence) {
|
|
35344
|
-
onlineStatus =
|
|
35616
|
+
onlineStatus = chalk3.red("no") + chalk3.dim(` (last seen ${presence.last_seen_at})`);
|
|
35345
35617
|
} else {
|
|
35346
|
-
onlineStatus =
|
|
35618
|
+
onlineStatus = chalk3.red("no") + chalk3.dim(" (no presence record)");
|
|
35347
35619
|
}
|
|
35348
|
-
console.log(` ${
|
|
35349
|
-
console.log(` ${
|
|
35350
|
-
console.log(` ${
|
|
35620
|
+
console.log(` ${chalk3.bold("Agent:")} ${chalk3.cyan(agent)}`);
|
|
35621
|
+
console.log(` ${chalk3.bold("Source:")} ${source}`);
|
|
35622
|
+
console.log(` ${chalk3.bold("Online:")} ${onlineStatus}`);
|
|
35351
35623
|
closeDb();
|
|
35352
35624
|
});
|
|
35353
35625
|
program2.command("blockers").description("Check for unread blocking messages").option("--from <agent>", "Agent to check blockers for").option("--json", "Output as JSON").action((opts) => {
|
|
@@ -35357,16 +35629,16 @@ program2.command("blockers").description("Check for unread blocking messages").o
|
|
|
35357
35629
|
console.log(JSON.stringify(blockers, null, 2));
|
|
35358
35630
|
} else {
|
|
35359
35631
|
if (blockers.length === 0) {
|
|
35360
|
-
console.log(
|
|
35632
|
+
console.log(chalk3.dim("No blocking messages."));
|
|
35361
35633
|
} else {
|
|
35362
|
-
console.log(
|
|
35634
|
+
console.log(chalk3.red.bold(`${blockers.length} blocking message(s):
|
|
35363
35635
|
`));
|
|
35364
35636
|
for (const b of blockers) {
|
|
35365
|
-
const where = b.space ?
|
|
35366
|
-
const time3 =
|
|
35367
|
-
console.log(` ${
|
|
35637
|
+
const where = b.space ? chalk3.magenta(`#${b.space}`) : chalk3.yellow("DM");
|
|
35638
|
+
const time3 = chalk3.dim(b.created_at.slice(11, 19));
|
|
35639
|
+
console.log(` ${chalk3.red(`[#${b.id}]`)} ${time3} ${chalk3.cyan(b.from_agent)} ${where}: ${b.content}`);
|
|
35368
35640
|
}
|
|
35369
|
-
console.log(
|
|
35641
|
+
console.log(chalk3.dim(`
|
|
35370
35642
|
Acknowledge with: conversations mark-read ${blockers.map((b) => b.id).join(" ")}`));
|
|
35371
35643
|
}
|
|
35372
35644
|
}
|
|
@@ -35385,49 +35657,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
|
|
|
35385
35657
|
}
|
|
35386
35658
|
const modeLabel = opts.all ? `DMs + ${agentSpaces.length} space(s)` : opts.space ? `Space: #${opts.space}` : "All DMs";
|
|
35387
35659
|
console.log("");
|
|
35388
|
-
console.log(
|
|
35389
|
-
console.log(
|
|
35390
|
-
console.log(
|
|
35660
|
+
console.log(chalk3.bold(` Conversations`) + chalk3.dim(` \u2014 watching as ${chalk3.cyan(agent)}`));
|
|
35661
|
+
console.log(chalk3.dim(` ${modeLabel} \xB7 Poll: ${interval}ms \xB7 Ctrl+C to stop`));
|
|
35662
|
+
console.log(chalk3.dim(" " + "\u2500".repeat(cols - 4)));
|
|
35391
35663
|
console.log("");
|
|
35392
35664
|
const { startPolling: startPolling2 } = (init_poll(), __toCommonJS(exports_poll));
|
|
35393
|
-
const renderContent = (
|
|
35394
|
-
const lines = content.split(`
|
|
35395
|
-
`);
|
|
35396
|
-
const rendered = [];
|
|
35397
|
-
for (const line of lines) {
|
|
35398
|
-
let l = line;
|
|
35399
|
-
const h = l.match(/^(#{1,3})\s+(.+)/);
|
|
35400
|
-
if (h) {
|
|
35401
|
-
rendered.push(chalk2.bold(h[2]));
|
|
35402
|
-
continue;
|
|
35403
|
-
}
|
|
35404
|
-
if (/^\s*[-*+]\s/.test(l)) {
|
|
35405
|
-
rendered.push(" " + chalk2.dim("\u2022") + " " + renderInline(l.replace(/^\s*[-*+]\s/, "")));
|
|
35406
|
-
continue;
|
|
35407
|
-
}
|
|
35408
|
-
const ol = l.match(/^\s*(\d+)[.)]\s(.*)/);
|
|
35409
|
-
if (ol) {
|
|
35410
|
-
rendered.push(" " + chalk2.dim(ol[1] + ".") + " " + renderInline(ol[2]));
|
|
35411
|
-
continue;
|
|
35412
|
-
}
|
|
35413
|
-
if (l.startsWith(">")) {
|
|
35414
|
-
rendered.push(chalk2.dim(" \u2502 ") + chalk2.italic(renderInline(l.replace(/^>\s?/, ""))));
|
|
35415
|
-
continue;
|
|
35416
|
-
}
|
|
35417
|
-
if (l.trimStart().startsWith("```"))
|
|
35418
|
-
continue;
|
|
35419
|
-
if (l.trim() === "") {
|
|
35420
|
-
rendered.push("");
|
|
35421
|
-
continue;
|
|
35422
|
-
}
|
|
35423
|
-
rendered.push(renderInline(l));
|
|
35424
|
-
}
|
|
35425
|
-
return rendered.join(`
|
|
35426
|
-
`);
|
|
35427
|
-
};
|
|
35428
|
-
const renderInline = (text) => {
|
|
35429
|
-
return text.replace(/`([^`]+)`/g, (_, code) => chalk2.bgGray.white(` ${code} `)).replace(/\*\*\*(.+?)\*\*\*/g, (_, t) => chalk2.bold.italic(t)).replace(/\*\*(.+?)\*\*/g, (_, t) => chalk2.bold(t)).replace(/\*(.+?)\*/g, (_, t) => chalk2.italic(t)).replace(/~~(.+?)~~/g, (_, t) => chalk2.strikethrough(t));
|
|
35430
|
-
};
|
|
35665
|
+
const { renderContent: renderContent2 } = (init_terminal_markdown(), __toCommonJS(exports_terminal_markdown));
|
|
35431
35666
|
const desktopNotify = (title, body) => {
|
|
35432
35667
|
if (process.platform === "darwin") {
|
|
35433
35668
|
try {
|
|
@@ -35439,18 +35674,18 @@ program2.command("watch").description("Watch for new messages with desktop notif
|
|
|
35439
35674
|
}
|
|
35440
35675
|
};
|
|
35441
35676
|
const renderMessage = (msg) => {
|
|
35442
|
-
const time3 =
|
|
35443
|
-
const where = msg.space ?
|
|
35444
|
-
const priority = msg.priority !== "normal" ? msg.priority === "urgent" ?
|
|
35445
|
-
const blocking = msg.blocking ?
|
|
35446
|
-
const sender =
|
|
35677
|
+
const time3 = chalk3.dim(msg.created_at.slice(11, 19));
|
|
35678
|
+
const where = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow("DM");
|
|
35679
|
+
const priority = msg.priority !== "normal" ? msg.priority === "urgent" ? chalk3.red.bold(` [${msg.priority}]`) : msg.priority === "high" ? chalk3.yellow(` [${msg.priority}]`) : chalk3.dim(` [${msg.priority}]`) : "";
|
|
35680
|
+
const blocking = msg.blocking ? chalk3.red.bold(" \u26A0 BLOCKER") : "";
|
|
35681
|
+
const sender = chalk3.cyan.bold(msg.from_agent);
|
|
35447
35682
|
console.log(` ${sender} ${where} ${time3}${priority}${blocking}`);
|
|
35448
|
-
const content =
|
|
35683
|
+
const content = renderContent2(msg.content);
|
|
35449
35684
|
const indented = content.split(`
|
|
35450
35685
|
`).map((l) => " " + l).join(`
|
|
35451
35686
|
`);
|
|
35452
35687
|
console.log(indented);
|
|
35453
|
-
console.log(
|
|
35688
|
+
console.log(chalk3.dim(" " + "\xB7".repeat(Math.min(cols - 8, 60))));
|
|
35454
35689
|
console.log("");
|
|
35455
35690
|
};
|
|
35456
35691
|
if (opts.all) {
|
|
@@ -35461,12 +35696,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
|
|
|
35461
35696
|
}
|
|
35462
35697
|
const recent = [...dmRecent, ...spaceRecent].sort((a, b) => a.created_at.localeCompare(b.created_at)).slice(-20);
|
|
35463
35698
|
if (recent.length > 0) {
|
|
35464
|
-
console.log(
|
|
35699
|
+
console.log(chalk3.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
|
|
35465
35700
|
`));
|
|
35466
35701
|
for (const msg of recent) {
|
|
35467
35702
|
renderMessage(msg);
|
|
35468
35703
|
}
|
|
35469
|
-
console.log(
|
|
35704
|
+
console.log(chalk3.dim(` \u2500\u2500 Live \u2500\u2500
|
|
35470
35705
|
`));
|
|
35471
35706
|
}
|
|
35472
35707
|
} else {
|
|
@@ -35477,12 +35712,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
|
|
|
35477
35712
|
order: "asc"
|
|
35478
35713
|
});
|
|
35479
35714
|
if (recent.length > 0) {
|
|
35480
|
-
console.log(
|
|
35715
|
+
console.log(chalk3.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
|
|
35481
35716
|
`));
|
|
35482
35717
|
for (const msg of recent) {
|
|
35483
35718
|
renderMessage(msg);
|
|
35484
35719
|
}
|
|
35485
|
-
console.log(
|
|
35720
|
+
console.log(chalk3.dim(` \u2500\u2500 Live \u2500\u2500
|
|
35486
35721
|
`));
|
|
35487
35722
|
}
|
|
35488
35723
|
}
|
|
@@ -35510,7 +35745,7 @@ program2.command("watch").description("Watch for new messages with desktop notif
|
|
|
35510
35745
|
});
|
|
35511
35746
|
}
|
|
35512
35747
|
process.on("SIGINT", () => {
|
|
35513
|
-
console.log(
|
|
35748
|
+
console.log(chalk3.dim(`
|
|
35514
35749
|
Stopped watching.`));
|
|
35515
35750
|
closeDb();
|
|
35516
35751
|
process.exit(0);
|
|
@@ -35531,8 +35766,8 @@ program2.command("dashboard").description("Start web dashboard").option("--port
|
|
|
35531
35766
|
});
|
|
35532
35767
|
program2.action(() => {
|
|
35533
35768
|
if (!process.stdin.isTTY) {
|
|
35534
|
-
console.error(
|
|
35535
|
-
console.error(
|
|
35769
|
+
console.error(chalk3.red("Interactive mode requires a TTY terminal."));
|
|
35770
|
+
console.error(chalk3.dim("Use subcommands (send, read, sessions, etc.) for non-interactive use."));
|
|
35536
35771
|
process.exit(1);
|
|
35537
35772
|
}
|
|
35538
35773
|
const agent = resolveIdentity();
|