@hasna/conversations 0.2.32 → 0.2.34

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
@@ -14928,7 +14928,7 @@ var init_presence = __esm(() => {
14928
14928
  var require_package = __commonJS((exports, module) => {
14929
14929
  module.exports = {
14930
14930
  name: "@hasna/conversations",
14931
- version: "0.2.32",
14931
+ version: "0.2.34",
14932
14932
  description: "Real-time CLI messaging for AI agents",
14933
14933
  type: "module",
14934
14934
  bin: {
@@ -15071,6 +15071,18 @@ function listProjects(opts) {
15071
15071
  params.push(opts.status);
15072
15072
  }
15073
15073
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
15074
+ let pagination = "";
15075
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
15076
+ pagination += " LIMIT ?";
15077
+ params.push(Math.floor(opts.limit));
15078
+ }
15079
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
15080
+ if (!pagination.includes("LIMIT")) {
15081
+ pagination += " LIMIT -1";
15082
+ }
15083
+ pagination += " OFFSET ?";
15084
+ params.push(Math.floor(opts.offset));
15085
+ }
15074
15086
  const rows = db2.prepare(`
15075
15087
  SELECT
15076
15088
  p.*,
@@ -15078,6 +15090,7 @@ function listProjects(opts) {
15078
15090
  FROM projects p
15079
15091
  ${where}
15080
15092
  ORDER BY p.name ASC
15093
+ ${pagination}
15081
15094
  `).all(...params);
15082
15095
  return rows.map((row) => ({
15083
15096
  ...parseProject(row),
@@ -15756,7 +15769,7 @@ async function tmuxSend(target, message, opts = {}) {
15756
15769
  }
15757
15770
  function registerTmuxCommands(program2) {
15758
15771
  const tmux = program2.command("tmux").description("Dispatch messages to tmux windows (Claude Code sessions)");
15759
- tmux.command("send").description("Send a message to a tmux window with paste+wait+Enter+verify").requiredOption("--target <target>", "Tmux target: session:window or session:window.pane").requiredOption("--message <text>", "Message text to send").option("--delay <ms>", "Wait time (ms) after paste before hitting Enter (default: adaptive 25-1500ms)", parseInt).option("--retries <n>", "Max retry attempts (default: 3)", parseInt).option("--no-verify", "Skip verification after sending").option("--json", "Output result as JSON").action(async (opts) => {
15772
+ tmux.command("send").description("Send a message to a tmux window with paste+wait+Enter+verify").requiredOption("--target <target>", "Tmux target: session:window or session:window.pane").requiredOption("--message <text>", "Message text to send").option("--delay <ms>", "Wait time (ms) after paste before hitting Enter (default: adaptive 25-1500ms)", parseInt).option("--retries <n>", "Max retry attempts (default: 3)", parseInt).option("--no-verify", "Skip verification after sending").option("-j, --json", "Output result as JSON").action(async (opts) => {
15760
15773
  const target = opts.target.trim();
15761
15774
  const message = opts.message;
15762
15775
  if (!target) {
@@ -15791,7 +15804,7 @@ function registerTmuxCommands(program2) {
15791
15804
  process.exit(1);
15792
15805
  }
15793
15806
  });
15794
- tmux.command("broadcast").description("Send the same message to multiple tmux windows").requiredOption("--targets <list>", "Comma-separated list of tmux targets").requiredOption("--message <text>", "Message text to send").option("--delay <ms>", "Wait time (ms) after paste before Enter (default: adaptive 25-1500ms)", parseInt).option("--stagger <ms>", "Delay (ms) between each target (default: 500)", parseInt).option("--retries <n>", "Max retry attempts per target (default: 3)", parseInt).option("--no-verify", "Skip verification after sending").option("--json", "Output results as JSON").action(async (opts) => {
15807
+ tmux.command("broadcast").description("Send the same message to multiple tmux windows").requiredOption("--targets <list>", "Comma-separated list of tmux targets").requiredOption("--message <text>", "Message text to send").option("--delay <ms>", "Wait time (ms) after paste before Enter (default: adaptive 25-1500ms)", parseInt).option("--stagger <ms>", "Delay (ms) between each target (default: 500)", parseInt).option("--retries <n>", "Max retry attempts per target (default: 3)", parseInt).option("--no-verify", "Skip verification after sending").option("-j, --json", "Output results as JSON").action(async (opts) => {
15795
15808
  const targets = opts.targets.split(",").map((t) => t.trim()).filter(Boolean);
15796
15809
  const message = opts.message;
15797
15810
  const stagger = Number.isFinite(opts.stagger) && opts.stagger >= 0 ? opts.stagger : 500;
@@ -48822,7 +48835,7 @@ init_presence();
48822
48835
  init_db();
48823
48836
  import chalk4 from "chalk";
48824
48837
  function registerMessagingCommands(program2) {
48825
- program2.command("send").description("Send a message to an agent").argument("<message>", "Message content").option("--to <agent>", "Recipient agent ID (required unless --space is used)").option("--from <agent>", "Sender agent ID").option("--session <id>", "Session ID (auto-generated if omitted)").option("--priority <level>", "Priority: low, normal, high, urgent", "normal").option("--working-dir <path>", "Working directory context").option("--repository <repo>", "Repository context").option("--branch <branch>", "Branch context").option("--metadata <json>", "JSON metadata string").option("--space <name>", "Send to a space instead of a specific agent").option("--blocking", "Send as a blocking message (recipient must acknowledge)").option("--json", "Output as JSON").action((message, opts) => {
48838
+ program2.command("send").description("Send a message to an agent").argument("<message>", "Message content").option("--to <agent>", "Recipient agent ID (required unless --space is used)").option("--from <agent>", "Sender agent ID").option("--session <id>", "Session ID (auto-generated if omitted)").option("--priority <level>", "Priority: low, normal, high, urgent", "normal").option("--working-dir <path>", "Working directory context").option("--repository <repo>", "Repository context").option("--branch <branch>", "Branch context").option("--metadata <json>", "JSON metadata string").option("--space <name>", "Send to a space instead of a specific agent").option("--blocking", "Send as a blocking message (recipient must acknowledge)").option("-j, --json", "Output as JSON").action((message, opts) => {
48826
48839
  const from = resolveIdentity(opts.from).trim();
48827
48840
  const to = typeof opts.to === "string" ? opts.to.trim() : "";
48828
48841
  const space = typeof opts.space === "string" ? opts.space.trim() : "";
@@ -48871,7 +48884,7 @@ function registerMessagingCommands(program2) {
48871
48884
  }
48872
48885
  closeDb();
48873
48886
  });
48874
- program2.command("read").description("Read messages").option("--session <id>", "Filter by session ID").option("--from <agent>", "Filter by sender").option("--to <agent>", "Filter by recipient").option("--space <name>", "Filter by space").option("--since <timestamp>", "Messages after this ISO timestamp").option("--limit <n>", "Max messages to return", parseInt).option("--unread", "Only unread messages").option("--mark-read", "Mark returned messages as read").option("--json", "Output as JSON").action((opts) => {
48887
+ program2.command("read").description("Read messages").option("--session <id>", "Filter by session ID").option("--from <agent>", "Filter by sender").option("--to <agent>", "Filter by recipient").option("--space <name>", "Filter by space").option("--since <timestamp>", "Messages after this ISO timestamp").option("--limit <n>", "Max messages to return", parseInt).option("--unread", "Only unread messages").option("--mark-read", "Mark returned messages as read").option("-j, --json", "Output as JSON").action((opts) => {
48875
48888
  const messages = readMessages({
48876
48889
  session_id: opts.session,
48877
48890
  from: opts.from,
@@ -48916,7 +48929,7 @@ function registerMessagingCommands(program2) {
48916
48929
  }
48917
48930
  closeDb();
48918
48931
  });
48919
- program2.command("digest").description("Show unread message digest (preview only, auto-marks read)").argument("[space]", "Space name to digest (omit for DMs)").option("--since <timestamp>", "Messages after this ISO timestamp").option("--limit <n>", "Max messages to show", parseInt).option("--to <agent>", "Filter by recipient (for DMs)").option("--json", "Output as JSON").action((spaceArg, opts) => {
48932
+ program2.command("digest").description("Show unread message digest (preview only, auto-marks read)").argument("[space]", "Space name to digest (omit for DMs)").option("--since <timestamp>", "Messages after this ISO timestamp").option("--limit <n>", "Max messages to show", parseInt).option("--to <agent>", "Filter by recipient (for DMs)").option("-j, --json", "Output as JSON").action((spaceArg, opts) => {
48920
48933
  const result = readDigest({
48921
48934
  space: spaceArg || undefined,
48922
48935
  since: opts.since,
@@ -48943,7 +48956,7 @@ function registerMessagingCommands(program2) {
48943
48956
  }
48944
48957
  closeDb();
48945
48958
  });
48946
- 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) => {
48959
+ 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("-j, --json", "Output as JSON").action((query, opts) => {
48947
48960
  const q = typeof query === "string" ? query.trim() : "";
48948
48961
  if (!q) {
48949
48962
  console.error(chalk4.red("Search query cannot be empty."));
@@ -48976,7 +48989,7 @@ function registerMessagingCommands(program2) {
48976
48989
  }
48977
48990
  closeDb();
48978
48991
  });
48979
- program2.command("since").description("Show all activity (DMs + spaces) since a duration ago").argument("<duration>", "Duration: e.g. 30m, 2h, 1d").option("--json", "Output as JSON").action((duration, opts) => {
48992
+ program2.command("since").description("Show all activity (DMs + spaces) since a duration ago").argument("<duration>", "Duration: e.g. 30m, 2h, 1d").option("-j, --json", "Output as JSON").action((duration, opts) => {
48980
48993
  const match = duration.match(/^(\d+)([mhd])$/);
48981
48994
  if (!match) {
48982
48995
  console.error(chalk4.red(`Invalid duration "${duration}". Use format: 30m, 2h, 1d`));
@@ -49010,7 +49023,7 @@ function registerMessagingCommands(program2) {
49010
49023
  }
49011
49024
  closeDb();
49012
49025
  });
49013
- 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) => {
49026
+ 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("-j, --json", "Output as JSON").action((message, opts) => {
49014
49027
  const original = getMessageById(opts.to);
49015
49028
  if (!original) {
49016
49029
  console.error(chalk4.red(`Message #${opts.to} not found.`));
@@ -49043,7 +49056,7 @@ function registerMessagingCommands(program2) {
49043
49056
  }
49044
49057
  closeDb();
49045
49058
  });
49046
- program2.command("mark-read").description("Mark messages as read").argument("[ids...]", "Message IDs to mark as read").option("--all", "Mark all messages as read").option("--session <id>", "Mark all messages in session as read").option("--space <name>", "Mark all messages in space as read").option("--agent <id>", "Agent marking messages as read").option("--json", "Output as JSON").action((ids, opts) => {
49059
+ program2.command("mark-read").description("Mark messages as read").argument("[ids...]", "Message IDs to mark as read").option("--all", "Mark all messages as read").option("--session <id>", "Mark all messages in session as read").option("--space <name>", "Mark all messages in space as read").option("--agent <id>", "Agent marking messages as read").option("-j, --json", "Output as JSON").action((ids, opts) => {
49047
49060
  const agent = resolveIdentity(opts.agent);
49048
49061
  let count = 0;
49049
49062
  if (opts.all) {
@@ -49078,7 +49091,7 @@ function registerMessagingCommands(program2) {
49078
49091
  console.log(result);
49079
49092
  closeDb();
49080
49093
  });
49081
- program2.command("edit").description("Edit a message (only sender can edit)").argument("<id>", "Message ID", parseInt).argument("<new-content>", "New message content").option("--from <agent>", "Sender agent ID").option("--json", "Output as JSON").action((id, newContent, opts) => {
49094
+ program2.command("edit").description("Edit a message (only sender can edit)").argument("<id>", "Message ID", parseInt).argument("<new-content>", "New message content").option("--from <agent>", "Sender agent ID").option("-j, --json", "Output as JSON").action((id, newContent, opts) => {
49082
49095
  const agent = resolveIdentity(opts.from).trim();
49083
49096
  const content = typeof newContent === "string" ? newContent : "";
49084
49097
  if (!agent) {
@@ -49102,7 +49115,7 @@ function registerMessagingCommands(program2) {
49102
49115
  }
49103
49116
  closeDb();
49104
49117
  });
49105
- 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) => {
49118
+ program2.command("delete").description("Delete a message (only sender can delete)").argument("<id>", "Message ID", parseInt).option("--from <agent>", "Sender agent ID").option("-j, --json", "Output as JSON").action((id, opts) => {
49106
49119
  const agent = resolveIdentity(opts.from).trim();
49107
49120
  if (!agent) {
49108
49121
  console.error(chalk4.red("Agent identity is required."));
@@ -49121,7 +49134,7 @@ function registerMessagingCommands(program2) {
49121
49134
  }
49122
49135
  closeDb();
49123
49136
  });
49124
- program2.command("pin").description("Pin a message").argument("<id>", "Message ID", parseInt).option("--json", "Output as JSON").action((id, opts) => {
49137
+ program2.command("pin").description("Pin a message").argument("<id>", "Message ID", parseInt).option("-j, --json", "Output as JSON").action((id, opts) => {
49125
49138
  const msg = pinMessage(id);
49126
49139
  if (opts.json) {
49127
49140
  console.log(JSON.stringify(msg, null, 2));
@@ -49135,7 +49148,7 @@ function registerMessagingCommands(program2) {
49135
49148
  }
49136
49149
  closeDb();
49137
49150
  });
49138
- program2.command("unpin").description("Unpin a message").argument("<id>", "Message ID", parseInt).option("--json", "Output as JSON").action((id, opts) => {
49151
+ program2.command("unpin").description("Unpin a message").argument("<id>", "Message ID", parseInt).option("-j, --json", "Output as JSON").action((id, opts) => {
49139
49152
  const msg = unpinMessage(id);
49140
49153
  if (opts.json) {
49141
49154
  console.log(JSON.stringify(msg, null, 2));
@@ -49149,7 +49162,7 @@ function registerMessagingCommands(program2) {
49149
49162
  }
49150
49163
  closeDb();
49151
49164
  });
49152
- program2.command("pinned").description("List pinned messages").option("--space <name>", "Filter by space").option("--session <id>", "Filter by session ID").option("--limit <n>", "Max results", parseInt).option("--json", "Output as JSON").action((opts) => {
49165
+ program2.command("pinned").description("List pinned messages").option("--space <name>", "Filter by space").option("--session <id>", "Filter by session ID").option("--limit <n>", "Max results", parseInt).option("-j, --json", "Output as JSON").action((opts) => {
49153
49166
  const messages = getPinnedMessages({ space: opts.space, session_id: opts.session, limit: opts.limit });
49154
49167
  if (opts.json) {
49155
49168
  console.log(JSON.stringify(messages, null, 2));
@@ -49169,7 +49182,7 @@ function registerMessagingCommands(program2) {
49169
49182
  }
49170
49183
  closeDb();
49171
49184
  });
49172
- program2.command("blockers").description("Check for unread blocking messages").option("--from <agent>", "Agent to check blockers for").option("--json", "Output as JSON").action((opts) => {
49185
+ program2.command("blockers").description("Check for unread blocking messages").option("--from <agent>", "Agent to check blockers for").option("-j, --json", "Output as JSON").action((opts) => {
49173
49186
  const agent = resolveIdentity(opts.from);
49174
49187
  const blockers = getUnreadBlockers(agent);
49175
49188
  if (opts.json) {
@@ -49298,7 +49311,7 @@ Acknowledge with: conversations mark-read ${blockers.map((b) => b.id).join(" ")}
49298
49311
  process.exit(0);
49299
49312
  });
49300
49313
  });
49301
- program2.command("update").description("Check for and install updates").option("--check", "Only check for updates, don't install").option("--json", "Output as JSON").action(async (opts) => {
49314
+ program2.command("update").description("Check for and install updates").option("--check", "Only check for updates, don't install").option("-j, --json", "Output as JSON").action(async (opts) => {
49302
49315
  const pkg = await Promise.resolve().then(() => __toESM(require_package(), 1));
49303
49316
  const current = pkg.version;
49304
49317
  let latest;
@@ -49363,7 +49376,7 @@ init_terminal_markdown();
49363
49376
  import chalk5 from "chalk";
49364
49377
  function registerSpaceCommands(program2) {
49365
49378
  const space = program2.command("space").description("Manage spaces");
49366
- space.command("create").description("Create a new space").argument("<name>", "Space name").option("--description <text>", "Space description").option("--parent <name>", "Parent space name (for nesting)").option("--project <id>", "Project ID to associate with").option("--from <agent>", "Creator agent ID").option("--json", "Output as JSON").action((name, opts) => {
49379
+ space.command("create").description("Create a new space").argument("<name>", "Space name").option("--description <text>", "Space description").option("--parent <name>", "Parent space name (for nesting)").option("--project <id>", "Project ID to associate with").option("--from <agent>", "Creator agent ID").option("-j, --json", "Output as JSON").action((name, opts) => {
49367
49380
  const agent = resolveIdentity(opts.from).trim();
49368
49381
  const spaceName = typeof name === "string" ? name.trim() : "";
49369
49382
  if (!agent) {
@@ -49396,7 +49409,7 @@ function registerSpaceCommands(program2) {
49396
49409
  }
49397
49410
  closeDb();
49398
49411
  });
49399
- space.command("list").description("List all spaces").option("--project <id>", "Filter by project ID").option("--parent <name>", "Filter by parent space name").option("--top-level", "Show only top-level spaces").option("--archived", "Include archived spaces").option("--json", "Output as JSON").action((opts) => {
49412
+ space.command("list").description("List all spaces").option("--project <id>", "Filter by project ID").option("--parent <name>", "Filter by parent space name").option("--top-level", "Show only top-level spaces").option("--archived", "Include archived spaces").option("-j, --json", "Output as JSON").action((opts) => {
49400
49413
  const listOpts = {};
49401
49414
  if (opts.project)
49402
49415
  listOpts.project_id = opts.project;
@@ -49424,7 +49437,7 @@ function registerSpaceCommands(program2) {
49424
49437
  }
49425
49438
  closeDb();
49426
49439
  });
49427
- 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) => {
49440
+ 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("-j, --json", "Output as JSON").action((name, opts) => {
49428
49441
  const spaceName = typeof name === "string" ? name.trim() : "";
49429
49442
  if (!spaceName) {
49430
49443
  console.error(chalk5.red("Space name cannot be empty."));
@@ -49450,7 +49463,7 @@ function registerSpaceCommands(program2) {
49450
49463
  }
49451
49464
  closeDb();
49452
49465
  });
49453
- space.command("archive").description("Archive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
49466
+ space.command("archive").description("Archive a space").argument("<name>", "Space name").option("-j, --json", "Output as JSON").action((name, opts) => {
49454
49467
  const spaceName = typeof name === "string" ? name.trim() : "";
49455
49468
  if (!spaceName) {
49456
49469
  console.error(chalk5.red("Space name cannot be empty."));
@@ -49469,7 +49482,7 @@ function registerSpaceCommands(program2) {
49469
49482
  }
49470
49483
  closeDb();
49471
49484
  });
49472
- space.command("unarchive").description("Unarchive a space").argument("<name>", "Space name").option("--json", "Output as JSON").action((name, opts) => {
49485
+ space.command("unarchive").description("Unarchive a space").argument("<name>", "Space name").option("-j, --json", "Output as JSON").action((name, opts) => {
49473
49486
  const spaceName = typeof name === "string" ? name.trim() : "";
49474
49487
  if (!spaceName) {
49475
49488
  console.error(chalk5.red("Space name cannot be empty."));
@@ -49488,7 +49501,7 @@ function registerSpaceCommands(program2) {
49488
49501
  }
49489
49502
  closeDb();
49490
49503
  });
49491
- space.command("send").description("Send a message to a space").argument("<space>", "Space name").argument("<message>", "Message content").option("--from <agent>", "Sender agent ID").option("--priority <level>", "Priority: low, normal, high, urgent", "normal").option("--json", "Output as JSON").action((spaceName, message, opts) => {
49504
+ space.command("send").description("Send a message to a space").argument("<space>", "Space name").argument("<message>", "Message content").option("--from <agent>", "Sender agent ID").option("--priority <level>", "Priority: low, normal, high, urgent", "normal").option("-j, --json", "Output as JSON").action((spaceName, message, opts) => {
49492
49505
  const from = resolveIdentity(opts.from).trim();
49493
49506
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
49494
49507
  const content = typeof message === "string" ? message : "";
@@ -49524,7 +49537,7 @@ function registerSpaceCommands(program2) {
49524
49537
  }
49525
49538
  closeDb();
49526
49539
  });
49527
- 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) => {
49540
+ 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("-j, --json", "Output as JSON").action((spaceName, opts) => {
49528
49541
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
49529
49542
  if (!spaceArg) {
49530
49543
  console.error(chalk5.red("Space name cannot be empty."));
@@ -49556,7 +49569,7 @@ function registerSpaceCommands(program2) {
49556
49569
  }
49557
49570
  closeDb();
49558
49571
  });
49559
- space.command("join").description("Join a space").argument("<space>", "Space name").option("--from <agent>", "Agent ID").option("--json", "Output as JSON").action((spaceName, opts) => {
49572
+ space.command("join").description("Join a space").argument("<space>", "Space name").option("--from <agent>", "Agent ID").option("-j, --json", "Output as JSON").action((spaceName, opts) => {
49560
49573
  const agent = resolveIdentity(opts.from).trim();
49561
49574
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
49562
49575
  if (!agent) {
@@ -49579,7 +49592,7 @@ function registerSpaceCommands(program2) {
49579
49592
  }
49580
49593
  closeDb();
49581
49594
  });
49582
- space.command("leave").description("Leave a space").argument("<space>", "Space name").option("--from <agent>", "Agent ID").option("--json", "Output as JSON").action((spaceName, opts) => {
49595
+ space.command("leave").description("Leave a space").argument("<space>", "Space name").option("--from <agent>", "Agent ID").option("-j, --json", "Output as JSON").action((spaceName, opts) => {
49583
49596
  const agent = resolveIdentity(opts.from).trim();
49584
49597
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
49585
49598
  if (!agent) {
@@ -49602,7 +49615,7 @@ function registerSpaceCommands(program2) {
49602
49615
  }
49603
49616
  closeDb();
49604
49617
  });
49605
- space.command("members").description("List space members").argument("<space>", "Space name").option("--json", "Output as JSON").action((spaceName, opts) => {
49618
+ space.command("members").description("List space members").argument("<space>", "Space name").option("-j, --json", "Output as JSON").action((spaceName, opts) => {
49606
49619
  const spaceArg = typeof spaceName === "string" ? spaceName.trim() : "";
49607
49620
  if (!spaceArg) {
49608
49621
  console.error(chalk5.red("Space name cannot be empty."));
@@ -49630,9 +49643,25 @@ init_projects();
49630
49643
  init_db();
49631
49644
  init_identity();
49632
49645
  import chalk6 from "chalk";
49646
+ function requireDeleteConfirmation(confirmed) {
49647
+ if (!confirmed) {
49648
+ throw new Error("Project deletion requires --yes confirmation");
49649
+ }
49650
+ }
49651
+ function parseProjectListPagination(limitInput, offsetInput) {
49652
+ if (limitInput !== undefined && (!Number.isFinite(limitInput) || Number(limitInput) <= 0)) {
49653
+ throw new Error("--limit must be a positive integer.");
49654
+ }
49655
+ if (offsetInput !== undefined && (!Number.isFinite(offsetInput) || Number(offsetInput) < 0)) {
49656
+ throw new Error("--offset must be a non-negative integer.");
49657
+ }
49658
+ const limit = Number.isFinite(limitInput) ? Math.floor(Number(limitInput)) : undefined;
49659
+ const offset = Number.isFinite(offsetInput) ? Math.floor(Number(offsetInput)) : undefined;
49660
+ return { limit, offset };
49661
+ }
49633
49662
  function registerProjectCommands(program2) {
49634
49663
  const project = program2.command("project").description("Manage projects");
49635
- project.command("create").description("Create a new project").argument("<name>", "Project name").option("--description <text>", "Project description").option("--path <path>", "Project path on disk").option("--repository <url>", "Repository URL").option("--tags <json>", "JSON array of tags").option("--from <agent>", "Creator agent ID").option("--json", "Output as JSON").action((name, opts) => {
49664
+ project.command("create").description("Create a new project").argument("<name>", "Project name").option("--description <text>", "Project description").option("--path <path>", "Project path on disk").option("--repository <url>", "Repository URL").option("--tags <json>", "JSON array of tags").option("--from <agent>", "Creator agent ID").option("-j, --json", "Output as JSON").action((name, opts) => {
49636
49665
  const agent = resolveIdentity(opts.from).trim();
49637
49666
  const projectName = typeof name === "string" ? name.trim() : "";
49638
49667
  if (!agent) {
@@ -49676,9 +49705,21 @@ function registerProjectCommands(program2) {
49676
49705
  }
49677
49706
  closeDb();
49678
49707
  });
49679
- project.command("list").description("List all projects").option("--status <status>", "Filter by status (active/archived)").option("--json", "Output as JSON").action((opts) => {
49708
+ project.command("list").description("List all projects").option("--status <status>", "Filter by status (active/archived)").option("--limit <n>", "Limit results", parseInt).option("--offset <n>", "Skip first N results", parseInt).option("-j, --json", "Output as JSON").action((opts) => {
49680
49709
  const status = opts.status === "active" || opts.status === "archived" ? opts.status : undefined;
49681
- const projects = listProjects(status ? { status } : undefined);
49710
+ let limit;
49711
+ let offset;
49712
+ try {
49713
+ ({ limit, offset } = parseProjectListPagination(opts.limit, opts.offset));
49714
+ } catch (e) {
49715
+ console.error(chalk6.red(e.message));
49716
+ process.exit(1);
49717
+ }
49718
+ const projects = listProjects({
49719
+ ...status ? { status } : {},
49720
+ ...limit !== undefined ? { limit } : {},
49721
+ ...offset !== undefined ? { offset } : {}
49722
+ });
49682
49723
  if (opts.json) {
49683
49724
  console.log(JSON.stringify(projects, null, 2));
49684
49725
  } else {
@@ -49694,7 +49735,7 @@ function registerProjectCommands(program2) {
49694
49735
  }
49695
49736
  closeDb();
49696
49737
  });
49697
- project.command("get").description("Get project details").argument("<id-or-name>", "Project ID or name").option("--json", "Output as JSON").action((idOrName, opts) => {
49738
+ project.command("get").description("Get project details").argument("<id-or-name>", "Project ID or name").option("-j, --json", "Output as JSON").action((idOrName, opts) => {
49698
49739
  let p = getProject(idOrName);
49699
49740
  if (!p)
49700
49741
  p = getProjectByName(idOrName);
@@ -49720,7 +49761,7 @@ function registerProjectCommands(program2) {
49720
49761
  }
49721
49762
  closeDb();
49722
49763
  });
49723
- project.command("update").description("Update a project").argument("<id-or-name>", "Project ID or name").option("--name <name>", "New name").option("--description <text>", "New description").option("--path <path>", "New path").option("--status <status>", "New status (active/archived)").option("--repository <url>", "New repository URL").option("--tags <json>", "New tags (JSON array)").option("--json", "Output as JSON").action((id, opts) => {
49764
+ project.command("update").description("Update a project").argument("<id-or-name>", "Project ID or name").option("--name <name>", "New name").option("--description <text>", "New description").option("--path <path>", "New path").option("--status <status>", "New status (active/archived)").option("--repository <url>", "New repository URL").option("--tags <json>", "New tags (JSON array)").option("-j, --json", "Output as JSON").action((id, opts) => {
49724
49765
  const updates = {};
49725
49766
  if (opts.name)
49726
49767
  updates.name = opts.name;
@@ -49755,8 +49796,9 @@ function registerProjectCommands(program2) {
49755
49796
  }
49756
49797
  closeDb();
49757
49798
  });
49758
- project.command("delete").description("Delete a project").argument("<id-or-name>", "Project ID or name").option("--json", "Output as JSON").action((id, opts) => {
49799
+ project.command("delete").description("Delete a project").argument("<id-or-name>", "Project ID or name").option("--yes", "Confirm project deletion").option("-j, --json", "Output as JSON").action((id, opts) => {
49759
49800
  try {
49801
+ requireDeleteConfirmation(opts.yes);
49760
49802
  const isUuid = /^[0-9a-f-]{36}$/i.test(id);
49761
49803
  const resolvedId = isUuid ? id : getProjectByName(id)?.id ?? id;
49762
49804
  const deleted = deleteProject(resolvedId);
@@ -49770,7 +49812,11 @@ function registerProjectCommands(program2) {
49770
49812
  console.log(chalk6.green(`Project deleted.`));
49771
49813
  }
49772
49814
  } catch (e) {
49773
- console.error(chalk6.red(e.message));
49815
+ if (opts.json) {
49816
+ console.log(JSON.stringify({ id, deleted: false, error: e.message }));
49817
+ } else {
49818
+ console.error(chalk6.red(e.message));
49819
+ }
49774
49820
  process.exit(1);
49775
49821
  }
49776
49822
  closeDb();
@@ -49783,9 +49829,29 @@ init_identity();
49783
49829
  init_presence();
49784
49830
  init_projects();
49785
49831
  import chalk7 from "chalk";
49832
+ function buildWhoamiPayload(agent, source, presence, nowMs = Date.now()) {
49833
+ if (!presence) {
49834
+ return {
49835
+ agent,
49836
+ source,
49837
+ online: false,
49838
+ last_seen_at: null,
49839
+ last_seen_ago_seconds: null
49840
+ };
49841
+ }
49842
+ const lastSeenMs = new Date(`${presence.last_seen_at}Z`).getTime();
49843
+ const deltaSeconds = Number.isFinite(lastSeenMs) ? Math.max(0, Math.floor((nowMs - lastSeenMs) / 1000)) : null;
49844
+ return {
49845
+ agent,
49846
+ source,
49847
+ online: presence.online,
49848
+ last_seen_at: presence.last_seen_at,
49849
+ last_seen_ago_seconds: deltaSeconds
49850
+ };
49851
+ }
49786
49852
  function registerAgentCommands(program2) {
49787
49853
  const agents = program2.command("agents").description("Manage agents");
49788
- agents.command("list").description("List all agents with their presence status").option("--online", "Only show online agents").option("--json", "Output as JSON").action((opts) => {
49854
+ agents.command("list").description("List all agents with their presence status").option("--online", "Only show online agents").option("-j, --json", "Output as JSON").action((opts) => {
49789
49855
  const agent = resolveIdentity();
49790
49856
  heartbeat(agent);
49791
49857
  const agentsList = listAgents({ online_only: opts.online });
@@ -49805,7 +49871,7 @@ function registerAgentCommands(program2) {
49805
49871
  }
49806
49872
  closeDb();
49807
49873
  });
49808
- 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) => {
49874
+ agents.command("remove").description("Remove an agent from the presence list").argument("<name>", "Agent name to remove").option("-j, --json", "Output as JSON").action((name, opts) => {
49809
49875
  const agentName = typeof name === "string" ? name.trim() : "";
49810
49876
  if (!agentName) {
49811
49877
  console.error(chalk7.red("Agent name cannot be empty."));
@@ -49824,7 +49890,7 @@ function registerAgentCommands(program2) {
49824
49890
  }
49825
49891
  closeDb();
49826
49892
  });
49827
- agents.command("rename").description("Rename an agent in the presence list").argument("<old-name>", "Current agent name").argument("<new-name>", "New agent name").option("--json", "Output as JSON").action((oldName, newName, opts) => {
49893
+ agents.command("rename").description("Rename an agent in the presence list").argument("<old-name>", "Current agent name").argument("<new-name>", "New agent name").option("-j, --json", "Output as JSON").action((oldName, newName, opts) => {
49828
49894
  const old = typeof oldName === "string" ? oldName.trim() : "";
49829
49895
  const renamed = typeof newName === "string" ? newName.trim() : "";
49830
49896
  if (!old || !renamed) {
@@ -49848,7 +49914,7 @@ function registerAgentCommands(program2) {
49848
49914
  }
49849
49915
  closeDb();
49850
49916
  });
49851
- agents.command("register").description("Register an agent with conflict detection (30 min active window)").argument("<name>", "Agent name to register").option("--session <id>", "Session ID (default: random UUID)").option("--role <role>", "Agent role (default: agent)").option("--project <id>", "Project ID to lock agent to").option("--force", "Force takeover even if another session is active").option("--json", "Output as JSON").action((name, opts) => {
49917
+ agents.command("register").description("Register an agent with conflict detection (30 min active window)").argument("<name>", "Agent name to register").option("--session <id>", "Session ID (default: random UUID)").option("--role <role>", "Agent role (default: agent)").option("--project <id>", "Project ID to lock agent to").option("--force", "Force takeover even if another session is active").option("-j, --json", "Output as JSON").action((name, opts) => {
49852
49918
  const agentName = (typeof name === "string" ? name : "").trim();
49853
49919
  if (!agentName) {
49854
49920
  console.error(chalk7.red("Agent name is required."));
@@ -49873,7 +49939,7 @@ function registerAgentCommands(program2) {
49873
49939
  }
49874
49940
  closeDb();
49875
49941
  });
49876
- agents.command("heartbeat").description("Send a presence heartbeat to mark yourself as active").option("--from <agent>", "Agent identity (default: CONVERSATIONS_AGENT_ID or auto)").option("--status <status>", "Status: online, busy, idle (default: online)").option("--json", "Output as JSON").action((opts) => {
49942
+ agents.command("heartbeat").description("Send a presence heartbeat to mark yourself as active").option("--from <agent>", "Agent identity (default: CONVERSATIONS_AGENT_ID or auto)").option("--status <status>", "Status: online, busy, idle (default: online)").option("-j, --json", "Output as JSON").action((opts) => {
49877
49943
  const agent = resolveIdentity(opts.from);
49878
49944
  const status = opts.status || "online";
49879
49945
  heartbeat(agent, status);
@@ -49885,7 +49951,7 @@ function registerAgentCommands(program2) {
49885
49951
  closeDb();
49886
49952
  });
49887
49953
  const focus = program2.command("focus").description("Manage agent project focus");
49888
- focus.command("set").description("Set your project focus \u2014 scopes read operations to this project").argument("<project>", "Project ID or name").option("--from <agent>", "Agent identity").option("--json", "Output as JSON").action((projectArg, opts) => {
49954
+ focus.command("set").description("Set your project focus \u2014 scopes read operations to this project").argument("<project>", "Project ID or name").option("--from <agent>", "Agent identity").option("-j, --json", "Output as JSON").action((projectArg, opts) => {
49889
49955
  const agent = resolveIdentity(opts.from);
49890
49956
  const project = getProject(projectArg) || getProjectByName(projectArg);
49891
49957
  if (!project) {
@@ -49900,7 +49966,7 @@ function registerAgentCommands(program2) {
49900
49966
  }
49901
49967
  closeDb();
49902
49968
  });
49903
- focus.command("clear").description("Clear your project focus").option("--from <agent>", "Agent identity").option("--json", "Output as JSON").action((opts) => {
49969
+ focus.command("clear").description("Clear your project focus").option("--from <agent>", "Agent identity").option("-j, --json", "Output as JSON").action((opts) => {
49904
49970
  const agent = resolveIdentity(opts.from);
49905
49971
  getDb().prepare("UPDATE agent_presence SET project_id = NULL WHERE agent = ?").run(agent);
49906
49972
  if (opts.json) {
@@ -49910,7 +49976,7 @@ function registerAgentCommands(program2) {
49910
49976
  }
49911
49977
  closeDb();
49912
49978
  });
49913
- focus.command("get").description("Show current project focus").option("--from <agent>", "Agent identity").option("--json", "Output as JSON").action((opts) => {
49979
+ focus.command("get").description("Show current project focus").option("--from <agent>", "Agent identity").option("-j, --json", "Output as JSON").action((opts) => {
49914
49980
  const agent = resolveIdentity(opts.from);
49915
49981
  const presence = getPresence(agent);
49916
49982
  const projectId = presence?.project_id ?? null;
@@ -49927,7 +49993,7 @@ function registerAgentCommands(program2) {
49927
49993
  }
49928
49994
  closeDb();
49929
49995
  });
49930
- program2.command("whoami").description("Show current agent identity and online status").option("--from <agent>", "Explicit agent identity").action((opts) => {
49996
+ program2.command("whoami").description("Show current agent identity and online status").option("--from <agent>", "Explicit agent identity").option("-j, --json", "Output as JSON").action((opts) => {
49931
49997
  const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
49932
49998
  const agent = resolveIdentity(opts.from);
49933
49999
  let source;
@@ -49943,11 +50009,15 @@ function registerAgentCommands(program2) {
49943
50009
  source = `auto-generated (${agentIdFile})`;
49944
50010
  }
49945
50011
  const presence = getPresence(agent);
50012
+ const payload = buildWhoamiPayload(agent, source, presence);
50013
+ if (opts.json) {
50014
+ console.log(JSON.stringify(payload, null, 2));
50015
+ closeDb();
50016
+ return;
50017
+ }
49946
50018
  let onlineStatus;
49947
50019
  if (presence && presence.online) {
49948
- const lastSeenMs = new Date(presence.last_seen_at + "Z").getTime();
49949
- const agoMs = Date.now() - lastSeenMs;
49950
- const agoSec = Math.floor(agoMs / 1000);
50020
+ const agoSec = payload.last_seen_ago_seconds ?? 0;
49951
50021
  const agoStr = agoSec < 60 ? `${agoSec}s ago` : `${Math.floor(agoSec / 60)}m ago`;
49952
50022
  onlineStatus = chalk7.green(`yes`) + chalk7.dim(` (last seen ${agoStr})`);
49953
50023
  } else if (presence) {
@@ -49977,7 +50047,7 @@ var import__package = __toESM(require_package(), 1);
49977
50047
  import chalk8 from "chalk";
49978
50048
  function registerAnalyticsCommands(program2) {
49979
50049
  const graph = program2.command("graph").description("Knowledge graph operations");
49980
- graph.command("build").description("Build/rebuild knowledge graph from messages, spaces, projects").option("--json", "Output as JSON").action((opts) => {
50050
+ graph.command("build").description("Build/rebuild knowledge graph from messages, spaces, projects").option("-j, --json", "Output as JSON").action((opts) => {
49981
50051
  const result = buildGraph();
49982
50052
  if (opts.json) {
49983
50053
  console.log(JSON.stringify(result, null, 2));
@@ -49986,7 +50056,7 @@ function registerAnalyticsCommands(program2) {
49986
50056
  }
49987
50057
  closeDb();
49988
50058
  });
49989
- graph.command("stats").description("Show knowledge graph statistics").option("--json", "Output as JSON").action((opts) => {
50059
+ graph.command("stats").description("Show knowledge graph statistics").option("-j, --json", "Output as JSON").action((opts) => {
49990
50060
  const stats = getGraphStats();
49991
50061
  if (opts.json) {
49992
50062
  console.log(JSON.stringify(stats, null, 2));
@@ -49999,7 +50069,7 @@ function registerAnalyticsCommands(program2) {
49999
50069
  }
50000
50070
  closeDb();
50001
50071
  });
50002
- graph.command("agent").description("Show an agent's communication network").argument("<name>", "Agent name").option("--json", "Output as JSON").action((name, opts) => {
50072
+ graph.command("agent").description("Show an agent's communication network").argument("<name>", "Agent name").option("-j, --json", "Output as JSON").action((name, opts) => {
50003
50073
  const network = getAgentNetwork(name);
50004
50074
  if (opts.json) {
50005
50075
  console.log(JSON.stringify(network, null, 2));
@@ -50024,7 +50094,7 @@ function registerAnalyticsCommands(program2) {
50024
50094
  }
50025
50095
  closeDb();
50026
50096
  });
50027
- program2.command("summary").description("Get a structured summary of a conversation").argument("<target>", "Session ID or space name").option("--json", "Output as JSON").action((target, opts) => {
50097
+ program2.command("summary").description("Get a structured summary of a conversation").argument("<target>", "Session ID or space name").option("-j, --json", "Output as JSON").action((target, opts) => {
50028
50098
  const summary = getConversationSummary(target);
50029
50099
  if (!summary) {
50030
50100
  console.error(chalk8.red(`No messages found for "${target}"`));
@@ -50060,7 +50130,7 @@ function registerAnalyticsCommands(program2) {
50060
50130
  }
50061
50131
  closeDb();
50062
50132
  });
50063
- program2.command("topics").description("Extract topics from a space, session, or trending globally").option("--space <name>", "Topics for a specific space").option("--session <id>", "Topics for a specific session").option("--hours <n>", "Trending topics in last N hours", parseInt).option("--json", "Output as JSON").action((opts) => {
50133
+ program2.command("topics").description("Extract topics from a space, session, or trending globally").option("--space <name>", "Topics for a specific space").option("--session <id>", "Topics for a specific session").option("--hours <n>", "Trending topics in last N hours", parseInt).option("-j, --json", "Output as JSON").action((opts) => {
50064
50134
  let topics;
50065
50135
  if (opts.space) {
50066
50136
  topics = getSpaceTopics(opts.space);
@@ -50086,7 +50156,7 @@ function registerAnalyticsCommands(program2) {
50086
50156
  }
50087
50157
  closeDb();
50088
50158
  });
50089
- program2.command("hot").description("Show hot conversations ranked by activity").option("--limit <n>", "Max results", parseInt).option("--min-score <n>", "Minimum hotness score", parseInt).option("--space <name>", "Filter by space").option("--json", "Output as JSON").action((opts) => {
50159
+ program2.command("hot").description("Show hot conversations ranked by activity").option("--limit <n>", "Max results", parseInt).option("--min-score <n>", "Minimum hotness score", parseInt).option("--space <name>", "Filter by space").option("-j, --json", "Output as JSON").action((opts) => {
50090
50160
  const sessions = listHotSessions({
50091
50161
  limit: opts.limit ?? 10,
50092
50162
  min_score: opts.minScore,
@@ -50112,7 +50182,7 @@ function registerAnalyticsCommands(program2) {
50112
50182
  }
50113
50183
  closeDb();
50114
50184
  });
50115
- program2.command("context").description("One-shot session boot context for agents: online agents, unread DMs, spaces, recent activity").option("--json", "Output as JSON").action((opts) => {
50185
+ program2.command("context").description("One-shot session boot context for agents: online agents, unread DMs, spaces, recent activity").option("-j, --json", "Output as JSON").action((opts) => {
50116
50186
  const agent = resolveIdentity();
50117
50187
  heartbeat(agent);
50118
50188
  const db2 = getDb();
@@ -50159,7 +50229,7 @@ function registerAnalyticsCommands(program2) {
50159
50229
  }
50160
50230
  closeDb();
50161
50231
  });
50162
- program2.command("sessions").description("List conversation sessions").option("--agent <id>", "Filter sessions involving this agent").option("--json", "Output as JSON").action((opts) => {
50232
+ program2.command("sessions").description("List conversation sessions").option("--agent <id>", "Filter sessions involving this agent").option("-j, --json", "Output as JSON").action((opts) => {
50163
50233
  const sessions = listSessions(opts.agent);
50164
50234
  if (opts.json) {
50165
50235
  console.log(JSON.stringify(sessions, null, 2));
@@ -50176,7 +50246,7 @@ function registerAnalyticsCommands(program2) {
50176
50246
  }
50177
50247
  closeDb();
50178
50248
  });
50179
- program2.command("status").description("Show database stats").option("--json", "Output as JSON").action((opts) => {
50249
+ program2.command("status").description("Show database stats").option("-j, --json", "Output as JSON").action((opts) => {
50180
50250
  const db2 = getDb();
50181
50251
  const dbPath = getDbPath2();
50182
50252
  const totalMessages = db2.prepare("SELECT COUNT(*) as count FROM messages").get().count;
@@ -50205,7 +50275,7 @@ function registerAnalyticsCommands(program2) {
50205
50275
  }
50206
50276
  closeDb();
50207
50277
  });
50208
- program2.command("doctor").description("Check conversations setup and health").option("--json", "Output as JSON").action(async (opts) => {
50278
+ program2.command("doctor").description("Check conversations setup and health").option("-j, --json", "Output as JSON").action(async (opts) => {
50209
50279
  const checks = [];
50210
50280
  try {
50211
50281
  const db2 = getDb();
@@ -50279,7 +50349,7 @@ function registerAnalyticsCommands(program2) {
50279
50349
  }
50280
50350
  }
50281
50351
  });
50282
- program2.command("react").description("Add an emoji reaction to a message").argument("<id>", "Message ID", parseInt).argument("<emoji>", "Emoji to react with").option("--from <agent>", "Agent identity override").option("--json", "Output as JSON").action((id, emoji, opts) => {
50352
+ program2.command("react").description("Add an emoji reaction to a message").argument("<id>", "Message ID", parseInt).argument("<emoji>", "Emoji to react with").option("--from <agent>", "Agent identity override").option("-j, --json", "Output as JSON").action((id, emoji, opts) => {
50283
50353
  const agent = resolveIdentity(opts.from);
50284
50354
  const reaction = addReaction(id, agent, emoji);
50285
50355
  if (opts.json) {
@@ -50289,7 +50359,7 @@ function registerAnalyticsCommands(program2) {
50289
50359
  }
50290
50360
  closeDb();
50291
50361
  });
50292
- program2.command("unreact").description("Remove an emoji reaction from a message").argument("<id>", "Message ID", parseInt).argument("<emoji>", "Emoji to remove").option("--from <agent>", "Agent identity override").option("--json", "Output as JSON").action((id, emoji, opts) => {
50362
+ program2.command("unreact").description("Remove an emoji reaction from a message").argument("<id>", "Message ID", parseInt).argument("<emoji>", "Emoji to remove").option("--from <agent>", "Agent identity override").option("-j, --json", "Output as JSON").action((id, emoji, opts) => {
50293
50363
  const agent = resolveIdentity(opts.from);
50294
50364
  const removed = removeReaction(id, agent, emoji);
50295
50365
  if (opts.json) {
@@ -50303,7 +50373,7 @@ function registerAnalyticsCommands(program2) {
50303
50373
  }
50304
50374
  closeDb();
50305
50375
  });
50306
- program2.command("reactions").description("Show emoji reactions on a message").argument("<id>", "Message ID", parseInt).option("--json", "Output as JSON").action((id, opts) => {
50376
+ program2.command("reactions").description("Show emoji reactions on a message").argument("<id>", "Message ID", parseInt).option("-j, --json", "Output as JSON").action((id, opts) => {
50307
50377
  const summary = getReactionSummary(id);
50308
50378
  if (opts.json) {
50309
50379
  console.log(JSON.stringify(summary, null, 2));
package/bin/mcp.js CHANGED
@@ -42094,6 +42094,18 @@ function listProjects(opts) {
42094
42094
  params.push(opts.status);
42095
42095
  }
42096
42096
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
42097
+ let pagination = "";
42098
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
42099
+ pagination += " LIMIT ?";
42100
+ params.push(Math.floor(opts.limit));
42101
+ }
42102
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
42103
+ if (!pagination.includes("LIMIT")) {
42104
+ pagination += " LIMIT -1";
42105
+ }
42106
+ pagination += " OFFSET ?";
42107
+ params.push(Math.floor(opts.offset));
42108
+ }
42097
42109
  const rows = db2.prepare(`
42098
42110
  SELECT
42099
42111
  p.*,
@@ -42101,6 +42113,7 @@ function listProjects(opts) {
42101
42113
  FROM projects p
42102
42114
  ${where}
42103
42115
  ORDER BY p.name ASC
42116
+ ${pagination}
42104
42117
  `).all(...params);
42105
42118
  return rows.map((row) => ({
42106
42119
  ...parseProject(row),
@@ -44256,7 +44269,7 @@ function registerTmuxTools(server) {
44256
44269
  // package.json
44257
44270
  var package_default = {
44258
44271
  name: "@hasna/conversations",
44259
- version: "0.2.32",
44272
+ version: "0.2.34",
44260
44273
  description: "Real-time CLI messaging for AI agents",
44261
44274
  type: "module",
44262
44275
  bin: {
@@ -1,2 +1,15 @@
1
1
  import type { Command } from "commander";
2
+ type PresenceView = {
3
+ online: boolean;
4
+ last_seen_at: string;
5
+ } | null;
6
+ export type WhoamiPayload = {
7
+ agent: string;
8
+ source: string;
9
+ online: boolean;
10
+ last_seen_at: string | null;
11
+ last_seen_ago_seconds: number | null;
12
+ };
13
+ export declare function buildWhoamiPayload(agent: string, source: string, presence: PresenceView, nowMs?: number): WhoamiPayload;
2
14
  export declare function registerAgentCommands(program: Command): void;
15
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,2 +1,7 @@
1
1
  import type { Command } from "commander";
2
+ export declare function requireDeleteConfirmation(confirmed?: boolean): void;
3
+ export declare function parseProjectListPagination(limitInput: unknown, offsetInput: unknown): {
4
+ limit: number | undefined;
5
+ offset: number | undefined;
6
+ };
2
7
  export declare function registerProjectCommands(program: Command): void;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -12428,6 +12428,18 @@ function listProjects(opts) {
12428
12428
  params.push(opts.status);
12429
12429
  }
12430
12430
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
12431
+ let pagination = "";
12432
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
12433
+ pagination += " LIMIT ?";
12434
+ params.push(Math.floor(opts.limit));
12435
+ }
12436
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
12437
+ if (!pagination.includes("LIMIT")) {
12438
+ pagination += " LIMIT -1";
12439
+ }
12440
+ pagination += " OFFSET ?";
12441
+ params.push(Math.floor(opts.offset));
12442
+ }
12431
12443
  const rows = db2.prepare(`
12432
12444
  SELECT
12433
12445
  p.*,
@@ -12435,6 +12447,7 @@ function listProjects(opts) {
12435
12447
  FROM projects p
12436
12448
  ${where}
12437
12449
  ORDER BY p.name ASC
12450
+ ${pagination}
12438
12451
  `).all(...params);
12439
12452
  return rows.map((row) => ({
12440
12453
  ...parseProject(row),
@@ -11,6 +11,8 @@ export declare function createProject(opts: {
11
11
  }): Project;
12
12
  export declare function listProjects(opts?: {
13
13
  status?: "active" | "archived";
14
+ limit?: number;
15
+ offset?: number;
14
16
  }): ProjectInfo[];
15
17
  export declare function getProject(id: string): ProjectInfo | null;
16
18
  export declare function getProjectByName(name: string): ProjectInfo | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.32",
3
+ "version": "0.2.34",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {