@hasna/conversations 0.1.18 → 0.1.19

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/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 join2 } from "path";
2063
- import { homedir as homedir2 } from "os";
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 join2(homedir2(), ".conversations", "attachments");
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 = join2(getAttachmentsDir(), String(message.id));
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 = join2(attachmentsDir, att.name);
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 limit = Number.isFinite(opts.limit) && opts.limit > 0 ? `LIMIT ${Math.floor(opts.limit)}` : "";
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} ${limit}`).all(...params);
2190
- return rows.map(parseMessage);
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 join3, dirname as dirname2 } from "path";
3095
- import { homedir as homedir3 } from "os";
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 = readFileSync(AGENT_ID_FILE, "utf-8").trim();
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 = join3(homedir3(), ".conversations", "agent-id");
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.18",
3506
+ version: "0.1.19",
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. Pass 'from' to identify yourself, or it falls back to CONVERSATIONS_AGENT_ID env var.",
32478
+ description: "Send a direct message to another agent.",
32290
32479
  inputSchema: {
32291
- from: exports_external.string().optional().describe("Your agent ID (e.g. 'claude-1', 'assistant'). Falls back to CONVERSATIONS_AGENT_ID env var."),
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("Send as a blocking message. Recipients must acknowledge before continuing.")
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: "Invalid metadata JSON." }],
32499
+ content: [{ type: "text", text: "invalid JSON" }],
32311
32500
  isError: true
32312
32501
  };
32313
32502
  }
@@ -32333,12 +32522,12 @@ var init_mcp2 = __esm(() => {
32333
32522
  description: "Read messages with optional filters. Returns messages sorted by time.",
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 agent ID"),
32337
- to: exports_external.string().optional().describe("Filter by recipient agent ID"),
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("Messages after this ISO timestamp"),
32340
- limit: exports_external.number().optional().describe("Max messages to return"),
32341
- unread_only: exports_external.boolean().optional().describe("Only return unread messages")
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);
@@ -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 by its ID. Automatically uses the same session and sends to the original sender.",
32552
+ description: "Reply to a message by ID. Uses the same session and sends to the 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 message IDs as read for the current agent. Set 'all' to true to mark all unread messages as read.",
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: "Provide message IDs or set 'all' to true." }],
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. Returns matching messages ordered by newest first.",
32609
+ description: "Full-text search across message content, newest first.",
32421
32610
  inputSchema: {
32422
- query: exports_external.string().describe("Search query string"),
32423
- space: exports_external.string().optional().describe("Filter by space name"),
32424
- from: exports_external.string().optional().describe("Filter by sender agent ID"),
32425
- to: exports_external.string().optional().describe("Filter by recipient agent ID"),
32426
- limit: exports_external.number().optional().describe("Max results to return (default 50)")
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 name"),
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 agent ID"),
32441
- since: exports_external.string().optional().describe("Messages after this ISO date"),
32442
- until: exports_external.string().optional().describe("Messages before this ISO date"),
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 new space. The creator is auto-joined. Spaces can be nested (max 3 levels) and associated with a project.",
32642
+ description: "Create a new space. Creator is auto-joined. Supports nesting (max 3 levels) and project association.",
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 (e.g. 'deployments', 'code-review')"),
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 for nesting (max 3 levels deep)"),
32459
- project_id: exports_external.string().optional().describe("Project ID to associate this space with")
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: `Space #${name} already exists` }],
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 all available spaces with member and message counts. Can filter by project or parent. Archived spaces are excluded by default.",
32672
+ description: "List spaces with member/message counts. Archived spaces excluded by default.",
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 name. Use 'null' for top-level only."),
32487
- include_archived: exports_external.boolean().optional().describe("Include archived spaces (default: false)")
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("Send as a blocking message. All space members must acknowledge.")
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: `Space #${space} not found` }],
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("Messages after this ISO timestamp"),
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: `Space #${space} not found` }],
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 association.",
32776
+ description: "Update a space's description, parent, or project.",
32588
32777
  inputSchema: {
32589
- name: exports_external.string().describe("Space name to update"),
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 name (use 'null' to remove parent)"),
32592
- project_id: exports_external.string().optional().describe("New project ID (use 'null' to remove project)")
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. Archived spaces are hidden from list by default.",
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 new project. Projects organize spaces and provide context for agent collaboration.",
32843
+ description: "Create a new project to organize 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 to project on disk"),
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(`JSON array of tags (e.g. '["backend", "api"]')`),
32662
- metadata: exports_external.string().optional().describe("JSON metadata string"),
32663
- settings: exports_external.string().optional().describe("JSON settings string")
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: "Invalid tags JSON. Expected array of strings." }],
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: "Invalid metadata JSON." }],
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: "Invalid settings JSON." }],
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: `Project "${name}" already exists` }],
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 project status")
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: `Project "${id}" not found` }],
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 project name"),
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 string"),
32772
- settings: exports_external.string().optional().describe("JSON settings string")
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: "Invalid tags JSON." }],
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: "Invalid metadata JSON." }],
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: "Invalid settings JSON." }],
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 still reference it.",
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: `Project "${id}" not found` }],
33028
+ content: [{ type: "text", text: `project "${id}" not found` }],
32840
33029
  isError: true
32841
33030
  };
32842
33031
  }
@@ -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: `Message #${id} not found or not your message` }],
33054
+ content: [{ type: "text", text: `not found or forbidden` }],
32866
33055
  isError: true
32867
33056
  };
32868
33057
  }
@@ -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: `Message #${id} not found or not your message` }],
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. Pinned messages can be retrieved with get_pinned_messages.",
33085
+ description: "Pin a message. Retrieve pinned messages with get_pinned_messages.",
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: `Message #${id} not found` }],
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: `Message #${id} not found` }],
33111
+ content: [{ type: "text", text: `message #${id} not found` }],
32923
33112
  isError: true
32924
33113
  };
32925
33114
  }
@@ -32931,7 +33120,7 @@ var init_mcp2 = __esm(() => {
32931
33120
  title: "Get Pinned Messages",
32932
33121
  description: "Retrieve pinned messages, optionally filtered by space or session.",
32933
33122
  inputSchema: {
32934
- space: exports_external.string().optional().describe("Filter by space name"),
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
  }
@@ -32957,9 +33146,9 @@ var init_mcp2 = __esm(() => {
32957
33146
  });
32958
33147
  server.registerTool("list_agents", {
32959
33148
  title: "List Agents",
32960
- description: "List all agents with their presence status. Returns agent name, status, last seen time, and whether they are online.",
33149
+ description: "List agents with presence status (name, status, last_seen, online).",
32961
33150
  inputSchema: {
32962
- online_only: exports_external.boolean().optional().describe("Only return agents that are currently online (seen within last 60 seconds)")
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 targeting you. Returns messages that must be acknowledged before continuing.",
33161
+ description: "Check for unread blocking messages targeting you. Must acknowledge before continuing.",
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. Only the agent itself should remove its own presence.",
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: `Agent "${agent}" not found` }],
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. By default renames yourself.",
33195
+ description: "Rename an agent in the presence list. Defaults to renaming yourself.",
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: "New name cannot be empty" }],
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: `Agent "${oldName}" not found in presence list` }],
33213
+ content: [{ type: "text", text: `agent "${oldName}" not found` }],
33025
33214
  isError: true
33026
33215
  };
33027
33216
  }
@@ -33049,7 +33238,7 @@ var exports_serve = {};
33049
33238
  __export(exports_serve, {
33050
33239
  startDashboardServer: () => startDashboardServer
33051
33240
  });
33052
- import { join as join4, resolve, sep } from "path";
33241
+ import { join as join5, resolve, sep } from "path";
33053
33242
  import { existsSync } from "fs";
33054
33243
  function securityHeaders(base) {
33055
33244
  const headers = new Headers(base);
@@ -33120,7 +33309,7 @@ function isSameOrigin(req) {
33120
33309
  function startDashboardServer(port = 0, host) {
33121
33310
  const resolvedPort = normalizePort(port, 0);
33122
33311
  const resolvedHost = normalizeHost(host ?? process.env.CONVERSATIONS_DASHBOARD_HOST);
33123
- const dashboardDist = join4(import.meta.dir, "../../dashboard/dist");
33312
+ const dashboardDist = join5(import.meta.dir, "../../dashboard/dist");
33124
33313
  const hasDist = existsSync(dashboardDist);
33125
33314
  const server2 = Bun.serve({
33126
33315
  port: resolvedPort,
@@ -33504,7 +33693,7 @@ function startDashboardServer(port = 0, host) {
33504
33693
  headers.set("Content-Type", file2.type);
33505
33694
  return new Response(file2, { headers });
33506
33695
  }
33507
- file2 = Bun.file(join4(dashboardDist, "index.html"));
33696
+ file2 = Bun.file(join5(dashboardDist, "index.html"));
33508
33697
  if (await file2.exists()) {
33509
33698
  const headers = securityHeaders();
33510
33699
  if (file2.type)
@@ -33560,7 +33749,8 @@ init_projects();
33560
33749
  init_db();
33561
33750
  init_identity();
33562
33751
  init_presence();
33563
- import chalk2 from "chalk";
33752
+ init_terminal_markdown();
33753
+ import chalk3 from "chalk";
33564
33754
  import { render } from "ink";
33565
33755
  import React8 from "react";
33566
33756
 
@@ -33571,7 +33761,7 @@ import { Box as Box6, Text as Text7, useApp, useInput as useInput5 } from "ink";
33571
33761
  // node_modules/ink-text-input/build/index.js
33572
33762
  import React, { useState, useEffect } from "react";
33573
33763
  import { Text, useInput } from "ink";
33574
- import chalk from "chalk";
33764
+ import chalk2 from "chalk";
33575
33765
  function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
33576
33766
  const [state, setState] = useState({
33577
33767
  cursorOffset: (originalValue || "").length,
@@ -33596,17 +33786,17 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
33596
33786
  const cursorActualWidth = highlightPastedText ? cursorWidth : 0;
33597
33787
  const value = mask ? mask.repeat(originalValue.length) : originalValue;
33598
33788
  let renderedValue = value;
33599
- let renderedPlaceholder = placeholder ? chalk.grey(placeholder) : undefined;
33789
+ let renderedPlaceholder = placeholder ? chalk2.grey(placeholder) : undefined;
33600
33790
  if (showCursor && focus) {
33601
- renderedPlaceholder = placeholder.length > 0 ? chalk.inverse(placeholder[0]) + chalk.grey(placeholder.slice(1)) : chalk.inverse(" ");
33602
- renderedValue = value.length > 0 ? "" : chalk.inverse(" ");
33791
+ renderedPlaceholder = placeholder.length > 0 ? chalk2.inverse(placeholder[0]) + chalk2.grey(placeholder.slice(1)) : chalk2.inverse(" ");
33792
+ renderedValue = value.length > 0 ? "" : chalk2.inverse(" ");
33603
33793
  let i = 0;
33604
33794
  for (const char of value) {
33605
- renderedValue += i >= cursorOffset - cursorActualWidth && i <= cursorOffset ? chalk.inverse(char) : char;
33795
+ renderedValue += i >= cursorOffset - cursorActualWidth && i <= cursorOffset ? chalk2.inverse(char) : char;
33606
33796
  i++;
33607
33797
  }
33608
33798
  if (value.length > 0 && cursorOffset === value.length) {
33609
- renderedValue += chalk.inverse(" ");
33799
+ renderedValue += chalk2.inverse(" ");
33610
33800
  }
33611
33801
  }
33612
33802
  useInput((input, key) => {
@@ -34507,15 +34697,15 @@ program2.command("send").description("Send a message to an agent").argument("<me
34507
34697
  const content = typeof message === "string" ? message : "";
34508
34698
  const session = typeof opts.session === "string" && opts.session.trim() ? opts.session.trim() : undefined;
34509
34699
  if (!from) {
34510
- console.error(chalk2.red("Sender identity is required."));
34700
+ console.error(chalk3.red("Sender identity is required."));
34511
34701
  process.exit(1);
34512
34702
  }
34513
34703
  if (!to) {
34514
- console.error(chalk2.red("Recipient is required."));
34704
+ console.error(chalk3.red("Recipient is required."));
34515
34705
  process.exit(1);
34516
34706
  }
34517
34707
  if (!content.trim()) {
34518
- console.error(chalk2.red("Message content cannot be empty."));
34708
+ console.error(chalk3.red("Message content cannot be empty."));
34519
34709
  process.exit(1);
34520
34710
  }
34521
34711
  let metadata;
@@ -34523,7 +34713,7 @@ program2.command("send").description("Send a message to an agent").argument("<me
34523
34713
  try {
34524
34714
  metadata = JSON.parse(opts.metadata);
34525
34715
  } catch {
34526
- console.error(chalk2.red("Invalid --metadata JSON."));
34716
+ console.error(chalk3.red("Invalid --metadata JSON."));
34527
34717
  process.exit(1);
34528
34718
  }
34529
34719
  }
@@ -34542,7 +34732,7 @@ program2.command("send").description("Send a message to an agent").argument("<me
34542
34732
  if (opts.json) {
34543
34733
  console.log(JSON.stringify(msg, null, 2));
34544
34734
  } else {
34545
- console.log(chalk2.green(`Message sent`) + chalk2.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
34735
+ console.log(chalk3.green(`Message sent`) + chalk3.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
34546
34736
  }
34547
34737
  closeDb();
34548
34738
  });
@@ -34572,15 +34762,20 @@ program2.command("read").description("Read messages").option("--session <id>", "
34572
34762
  console.log(JSON.stringify(messages, null, 2));
34573
34763
  } else {
34574
34764
  if (messages.length === 0) {
34575
- console.log(chalk2.dim("No messages found."));
34765
+ console.log(chalk3.dim("No messages found."));
34576
34766
  } else {
34577
34767
  for (const msg of messages) {
34578
- const time3 = chalk2.dim(msg.created_at.slice(11, 19));
34579
- const from = chalk2.cyan(msg.from_agent);
34580
- const to = msg.space ? chalk2.magenta(`#${msg.space}`) : chalk2.yellow(msg.to_agent);
34581
- const priority = msg.priority !== "normal" ? chalk2.red(` [${msg.priority}]`) : "";
34582
- const unread = !msg.read_at ? chalk2.green(" *") : "";
34583
- console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}: ${msg.content}`);
34768
+ const time3 = chalk3.dim(msg.created_at.slice(11, 19));
34769
+ const from = chalk3.cyan(msg.from_agent);
34770
+ const to = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow(msg.to_agent);
34771
+ const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
34772
+ const unread = !msg.read_at ? chalk3.green(" *") : "";
34773
+ console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}`);
34774
+ const rendered = renderContent(msg.content);
34775
+ const indented = rendered.split(`
34776
+ `).map((l) => " " + l).join(`
34777
+ `);
34778
+ console.log(indented);
34584
34779
  }
34585
34780
  }
34586
34781
  }
@@ -34589,7 +34784,7 @@ program2.command("read").description("Read messages").option("--session <id>", "
34589
34784
  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
34785
  const q = typeof query === "string" ? query.trim() : "";
34591
34786
  if (!q) {
34592
- console.error(chalk2.red("Search query cannot be empty."));
34787
+ console.error(chalk3.red("Search query cannot be empty."));
34593
34788
  process.exit(1);
34594
34789
  }
34595
34790
  const messages = searchMessages({
@@ -34603,16 +34798,16 @@ program2.command("search").description("Search messages by content").argument("<
34603
34798
  console.log(JSON.stringify(messages, null, 2));
34604
34799
  } else {
34605
34800
  if (messages.length === 0) {
34606
- console.log(chalk2.dim("No messages found."));
34801
+ console.log(chalk3.dim("No messages found."));
34607
34802
  } else {
34608
- console.log(chalk2.dim(`Found ${messages.length} result(s) for "${q}":
34803
+ console.log(chalk3.dim(`Found ${messages.length} result(s) for "${q}":
34609
34804
  `));
34610
34805
  for (const msg of messages) {
34611
- const time3 = chalk2.dim(msg.created_at.slice(11, 19));
34612
- const from = chalk2.cyan(msg.from_agent);
34613
- const to = msg.space ? chalk2.magenta(`#${msg.space}`) : chalk2.yellow(msg.to_agent);
34614
- const priority = msg.priority !== "normal" ? chalk2.red(` [${msg.priority}]`) : "";
34615
- const unread = !msg.read_at ? chalk2.green(" *") : "";
34806
+ const time3 = chalk3.dim(msg.created_at.slice(11, 19));
34807
+ const from = chalk3.cyan(msg.from_agent);
34808
+ const to = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow(msg.to_agent);
34809
+ const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
34810
+ const unread = !msg.read_at ? chalk3.green(" *") : "";
34616
34811
  console.log(`${time3} ${from} \u2192 ${to}${priority}${unread}: ${msg.content}`);
34617
34812
  }
34618
34813
  }
@@ -34625,12 +34820,12 @@ program2.command("sessions").description("List conversation sessions").option("-
34625
34820
  console.log(JSON.stringify(sessions, null, 2));
34626
34821
  } else {
34627
34822
  if (sessions.length === 0) {
34628
- console.log(chalk2.dim("No sessions found."));
34823
+ console.log(chalk3.dim("No sessions found."));
34629
34824
  } else {
34630
34825
  for (const s of sessions) {
34631
- const unread = s.unread_count > 0 ? chalk2.green(` (${s.unread_count} unread)`) : "";
34826
+ const unread = s.unread_count > 0 ? chalk3.green(` (${s.unread_count} unread)`) : "";
34632
34827
  const participants = s.participants.join(", ");
34633
- console.log(`${chalk2.bold(s.session_id)} \u2014 ${participants} \u2014 ${s.message_count} messages${unread}`);
34828
+ console.log(`${chalk3.bold(s.session_id)} \u2014 ${participants} \u2014 ${s.message_count} messages${unread}`);
34634
34829
  }
34635
34830
  }
34636
34831
  }
@@ -34639,17 +34834,17 @@ program2.command("sessions").description("List conversation sessions").option("-
34639
34834
  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
34835
  const original = getMessageById(opts.to);
34641
34836
  if (!original) {
34642
- console.error(chalk2.red(`Message #${opts.to} not found.`));
34837
+ console.error(chalk3.red(`Message #${opts.to} not found.`));
34643
34838
  process.exit(1);
34644
34839
  }
34645
34840
  const from = resolveIdentity(opts.from).trim();
34646
34841
  const content = typeof message === "string" ? message : "";
34647
34842
  if (!from) {
34648
- console.error(chalk2.red("Sender identity is required."));
34843
+ console.error(chalk3.red("Sender identity is required."));
34649
34844
  process.exit(1);
34650
34845
  }
34651
34846
  if (!content.trim()) {
34652
- console.error(chalk2.red("Reply content cannot be empty."));
34847
+ console.error(chalk3.red("Reply content cannot be empty."));
34653
34848
  process.exit(1);
34654
34849
  }
34655
34850
  const space = original.space || (original.session_id?.startsWith("space:") ? original.session_id.slice(6) : undefined);
@@ -34665,7 +34860,7 @@ program2.command("reply").description("Reply to a message (uses same session)").
34665
34860
  if (opts.json) {
34666
34861
  console.log(JSON.stringify(msg, null, 2));
34667
34862
  } else {
34668
- console.log(chalk2.green(`Reply sent`) + chalk2.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
34863
+ console.log(chalk3.green(`Reply sent`) + chalk3.dim(` (id: ${msg.id}, session: ${msg.session_id})`));
34669
34864
  }
34670
34865
  closeDb();
34671
34866
  });
@@ -34681,13 +34876,13 @@ program2.command("mark-read").description("Mark messages as read").argument("[id
34681
34876
  } else if (ids.length > 0) {
34682
34877
  count = markRead(ids.map(Number), agent);
34683
34878
  } else {
34684
- console.error(chalk2.red("Provide message IDs, --all, --session, or --space flag."));
34879
+ console.error(chalk3.red("Provide message IDs, --all, --session, or --space flag."));
34685
34880
  process.exit(1);
34686
34881
  }
34687
34882
  if (opts.json) {
34688
34883
  console.log(JSON.stringify({ marked_read: count }));
34689
34884
  } else {
34690
- console.log(chalk2.green(`Marked ${count} message(s) as read.`));
34885
+ console.log(chalk3.green(`Marked ${count} message(s) as read.`));
34691
34886
  }
34692
34887
  closeDb();
34693
34888
  });
@@ -34723,7 +34918,7 @@ program2.command("status").description("Show database stats").option("--json", "
34723
34918
  if (opts.json) {
34724
34919
  console.log(JSON.stringify(stats, null, 2));
34725
34920
  } else {
34726
- console.log(chalk2.bold("Conversations Status"));
34921
+ console.log(chalk3.bold("Conversations Status"));
34727
34922
  console.log(` DB Path: ${stats.db_path}`);
34728
34923
  console.log(` Messages: ${stats.total_messages}`);
34729
34924
  console.log(` Sessions: ${stats.total_sessions}`);
@@ -34745,7 +34940,7 @@ program2.command("update").description("Check for and install updates").option("
34745
34940
  if (opts.json) {
34746
34941
  console.log(JSON.stringify({ error: "Failed to check npm registry" }));
34747
34942
  } else {
34748
- console.error(chalk2.red("Failed to check npm registry for updates."));
34943
+ console.error(chalk3.red("Failed to check npm registry for updates."));
34749
34944
  }
34750
34945
  process.exit(1);
34751
34946
  }
@@ -34754,18 +34949,18 @@ program2.command("update").description("Check for and install updates").option("
34754
34949
  if (opts.json) {
34755
34950
  console.log(JSON.stringify({ current, latest, updateAvailable }));
34756
34951
  } else if (updateAvailable) {
34757
- console.log(`Current version: ${chalk2.yellow(current)}`);
34758
- console.log(`Latest version: ${chalk2.green(latest)}`);
34759
- console.log(chalk2.cyan(`Run ${chalk2.bold("conversations update")} to install.`));
34952
+ console.log(`Current version: ${chalk3.yellow(current)}`);
34953
+ console.log(`Latest version: ${chalk3.green(latest)}`);
34954
+ console.log(chalk3.cyan(`Run ${chalk3.bold("conversations update")} to install.`));
34760
34955
  } else {
34761
- console.log(chalk2.green(`Already on latest version (${current})`));
34956
+ console.log(chalk3.green(`Already on latest version (${current})`));
34762
34957
  }
34763
34958
  return;
34764
34959
  }
34765
34960
  if (opts.json) {
34766
34961
  console.log(JSON.stringify({ current, latest, updateAvailable, status: "updating" }));
34767
34962
  } else {
34768
- console.log(`Updating from ${chalk2.yellow(current)} to ${chalk2.green(latest)}...`);
34963
+ console.log(`Updating from ${chalk3.yellow(current)} to ${chalk3.green(latest)}...`);
34769
34964
  }
34770
34965
  const proc = Bun.spawn(["bun", "install", "-g", `@hasna/conversations@${latest}`], {
34771
34966
  stdout: "inherit",
@@ -34774,14 +34969,14 @@ program2.command("update").description("Check for and install updates").option("
34774
34969
  const exitCode = await proc.exited;
34775
34970
  if (exitCode === 0) {
34776
34971
  if (!opts.json) {
34777
- console.log(chalk2.green(`
34972
+ console.log(chalk3.green(`
34778
34973
  Successfully updated to v${latest}`));
34779
34974
  }
34780
34975
  } else {
34781
34976
  if (opts.json) {
34782
34977
  console.log(JSON.stringify({ error: "Update failed", exitCode }));
34783
34978
  } else {
34784
- console.error(chalk2.red(`
34979
+ console.error(chalk3.red(`
34785
34980
  Update failed (exit code ${exitCode})`));
34786
34981
  }
34787
34982
  process.exit(1);
@@ -34792,11 +34987,11 @@ space.command("create").description("Create a new space").argument("<name>", "Sp
34792
34987
  const agent = resolveIdentity(opts.from).trim();
34793
34988
  const spaceName = typeof name === "string" ? name.trim() : "";
34794
34989
  if (!agent) {
34795
- console.error(chalk2.red("Creator identity is required."));
34990
+ console.error(chalk3.red("Creator identity is required."));
34796
34991
  process.exit(1);
34797
34992
  }
34798
34993
  if (!spaceName) {
34799
- console.error(chalk2.red("Space name cannot be empty."));
34994
+ console.error(chalk3.red("Space name cannot be empty."));
34800
34995
  process.exit(1);
34801
34996
  }
34802
34997
  try {
@@ -34809,14 +35004,14 @@ space.command("create").description("Create a new space").argument("<name>", "Sp
34809
35004
  if (opts.json) {
34810
35005
  console.log(JSON.stringify(sp, null, 2));
34811
35006
  } else {
34812
- console.log(chalk2.green(`Space #${sp.name} created`) + (sp.description ? chalk2.dim(` \u2014 ${sp.description}`) : ""));
35007
+ console.log(chalk3.green(`Space #${sp.name} created`) + (sp.description ? chalk3.dim(` \u2014 ${sp.description}`) : ""));
34813
35008
  }
34814
35009
  } catch (e) {
34815
35010
  if (e.message?.includes("UNIQUE constraint")) {
34816
- console.error(chalk2.red(`Space #${spaceName} already exists.`));
35011
+ console.error(chalk3.red(`Space #${spaceName} already exists.`));
34817
35012
  process.exit(1);
34818
35013
  }
34819
- console.error(chalk2.red(e.message));
35014
+ console.error(chalk3.red(e.message));
34820
35015
  process.exit(1);
34821
35016
  }
34822
35017
  closeDb();
@@ -34837,13 +35032,13 @@ space.command("list").description("List all spaces").option("--project <id>", "F
34837
35032
  console.log(JSON.stringify(spaces, null, 2));
34838
35033
  } else {
34839
35034
  if (spaces.length === 0) {
34840
- console.log(chalk2.dim("No spaces found."));
35035
+ console.log(chalk3.dim("No spaces found."));
34841
35036
  } else {
34842
35037
  for (const sp of spaces) {
34843
- const desc = sp.description ? chalk2.dim(` \u2014 ${sp.description}`) : "";
34844
- const parent = sp.parent_id ? chalk2.dim(` (child of ${sp.parent_id})`) : "";
34845
- const archived = sp.archived_at ? chalk2.yellow(" [archived]") : "";
34846
- console.log(`${chalk2.magenta(`#${sp.name}`)}${desc}${parent}${archived} ${sp.member_count} members, ${sp.message_count} messages`);
35038
+ const desc = sp.description ? chalk3.dim(` \u2014 ${sp.description}`) : "";
35039
+ const parent = sp.parent_id ? chalk3.dim(` (child of ${sp.parent_id})`) : "";
35040
+ const archived = sp.archived_at ? chalk3.yellow(" [archived]") : "";
35041
+ console.log(`${chalk3.magenta(`#${sp.name}`)}${desc}${parent}${archived} ${sp.member_count} members, ${sp.message_count} messages`);
34847
35042
  }
34848
35043
  }
34849
35044
  }
@@ -34852,7 +35047,7 @@ space.command("list").description("List all spaces").option("--project <id>", "F
34852
35047
  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
35048
  const spaceName = typeof name === "string" ? name.trim() : "";
34854
35049
  if (!spaceName) {
34855
- console.error(chalk2.red("Space name cannot be empty."));
35050
+ console.error(chalk3.red("Space name cannot be empty."));
34856
35051
  process.exit(1);
34857
35052
  }
34858
35053
  const updates = {};
@@ -34867,10 +35062,10 @@ space.command("update").description("Update a space").argument("<name>", "Space
34867
35062
  if (opts.json) {
34868
35063
  console.log(JSON.stringify(sp, null, 2));
34869
35064
  } else {
34870
- console.log(chalk2.green(`Space #${sp.name} updated.`));
35065
+ console.log(chalk3.green(`Space #${sp.name} updated.`));
34871
35066
  }
34872
35067
  } catch (e) {
34873
- console.error(chalk2.red(e.message));
35068
+ console.error(chalk3.red(e.message));
34874
35069
  process.exit(1);
34875
35070
  }
34876
35071
  closeDb();
@@ -34878,7 +35073,7 @@ space.command("update").description("Update a space").argument("<name>", "Space
34878
35073
  space.command("archive").description("Archive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
34879
35074
  const spaceName = typeof name === "string" ? name.trim() : "";
34880
35075
  if (!spaceName) {
34881
- console.error(chalk2.red("Space name cannot be empty."));
35076
+ console.error(chalk3.red("Space name cannot be empty."));
34882
35077
  process.exit(1);
34883
35078
  }
34884
35079
  try {
@@ -34886,10 +35081,10 @@ space.command("archive").description("Archive a space").argument("<name>", "Spac
34886
35081
  if (opts.json) {
34887
35082
  console.log(JSON.stringify(sp, null, 2));
34888
35083
  } else {
34889
- console.log(chalk2.green(`Space #${sp.name} archived.`));
35084
+ console.log(chalk3.green(`Space #${sp.name} archived.`));
34890
35085
  }
34891
35086
  } catch (e) {
34892
- console.error(chalk2.red(e.message));
35087
+ console.error(chalk3.red(e.message));
34893
35088
  process.exit(1);
34894
35089
  }
34895
35090
  closeDb();
@@ -34897,7 +35092,7 @@ space.command("archive").description("Archive a space").argument("<name>", "Spac
34897
35092
  space.command("unarchive").description("Unarchive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
34898
35093
  const spaceName = typeof name === "string" ? name.trim() : "";
34899
35094
  if (!spaceName) {
34900
- console.error(chalk2.red("Space name cannot be empty."));
35095
+ console.error(chalk3.red("Space name cannot be empty."));
34901
35096
  process.exit(1);
34902
35097
  }
34903
35098
  try {
@@ -34905,10 +35100,10 @@ space.command("unarchive").description("Unarchive a space").argument("<name>", "
34905
35100
  if (opts.json) {
34906
35101
  console.log(JSON.stringify(sp, null, 2));
34907
35102
  } else {
34908
- console.log(chalk2.green(`Space #${sp.name} unarchived.`));
35103
+ console.log(chalk3.green(`Space #${sp.name} unarchived.`));
34909
35104
  }
34910
35105
  } catch (e) {
34911
- console.error(chalk2.red(e.message));
35106
+ console.error(chalk3.red(e.message));
34912
35107
  process.exit(1);
34913
35108
  }
34914
35109
  closeDb();
@@ -34918,20 +35113,20 @@ space.command("send").description("Send a message to a space").argument("<space>
34918
35113
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
34919
35114
  const content = typeof message === "string" ? message : "";
34920
35115
  if (!from) {
34921
- console.error(chalk2.red("Sender identity is required."));
35116
+ console.error(chalk3.red("Sender identity is required."));
34922
35117
  process.exit(1);
34923
35118
  }
34924
35119
  if (!spaceArg) {
34925
- console.error(chalk2.red("Space name cannot be empty."));
35120
+ console.error(chalk3.red("Space name cannot be empty."));
34926
35121
  process.exit(1);
34927
35122
  }
34928
35123
  if (!content.trim()) {
34929
- console.error(chalk2.red("Message content cannot be empty."));
35124
+ console.error(chalk3.red("Message content cannot be empty."));
34930
35125
  process.exit(1);
34931
35126
  }
34932
35127
  const sp = getSpace(spaceArg);
34933
35128
  if (!sp) {
34934
- console.error(chalk2.red(`Space #${spaceArg} not found.`));
35129
+ console.error(chalk3.red(`Space #${spaceArg} not found.`));
34935
35130
  process.exit(1);
34936
35131
  }
34937
35132
  const msg = sendMessage({
@@ -34945,14 +35140,14 @@ space.command("send").description("Send a message to a space").argument("<space>
34945
35140
  if (opts.json) {
34946
35141
  console.log(JSON.stringify(msg, null, 2));
34947
35142
  } else {
34948
- console.log(chalk2.green(`Message sent to #${spaceArg}`) + chalk2.dim(` (id: ${msg.id})`));
35143
+ console.log(chalk3.green(`Message sent to #${spaceArg}`) + chalk3.dim(` (id: ${msg.id})`));
34949
35144
  }
34950
35145
  closeDb();
34951
35146
  });
34952
35147
  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
35148
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
34954
35149
  if (!spaceArg) {
34955
- console.error(chalk2.red("Space name cannot be empty."));
35150
+ console.error(chalk3.red("Space name cannot be empty."));
34956
35151
  process.exit(1);
34957
35152
  }
34958
35153
  const messages = readMessages({
@@ -34964,13 +35159,18 @@ space.command("read").description("Read messages from a space").argument("<space
34964
35159
  console.log(JSON.stringify(messages, null, 2));
34965
35160
  } else {
34966
35161
  if (messages.length === 0) {
34967
- console.log(chalk2.dim(`No messages in #${spaceArg}.`));
35162
+ console.log(chalk3.dim(`No messages in #${spaceArg}.`));
34968
35163
  } else {
34969
35164
  for (const msg of messages) {
34970
- const time3 = chalk2.dim(msg.created_at.slice(11, 19));
34971
- const from = chalk2.cyan(msg.from_agent);
34972
- const priority = msg.priority !== "normal" ? chalk2.red(` [${msg.priority}]`) : "";
34973
- console.log(`${time3} ${from} \u2192 ${chalk2.magenta(`#${spaceArg}`)}${priority}: ${msg.content}`);
35165
+ const time3 = chalk3.dim(msg.created_at.slice(11, 19));
35166
+ const from = chalk3.cyan(msg.from_agent);
35167
+ const priority = msg.priority !== "normal" ? chalk3.red(` [${msg.priority}]`) : "";
35168
+ console.log(`${time3} ${from} \u2192 ${chalk3.magenta(`#${spaceArg}`)}${priority}`);
35169
+ const rendered = renderContent(msg.content);
35170
+ const indented = rendered.split(`
35171
+ `).map((l) => " " + l).join(`
35172
+ `);
35173
+ console.log(indented);
34974
35174
  }
34975
35175
  }
34976
35176
  }
@@ -34980,22 +35180,22 @@ space.command("join").description("Join a space").argument("<space>", "Space nam
34980
35180
  const agent = resolveIdentity(opts.from).trim();
34981
35181
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
34982
35182
  if (!agent) {
34983
- console.error(chalk2.red("Agent identity is required."));
35183
+ console.error(chalk3.red("Agent identity is required."));
34984
35184
  process.exit(1);
34985
35185
  }
34986
35186
  if (!spaceArg) {
34987
- console.error(chalk2.red("Space name cannot be empty."));
35187
+ console.error(chalk3.red("Space name cannot be empty."));
34988
35188
  process.exit(1);
34989
35189
  }
34990
35190
  const ok = joinSpace(spaceArg, agent);
34991
35191
  if (!ok) {
34992
- console.error(chalk2.red(`Space #${spaceArg} not found.`));
35192
+ console.error(chalk3.red(`Space #${spaceArg} not found.`));
34993
35193
  process.exit(1);
34994
35194
  }
34995
35195
  if (opts.json) {
34996
35196
  console.log(JSON.stringify({ space: spaceArg, agent, joined: true }));
34997
35197
  } else {
34998
- console.log(chalk2.green(`${agent} joined #${spaceArg}`));
35198
+ console.log(chalk3.green(`${agent} joined #${spaceArg}`));
34999
35199
  }
35000
35200
  closeDb();
35001
35201
  });
@@ -35003,11 +35203,11 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
35003
35203
  const agent = resolveIdentity(opts.from).trim();
35004
35204
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
35005
35205
  if (!agent) {
35006
- console.error(chalk2.red("Agent identity is required."));
35206
+ console.error(chalk3.red("Agent identity is required."));
35007
35207
  process.exit(1);
35008
35208
  }
35009
35209
  if (!spaceArg) {
35010
- console.error(chalk2.red("Space name cannot be empty."));
35210
+ console.error(chalk3.red("Space name cannot be empty."));
35011
35211
  process.exit(1);
35012
35212
  }
35013
35213
  const ok = leaveSpace(spaceArg, agent);
@@ -35015,9 +35215,9 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
35015
35215
  console.log(JSON.stringify({ space: spaceArg, agent, left: ok }));
35016
35216
  } else {
35017
35217
  if (ok) {
35018
- console.log(chalk2.green(`${agent} left #${spaceArg}`));
35218
+ console.log(chalk3.green(`${agent} left #${spaceArg}`));
35019
35219
  } else {
35020
- console.log(chalk2.dim(`${agent} was not a member of #${spaceArg}`));
35220
+ console.log(chalk3.dim(`${agent} was not a member of #${spaceArg}`));
35021
35221
  }
35022
35222
  }
35023
35223
  closeDb();
@@ -35025,7 +35225,7 @@ space.command("leave").description("Leave a space").argument("<space>", "Space n
35025
35225
  space.command("members").description("List space members").argument("<space>", "Space name").option("--json", "Output as JSON").action((spaceName, opts) => {
35026
35226
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
35027
35227
  if (!spaceArg) {
35028
- console.error(chalk2.red("Space name cannot be empty."));
35228
+ console.error(chalk3.red("Space name cannot be empty."));
35029
35229
  process.exit(1);
35030
35230
  }
35031
35231
  const members = getSpaceMembers(spaceArg);
@@ -35033,11 +35233,11 @@ space.command("members").description("List space members").argument("<space>", "
35033
35233
  console.log(JSON.stringify(members, null, 2));
35034
35234
  } else {
35035
35235
  if (members.length === 0) {
35036
- console.log(chalk2.dim(`No members in #${spaceArg}.`));
35236
+ console.log(chalk3.dim(`No members in #${spaceArg}.`));
35037
35237
  } else {
35038
- console.log(chalk2.magenta(`#${spaceArg}`) + chalk2.dim(` \u2014 ${members.length} member(s)`));
35238
+ console.log(chalk3.magenta(`#${spaceArg}`) + chalk3.dim(` \u2014 ${members.length} member(s)`));
35039
35239
  for (const m of members) {
35040
- console.log(` ${chalk2.cyan(m.agent)} ${chalk2.dim(`joined ${m.joined_at.slice(0, 10)}`)}`);
35240
+ console.log(` ${chalk3.cyan(m.agent)} ${chalk3.dim(`joined ${m.joined_at.slice(0, 10)}`)}`);
35041
35241
  }
35042
35242
  }
35043
35243
  }
@@ -35048,11 +35248,11 @@ project.command("create").description("Create a new project").argument("<name>",
35048
35248
  const agent = resolveIdentity(opts.from).trim();
35049
35249
  const projectName = typeof name === "string" ? name.trim() : "";
35050
35250
  if (!agent) {
35051
- console.error(chalk2.red("Creator identity is required."));
35251
+ console.error(chalk3.red("Creator identity is required."));
35052
35252
  process.exit(1);
35053
35253
  }
35054
35254
  if (!projectName) {
35055
- console.error(chalk2.red("Project name cannot be empty."));
35255
+ console.error(chalk3.red("Project name cannot be empty."));
35056
35256
  process.exit(1);
35057
35257
  }
35058
35258
  let tags;
@@ -35060,7 +35260,7 @@ project.command("create").description("Create a new project").argument("<name>",
35060
35260
  try {
35061
35261
  tags = JSON.parse(opts.tags);
35062
35262
  } catch {
35063
- console.error(chalk2.red("Invalid --tags JSON. Expected array of strings."));
35263
+ console.error(chalk3.red("Invalid --tags JSON. Expected array of strings."));
35064
35264
  process.exit(1);
35065
35265
  }
35066
35266
  }
@@ -35076,14 +35276,14 @@ project.command("create").description("Create a new project").argument("<name>",
35076
35276
  if (opts.json) {
35077
35277
  console.log(JSON.stringify(p, null, 2));
35078
35278
  } else {
35079
- console.log(chalk2.green(`Project "${p.name}" created`) + chalk2.dim(` (id: ${p.id})`));
35279
+ console.log(chalk3.green(`Project "${p.name}" created`) + chalk3.dim(` (id: ${p.id})`));
35080
35280
  }
35081
35281
  } catch (e) {
35082
35282
  if (e.message?.includes("UNIQUE constraint")) {
35083
- console.error(chalk2.red(`Project "${projectName}" already exists.`));
35283
+ console.error(chalk3.red(`Project "${projectName}" already exists.`));
35084
35284
  process.exit(1);
35085
35285
  }
35086
- console.error(chalk2.red(e.message));
35286
+ console.error(chalk3.red(e.message));
35087
35287
  process.exit(1);
35088
35288
  }
35089
35289
  closeDb();
@@ -35095,12 +35295,12 @@ project.command("list").description("List all projects").option("--status <statu
35095
35295
  console.log(JSON.stringify(projects, null, 2));
35096
35296
  } else {
35097
35297
  if (projects.length === 0) {
35098
- console.log(chalk2.dim("No projects found."));
35298
+ console.log(chalk3.dim("No projects found."));
35099
35299
  } else {
35100
35300
  for (const p of projects) {
35101
- const desc = p.description ? chalk2.dim(` \u2014 ${p.description}`) : "";
35102
- const statusBadge = p.status === "archived" ? chalk2.yellow(" [archived]") : "";
35103
- console.log(`${chalk2.bold(p.name)}${desc}${statusBadge} ${p.space_count} spaces`);
35301
+ const desc = p.description ? chalk3.dim(` \u2014 ${p.description}`) : "";
35302
+ const statusBadge = p.status === "archived" ? chalk3.yellow(" [archived]") : "";
35303
+ console.log(`${chalk3.bold(p.name)}${desc}${statusBadge} ${p.space_count} spaces`);
35104
35304
  }
35105
35305
  }
35106
35306
  }
@@ -35111,13 +35311,13 @@ project.command("get").description("Get project details").argument("<id-or-name>
35111
35311
  if (!p)
35112
35312
  p = getProjectByName(idOrName);
35113
35313
  if (!p) {
35114
- console.error(chalk2.red(`Project "${idOrName}" not found.`));
35314
+ console.error(chalk3.red(`Project "${idOrName}" not found.`));
35115
35315
  process.exit(1);
35116
35316
  }
35117
35317
  if (opts.json) {
35118
35318
  console.log(JSON.stringify(p, null, 2));
35119
35319
  } else {
35120
- console.log(chalk2.bold(p.name));
35320
+ console.log(chalk3.bold(p.name));
35121
35321
  if (p.description)
35122
35322
  console.log(` Description: ${p.description}`);
35123
35323
  if (p.path)
@@ -35148,7 +35348,7 @@ project.command("update").description("Update a project").argument("<id>", "Proj
35148
35348
  try {
35149
35349
  updates.tags = JSON.parse(opts.tags);
35150
35350
  } catch {
35151
- console.error(chalk2.red("Invalid --tags JSON."));
35351
+ console.error(chalk3.red("Invalid --tags JSON."));
35152
35352
  process.exit(1);
35153
35353
  }
35154
35354
  }
@@ -35157,10 +35357,10 @@ project.command("update").description("Update a project").argument("<id>", "Proj
35157
35357
  if (opts.json) {
35158
35358
  console.log(JSON.stringify(p, null, 2));
35159
35359
  } else {
35160
- console.log(chalk2.green(`Project "${p.name}" updated.`));
35360
+ console.log(chalk3.green(`Project "${p.name}" updated.`));
35161
35361
  }
35162
35362
  } catch (e) {
35163
- console.error(chalk2.red(e.message));
35363
+ console.error(chalk3.red(e.message));
35164
35364
  process.exit(1);
35165
35365
  }
35166
35366
  closeDb();
@@ -35169,16 +35369,16 @@ project.command("delete").description("Delete a project").argument("<id>", "Proj
35169
35369
  try {
35170
35370
  const deleted = deleteProject(id);
35171
35371
  if (!deleted) {
35172
- console.error(chalk2.red(`Project "${id}" not found.`));
35372
+ console.error(chalk3.red(`Project "${id}" not found.`));
35173
35373
  process.exit(1);
35174
35374
  }
35175
35375
  if (opts.json) {
35176
35376
  console.log(JSON.stringify({ id, deleted: true }));
35177
35377
  } else {
35178
- console.log(chalk2.green(`Project deleted.`));
35378
+ console.log(chalk3.green(`Project deleted.`));
35179
35379
  }
35180
35380
  } catch (e) {
35181
- console.error(chalk2.red(e.message));
35381
+ console.error(chalk3.red(e.message));
35182
35382
  process.exit(1);
35183
35383
  }
35184
35384
  closeDb();
@@ -35186,7 +35386,7 @@ project.command("delete").description("Delete a project").argument("<id>", "Proj
35186
35386
  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
35387
  const agent = resolveIdentity(opts.from).trim();
35188
35388
  if (!agent) {
35189
- console.error(chalk2.red("Agent identity is required."));
35389
+ console.error(chalk3.red("Agent identity is required."));
35190
35390
  process.exit(1);
35191
35391
  }
35192
35392
  const result = deleteMessage(id, agent);
@@ -35194,9 +35394,9 @@ program2.command("delete").description("Delete a message (only sender can delete
35194
35394
  console.log(JSON.stringify({ id, deleted: result }));
35195
35395
  } else {
35196
35396
  if (result) {
35197
- console.log(chalk2.green(`Message #${id} deleted.`));
35397
+ console.log(chalk3.green(`Message #${id} deleted.`));
35198
35398
  } else {
35199
- console.error(chalk2.red(`Message #${id} not found or not your message.`));
35399
+ console.error(chalk3.red(`Message #${id} not found or not your message.`));
35200
35400
  process.exit(1);
35201
35401
  }
35202
35402
  }
@@ -35206,11 +35406,11 @@ program2.command("edit").description("Edit a message (only sender can edit)").ar
35206
35406
  const agent = resolveIdentity(opts.from).trim();
35207
35407
  const content = typeof newContent === "string" ? newContent : "";
35208
35408
  if (!agent) {
35209
- console.error(chalk2.red("Agent identity is required."));
35409
+ console.error(chalk3.red("Agent identity is required."));
35210
35410
  process.exit(1);
35211
35411
  }
35212
35412
  if (!content.trim()) {
35213
- console.error(chalk2.red("New content cannot be empty."));
35413
+ console.error(chalk3.red("New content cannot be empty."));
35214
35414
  process.exit(1);
35215
35415
  }
35216
35416
  const msg = editMessage(id, agent, content);
@@ -35218,9 +35418,9 @@ program2.command("edit").description("Edit a message (only sender can edit)").ar
35218
35418
  console.log(JSON.stringify(msg, null, 2));
35219
35419
  } else {
35220
35420
  if (msg) {
35221
- console.log(chalk2.green(`Message #${id} edited.`));
35421
+ console.log(chalk3.green(`Message #${id} edited.`));
35222
35422
  } else {
35223
- console.error(chalk2.red(`Message #${id} not found or not your message.`));
35423
+ console.error(chalk3.red(`Message #${id} not found or not your message.`));
35224
35424
  process.exit(1);
35225
35425
  }
35226
35426
  }
@@ -35232,9 +35432,9 @@ program2.command("pin").description("Pin a message").argument("<id>", "Message I
35232
35432
  console.log(JSON.stringify(msg, null, 2));
35233
35433
  } else {
35234
35434
  if (msg) {
35235
- console.log(chalk2.green(`Message #${id} pinned.`));
35435
+ console.log(chalk3.green(`Message #${id} pinned.`));
35236
35436
  } else {
35237
- console.error(chalk2.red(`Message #${id} not found.`));
35437
+ console.error(chalk3.red(`Message #${id} not found.`));
35238
35438
  process.exit(1);
35239
35439
  }
35240
35440
  }
@@ -35246,9 +35446,9 @@ program2.command("unpin").description("Unpin a message").argument("<id>", "Messa
35246
35446
  console.log(JSON.stringify(msg, null, 2));
35247
35447
  } else {
35248
35448
  if (msg) {
35249
- console.log(chalk2.green(`Message #${id} unpinned.`));
35449
+ console.log(chalk3.green(`Message #${id} unpinned.`));
35250
35450
  } else {
35251
- console.error(chalk2.red(`Message #${id} not found.`));
35451
+ console.error(chalk3.red(`Message #${id} not found.`));
35252
35452
  process.exit(1);
35253
35453
  }
35254
35454
  }
@@ -35263,13 +35463,13 @@ agents.command("list").description("List all agents with their presence status")
35263
35463
  console.log(JSON.stringify(agentsList, null, 2));
35264
35464
  } else {
35265
35465
  if (agentsList.length === 0) {
35266
- console.log(chalk2.dim("No agents found."));
35466
+ console.log(chalk3.dim("No agents found."));
35267
35467
  } else {
35268
35468
  for (const a of agentsList) {
35269
- const status = a.online ? chalk2.green("online") : chalk2.dim("offline");
35270
- const lastSeen = chalk2.dim(a.last_seen_at.slice(0, 19));
35271
- const agentName = a.agent === agent ? chalk2.cyan(`${a.agent} (you)`) : chalk2.cyan(a.agent);
35272
- console.log(` ${agentName} ${status} ${chalk2.dim(a.status)} ${lastSeen}`);
35469
+ const status = a.online ? chalk3.green("online") : chalk3.dim("offline");
35470
+ const lastSeen = chalk3.dim(a.last_seen_at.slice(0, 19));
35471
+ const agentName = a.agent === agent ? chalk3.cyan(`${a.agent} (you)`) : chalk3.cyan(a.agent);
35472
+ console.log(` ${agentName} ${status} ${chalk3.dim(a.status)} ${lastSeen}`);
35273
35473
  }
35274
35474
  }
35275
35475
  }
@@ -35278,7 +35478,7 @@ agents.command("list").description("List all agents with their presence status")
35278
35478
  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
35479
  const agentName = typeof name === "string" ? name.trim() : "";
35280
35480
  if (!agentName) {
35281
- console.error(chalk2.red("Agent name cannot be empty."));
35481
+ console.error(chalk3.red("Agent name cannot be empty."));
35282
35482
  process.exit(1);
35283
35483
  }
35284
35484
  const removed = removePresence(agentName);
@@ -35286,9 +35486,9 @@ agents.command("remove").description("Remove an agent from the presence list").a
35286
35486
  console.log(JSON.stringify({ agent: agentName, removed }));
35287
35487
  } else {
35288
35488
  if (removed) {
35289
- console.log(chalk2.green(`Agent "${agentName}" removed.`));
35489
+ console.log(chalk3.green(`Agent "${agentName}" removed.`));
35290
35490
  } else {
35291
- console.error(chalk2.red(`Agent "${agentName}" not found.`));
35491
+ console.error(chalk3.red(`Agent "${agentName}" not found.`));
35292
35492
  process.exit(1);
35293
35493
  }
35294
35494
  }
@@ -35298,22 +35498,22 @@ agents.command("rename").description("Rename an agent in the presence list").arg
35298
35498
  const old = typeof oldName === "string" ? oldName.trim() : "";
35299
35499
  const renamed = typeof newName === "string" ? newName.trim() : "";
35300
35500
  if (!old || !renamed) {
35301
- console.error(chalk2.red("Both old and new names are required."));
35501
+ console.error(chalk3.red("Both old and new names are required."));
35302
35502
  process.exit(1);
35303
35503
  }
35304
35504
  try {
35305
35505
  const ok = renameAgent(old, renamed);
35306
35506
  if (!ok) {
35307
- console.error(chalk2.red(`Agent "${old}" not found.`));
35507
+ console.error(chalk3.red(`Agent "${old}" not found.`));
35308
35508
  process.exit(1);
35309
35509
  }
35310
35510
  if (opts.json) {
35311
35511
  console.log(JSON.stringify({ old_name: old, new_name: renamed, renamed: true }));
35312
35512
  } else {
35313
- console.log(chalk2.green(`Agent "${old}" renamed to "${renamed}".`));
35513
+ console.log(chalk3.green(`Agent "${old}" renamed to "${renamed}".`));
35314
35514
  }
35315
35515
  } catch (e) {
35316
- console.error(chalk2.red(e.message));
35516
+ console.error(chalk3.red(e.message));
35317
35517
  process.exit(1);
35318
35518
  }
35319
35519
  closeDb();
@@ -35327,9 +35527,9 @@ program2.command("whoami").description("Show current agent identity and online s
35327
35527
  } else if (envValue) {
35328
35528
  source = "env var (CONVERSATIONS_AGENT_ID)";
35329
35529
  } else {
35330
- const { join: join5 } = __require("path");
35331
- const { homedir: homedir4 } = __require("os");
35332
- const agentIdFile = join5(homedir4(), ".conversations", "agent-id");
35530
+ const { join: join6 } = __require("path");
35531
+ const { homedir: homedir5 } = __require("os");
35532
+ const agentIdFile = join6(homedir5(), ".conversations", "agent-id");
35333
35533
  source = `auto-generated (${agentIdFile})`;
35334
35534
  }
35335
35535
  const presence = getPresence(agent);
@@ -35339,15 +35539,15 @@ program2.command("whoami").description("Show current agent identity and online s
35339
35539
  const agoMs = Date.now() - lastSeenMs;
35340
35540
  const agoSec = Math.floor(agoMs / 1000);
35341
35541
  const agoStr = agoSec < 60 ? `${agoSec}s ago` : `${Math.floor(agoSec / 60)}m ago`;
35342
- onlineStatus = chalk2.green(`yes`) + chalk2.dim(` (last seen ${agoStr})`);
35542
+ onlineStatus = chalk3.green(`yes`) + chalk3.dim(` (last seen ${agoStr})`);
35343
35543
  } else if (presence) {
35344
- onlineStatus = chalk2.red("no") + chalk2.dim(` (last seen ${presence.last_seen_at})`);
35544
+ onlineStatus = chalk3.red("no") + chalk3.dim(` (last seen ${presence.last_seen_at})`);
35345
35545
  } else {
35346
- onlineStatus = chalk2.red("no") + chalk2.dim(" (no presence record)");
35546
+ onlineStatus = chalk3.red("no") + chalk3.dim(" (no presence record)");
35347
35547
  }
35348
- console.log(` ${chalk2.bold("Agent:")} ${chalk2.cyan(agent)}`);
35349
- console.log(` ${chalk2.bold("Source:")} ${source}`);
35350
- console.log(` ${chalk2.bold("Online:")} ${onlineStatus}`);
35548
+ console.log(` ${chalk3.bold("Agent:")} ${chalk3.cyan(agent)}`);
35549
+ console.log(` ${chalk3.bold("Source:")} ${source}`);
35550
+ console.log(` ${chalk3.bold("Online:")} ${onlineStatus}`);
35351
35551
  closeDb();
35352
35552
  });
35353
35553
  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 +35557,16 @@ program2.command("blockers").description("Check for unread blocking messages").o
35357
35557
  console.log(JSON.stringify(blockers, null, 2));
35358
35558
  } else {
35359
35559
  if (blockers.length === 0) {
35360
- console.log(chalk2.dim("No blocking messages."));
35560
+ console.log(chalk3.dim("No blocking messages."));
35361
35561
  } else {
35362
- console.log(chalk2.red.bold(`${blockers.length} blocking message(s):
35562
+ console.log(chalk3.red.bold(`${blockers.length} blocking message(s):
35363
35563
  `));
35364
35564
  for (const b of blockers) {
35365
- const where = b.space ? chalk2.magenta(`#${b.space}`) : chalk2.yellow("DM");
35366
- const time3 = chalk2.dim(b.created_at.slice(11, 19));
35367
- console.log(` ${chalk2.red(`[#${b.id}]`)} ${time3} ${chalk2.cyan(b.from_agent)} ${where}: ${b.content}`);
35565
+ const where = b.space ? chalk3.magenta(`#${b.space}`) : chalk3.yellow("DM");
35566
+ const time3 = chalk3.dim(b.created_at.slice(11, 19));
35567
+ console.log(` ${chalk3.red(`[#${b.id}]`)} ${time3} ${chalk3.cyan(b.from_agent)} ${where}: ${b.content}`);
35368
35568
  }
35369
- console.log(chalk2.dim(`
35569
+ console.log(chalk3.dim(`
35370
35570
  Acknowledge with: conversations mark-read ${blockers.map((b) => b.id).join(" ")}`));
35371
35571
  }
35372
35572
  }
@@ -35385,49 +35585,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
35385
35585
  }
35386
35586
  const modeLabel = opts.all ? `DMs + ${agentSpaces.length} space(s)` : opts.space ? `Space: #${opts.space}` : "All DMs";
35387
35587
  console.log("");
35388
- console.log(chalk2.bold(` Conversations`) + chalk2.dim(` \u2014 watching as ${chalk2.cyan(agent)}`));
35389
- console.log(chalk2.dim(` ${modeLabel} \xB7 Poll: ${interval}ms \xB7 Ctrl+C to stop`));
35390
- console.log(chalk2.dim(" " + "\u2500".repeat(cols - 4)));
35588
+ console.log(chalk3.bold(` Conversations`) + chalk3.dim(` \u2014 watching as ${chalk3.cyan(agent)}`));
35589
+ console.log(chalk3.dim(` ${modeLabel} \xB7 Poll: ${interval}ms \xB7 Ctrl+C to stop`));
35590
+ console.log(chalk3.dim(" " + "\u2500".repeat(cols - 4)));
35391
35591
  console.log("");
35392
35592
  const { startPolling: startPolling2 } = (init_poll(), __toCommonJS(exports_poll));
35393
- const renderContent = (content) => {
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
- };
35593
+ const { renderContent: renderContent2 } = (init_terminal_markdown(), __toCommonJS(exports_terminal_markdown));
35431
35594
  const desktopNotify = (title, body) => {
35432
35595
  if (process.platform === "darwin") {
35433
35596
  try {
@@ -35439,18 +35602,18 @@ program2.command("watch").description("Watch for new messages with desktop notif
35439
35602
  }
35440
35603
  };
35441
35604
  const renderMessage = (msg) => {
35442
- const time3 = chalk2.dim(msg.created_at.slice(11, 19));
35443
- const where = msg.space ? chalk2.magenta(`#${msg.space}`) : chalk2.yellow("DM");
35444
- const priority = msg.priority !== "normal" ? msg.priority === "urgent" ? chalk2.red.bold(` [${msg.priority}]`) : msg.priority === "high" ? chalk2.yellow(` [${msg.priority}]`) : chalk2.dim(` [${msg.priority}]`) : "";
35445
- const blocking = msg.blocking ? chalk2.red.bold(" \u26A0 BLOCKER") : "";
35446
- const sender = chalk2.cyan.bold(msg.from_agent);
35605
+ const time3 = chalk3.dim(msg.created_at.slice(11, 19));
35606
+ const where = msg.space ? chalk3.magenta(`#${msg.space}`) : chalk3.yellow("DM");
35607
+ const priority = msg.priority !== "normal" ? msg.priority === "urgent" ? chalk3.red.bold(` [${msg.priority}]`) : msg.priority === "high" ? chalk3.yellow(` [${msg.priority}]`) : chalk3.dim(` [${msg.priority}]`) : "";
35608
+ const blocking = msg.blocking ? chalk3.red.bold(" \u26A0 BLOCKER") : "";
35609
+ const sender = chalk3.cyan.bold(msg.from_agent);
35447
35610
  console.log(` ${sender} ${where} ${time3}${priority}${blocking}`);
35448
- const content = renderContent(msg.content);
35611
+ const content = renderContent2(msg.content);
35449
35612
  const indented = content.split(`
35450
35613
  `).map((l) => " " + l).join(`
35451
35614
  `);
35452
35615
  console.log(indented);
35453
- console.log(chalk2.dim(" " + "\xB7".repeat(Math.min(cols - 8, 60))));
35616
+ console.log(chalk3.dim(" " + "\xB7".repeat(Math.min(cols - 8, 60))));
35454
35617
  console.log("");
35455
35618
  };
35456
35619
  if (opts.all) {
@@ -35461,12 +35624,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
35461
35624
  }
35462
35625
  const recent = [...dmRecent, ...spaceRecent].sort((a, b) => a.created_at.localeCompare(b.created_at)).slice(-20);
35463
35626
  if (recent.length > 0) {
35464
- console.log(chalk2.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
35627
+ console.log(chalk3.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
35465
35628
  `));
35466
35629
  for (const msg of recent) {
35467
35630
  renderMessage(msg);
35468
35631
  }
35469
- console.log(chalk2.dim(` \u2500\u2500 Live \u2500\u2500
35632
+ console.log(chalk3.dim(` \u2500\u2500 Live \u2500\u2500
35470
35633
  `));
35471
35634
  }
35472
35635
  } else {
@@ -35477,12 +35640,12 @@ program2.command("watch").description("Watch for new messages with desktop notif
35477
35640
  order: "asc"
35478
35641
  });
35479
35642
  if (recent.length > 0) {
35480
- console.log(chalk2.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
35643
+ console.log(chalk3.dim(` \u2500\u2500 Recent messages (${recent.length}) \u2500\u2500
35481
35644
  `));
35482
35645
  for (const msg of recent) {
35483
35646
  renderMessage(msg);
35484
35647
  }
35485
- console.log(chalk2.dim(` \u2500\u2500 Live \u2500\u2500
35648
+ console.log(chalk3.dim(` \u2500\u2500 Live \u2500\u2500
35486
35649
  `));
35487
35650
  }
35488
35651
  }
@@ -35510,7 +35673,7 @@ program2.command("watch").description("Watch for new messages with desktop notif
35510
35673
  });
35511
35674
  }
35512
35675
  process.on("SIGINT", () => {
35513
- console.log(chalk2.dim(`
35676
+ console.log(chalk3.dim(`
35514
35677
  Stopped watching.`));
35515
35678
  closeDb();
35516
35679
  process.exit(0);
@@ -35531,8 +35694,8 @@ program2.command("dashboard").description("Start web dashboard").option("--port
35531
35694
  });
35532
35695
  program2.action(() => {
35533
35696
  if (!process.stdin.isTTY) {
35534
- console.error(chalk2.red("Interactive mode requires a TTY terminal."));
35535
- console.error(chalk2.dim("Use subcommands (send, read, sessions, etc.) for non-interactive use."));
35697
+ console.error(chalk3.red("Interactive mode requires a TTY terminal."));
35698
+ console.error(chalk3.dim("Use subcommands (send, read, sessions, etc.) for non-interactive use."));
35536
35699
  process.exit(1);
35537
35700
  }
35538
35701
  const agent = resolveIdentity();