@hasna/conversations 0.1.20 → 0.1.22

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
@@ -2822,10 +2822,6 @@ function getProjectByName(name) {
2822
2822
  }
2823
2823
  function updateProject(id, updates) {
2824
2824
  const db2 = getDb();
2825
- const existing = db2.prepare("SELECT * FROM projects WHERE id = ?").get(id);
2826
- if (!existing) {
2827
- throw new Error(`Project not found: ${id}`);
2828
- }
2829
2825
  const sets = [];
2830
2826
  const params = [];
2831
2827
  if (updates.name !== undefined) {
@@ -2861,10 +2857,15 @@ function updateProject(id, updates) {
2861
2857
  params.push(JSON.stringify(updates.settings));
2862
2858
  }
2863
2859
  if (sets.length === 0) {
2864
- return parseProject(existing);
2860
+ const row2 = db2.prepare("SELECT * FROM projects WHERE id = ?").get(id);
2861
+ if (!row2)
2862
+ throw new Error(`Project not found: ${id}`);
2863
+ return parseProject(row2);
2865
2864
  }
2866
2865
  params.push(id);
2867
2866
  const row = db2.prepare(`UPDATE projects SET ${sets.join(", ")} WHERE id = ? RETURNING *`).get(...params);
2867
+ if (!row)
2868
+ throw new Error(`Project not found: ${id}`);
2868
2869
  return parseProject(row);
2869
2870
  }
2870
2871
  function deleteProject(id) {
@@ -3503,7 +3504,7 @@ var init_poll = __esm(() => {
3503
3504
  var require_package = __commonJS((exports, module) => {
3504
3505
  module.exports = {
3505
3506
  name: "@hasna/conversations",
3506
- version: "0.1.20",
3507
+ version: "0.1.22",
3507
3508
  description: "Real-time CLI messaging for AI agents",
3508
3509
  type: "module",
3509
3510
  bin: {
@@ -32474,89 +32475,66 @@ var init_mcp2 = __esm(() => {
32474
32475
  version: import__package.default.version
32475
32476
  });
32476
32477
  server.registerTool("send_message", {
32477
- title: "Send Message",
32478
- description: "Send a direct message to another agent.",
32478
+ description: "Send a DM to an agent.",
32479
32479
  inputSchema: {
32480
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32481
- to: exports_external.string().describe("Recipient agent ID"),
32482
- content: exports_external.string().describe("Message content"),
32483
- session_id: exports_external.string().optional().describe("Session ID (auto-generated if omitted)"),
32484
- priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority"),
32485
- working_dir: exports_external.string().optional().describe("Working directory context"),
32486
- repository: exports_external.string().optional().describe("Repository context"),
32487
- branch: exports_external.string().optional().describe("Branch context"),
32488
- metadata: exports_external.string().optional().describe("JSON metadata string"),
32489
- blocking: exports_external.boolean().optional().describe("Blocking message \u2014 recipients must acknowledge before continuing")
32490
- }
32491
- }, async ({ from: fromParam, to, content, session_id, priority, working_dir, repository, branch, metadata, blocking }) => {
32480
+ to: exports_external.string(),
32481
+ content: exports_external.string(),
32482
+ from: exports_external.string().optional(),
32483
+ priority: exports_external.string().optional(),
32484
+ blocking: exports_external.boolean().optional()
32485
+ }
32486
+ }, async (args) => {
32487
+ const { from: fromParam, to, content, priority, blocking } = args;
32492
32488
  const from = resolveIdentity(fromParam);
32493
- let parsedMetadata;
32494
- if (metadata) {
32495
- try {
32496
- parsedMetadata = JSON.parse(metadata);
32497
- } catch {
32498
- return {
32499
- content: [{ type: "text", text: "invalid JSON" }],
32500
- isError: true
32501
- };
32502
- }
32503
- }
32504
32489
  const msg = sendMessage({
32505
32490
  from,
32506
32491
  to,
32507
32492
  content,
32508
- session_id,
32509
32493
  priority,
32510
- working_dir,
32511
- repository,
32512
- branch,
32513
- metadata: parsedMetadata,
32514
32494
  blocking
32515
32495
  });
32516
32496
  return {
32517
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
32497
+ content: [{ type: "text", text: JSON.stringify(msg) }]
32518
32498
  };
32519
32499
  });
32520
32500
  server.registerTool("read_messages", {
32521
- title: "Read Messages",
32522
- description: "Read messages with filters, newest first.",
32501
+ description: "Read DMs with optional filters.",
32523
32502
  inputSchema: {
32524
- session_id: exports_external.string().optional().describe("Filter by session ID"),
32525
- from: exports_external.string().optional().describe("Filter by sender"),
32526
- to: exports_external.string().optional().describe("Filter by recipient"),
32527
- space: exports_external.string().optional().describe("Filter by space name"),
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")
32531
- }
32532
- }, async (opts) => {
32533
- const messages = readMessages(opts);
32503
+ session_id: exports_external.string().optional(),
32504
+ from: exports_external.string().optional(),
32505
+ to: exports_external.string().optional(),
32506
+ space: exports_external.string().optional(),
32507
+ since: exports_external.string().optional(),
32508
+ limit: exports_external.number().optional(),
32509
+ unread_only: exports_external.boolean().optional()
32510
+ }
32511
+ }, async (args) => {
32512
+ const messages = readMessages(args);
32534
32513
  return {
32535
- content: [{ type: "text", text: JSON.stringify(messages, null, 2) }]
32514
+ content: [{ type: "text", text: JSON.stringify(messages) }]
32536
32515
  };
32537
32516
  });
32538
32517
  server.registerTool("list_sessions", {
32539
- title: "List Sessions",
32540
- description: "List sessions, optionally filtered by agent.",
32518
+ description: "List all sessions by agent.",
32541
32519
  inputSchema: {
32542
- agent: exports_external.string().optional().describe("Filter sessions involving this agent")
32520
+ agent: exports_external.string().optional()
32543
32521
  }
32544
- }, async ({ agent }) => {
32522
+ }, async (args) => {
32523
+ const { agent } = args;
32545
32524
  const sessions = listSessions(agent);
32546
32525
  return {
32547
- content: [{ type: "text", text: JSON.stringify(sessions, null, 2) }]
32526
+ content: [{ type: "text", text: JSON.stringify(sessions) }]
32548
32527
  };
32549
32528
  });
32550
32529
  server.registerTool("reply", {
32551
- title: "Reply to Message",
32552
- description: "Reply to a message (same session, original sender).",
32530
+ description: "Reply to a message by ID.",
32553
32531
  inputSchema: {
32554
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32555
- message_id: exports_external.number().describe("ID of the message to reply to"),
32556
- content: exports_external.string().describe("Reply content"),
32557
- priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority")
32532
+ message_id: exports_external.number(),
32533
+ content: exports_external.string(),
32534
+ from: exports_external.string().optional()
32558
32535
  }
32559
- }, async ({ from: fromParam, message_id, content, priority }) => {
32536
+ }, async (args) => {
32537
+ const { from: fromParam, message_id, content } = args;
32560
32538
  const original = getMessageById(message_id);
32561
32539
  if (!original) {
32562
32540
  return {
@@ -32572,22 +32550,21 @@ var init_mcp2 = __esm(() => {
32572
32550
  to,
32573
32551
  content,
32574
32552
  session_id: original.session_id,
32575
- priority,
32576
32553
  space
32577
32554
  });
32578
32555
  return {
32579
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
32556
+ content: [{ type: "text", text: JSON.stringify(msg) }]
32580
32557
  };
32581
32558
  });
32582
32559
  server.registerTool("mark_read", {
32583
- title: "Mark Read",
32584
- description: "Mark messages as read. Provide IDs or set 'all' to true.",
32560
+ description: "Mark messages read by IDs or all.",
32585
32561
  inputSchema: {
32586
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32587
- ids: exports_external.array(exports_external.number()).optional().describe("Message IDs to mark as read"),
32588
- all: exports_external.boolean().optional().describe("Mark all unread messages as read")
32562
+ from: exports_external.string().optional(),
32563
+ ids: exports_external.array(exports_external.number()).optional(),
32564
+ all: exports_external.boolean().optional()
32589
32565
  }
32590
- }, async ({ from: fromParam, ids, all }) => {
32566
+ }, async (args) => {
32567
+ const { from: fromParam, ids, all } = args;
32591
32568
  const agent = resolveIdentity(fromParam);
32592
32569
  let count;
32593
32570
  if (all) {
@@ -32601,58 +32578,58 @@ var init_mcp2 = __esm(() => {
32601
32578
  };
32602
32579
  }
32603
32580
  return {
32604
- content: [{ type: "text", text: JSON.stringify({ marked_read: count }, null, 2) }]
32581
+ content: [{ type: "text", text: JSON.stringify({ marked_read: count }) }]
32605
32582
  };
32606
32583
  });
32607
32584
  server.registerTool("search_messages", {
32608
- title: "Search Messages",
32609
- description: "Full-text search across message content, newest first.",
32585
+ description: "Full-text search across messages.",
32610
32586
  inputSchema: {
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)")
32616
- }
32617
- }, async ({ query, space, from, to, limit }) => {
32587
+ query: exports_external.string(),
32588
+ space: exports_external.string().optional(),
32589
+ from: exports_external.string().optional(),
32590
+ to: exports_external.string().optional(),
32591
+ limit: exports_external.number().optional()
32592
+ }
32593
+ }, async (args) => {
32594
+ const { query, space, from, to, limit } = args;
32618
32595
  const messages = searchMessages({ query, space, from, to, limit });
32619
32596
  return {
32620
- content: [{ type: "text", text: JSON.stringify(messages, null, 2) }]
32597
+ content: [{ type: "text", text: JSON.stringify(messages) }]
32621
32598
  };
32622
32599
  });
32623
32600
  server.registerTool("export_messages", {
32624
- title: "Export Messages",
32625
- description: "Export messages as JSON or CSV with optional filters.",
32601
+ description: "Export messages as JSON or CSV.",
32626
32602
  inputSchema: {
32627
- space: exports_external.string().optional().describe("Filter by space"),
32628
- session_id: exports_external.string().optional().describe("Filter by session ID"),
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"),
32632
- format: exports_external.enum(["json", "csv"]).optional().describe("Output format (default: json)")
32633
- }
32634
- }, async ({ space, session_id, from, since, until, format }) => {
32603
+ space: exports_external.string().optional(),
32604
+ session_id: exports_external.string().optional(),
32605
+ from: exports_external.string().optional(),
32606
+ since: exports_external.string().optional(),
32607
+ until: exports_external.string().optional(),
32608
+ format: exports_external.string().optional()
32609
+ }
32610
+ }, async (args) => {
32611
+ const { space, session_id, from, since, until, format } = args;
32635
32612
  const result = exportMessages({ space, session_id, from, since, until, format });
32636
32613
  return {
32637
32614
  content: [{ type: "text", text: result }]
32638
32615
  };
32639
32616
  });
32640
32617
  server.registerTool("create_space", {
32641
- title: "Create Space",
32642
- description: "Create a space. Auto-joined. Supports nesting and projects.",
32618
+ description: "Create a space and auto-join.",
32643
32619
  inputSchema: {
32644
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32645
- name: exports_external.string().describe("Space name"),
32646
- description: exports_external.string().optional().describe("Space description"),
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")
32649
- }
32650
- }, async ({ from: fromParam, name, description, parent_id, project_id }) => {
32620
+ name: exports_external.string(),
32621
+ from: exports_external.string().optional(),
32622
+ description: exports_external.string().optional(),
32623
+ parent_id: exports_external.string().optional(),
32624
+ project_id: exports_external.string().optional()
32625
+ }
32626
+ }, async (args) => {
32627
+ const { from: fromParam, name, description, parent_id, project_id } = args;
32651
32628
  const agent = resolveIdentity(fromParam);
32652
32629
  try {
32653
32630
  const sp = createSpace(name, agent, { description, parent_id, project_id });
32654
32631
  return {
32655
- content: [{ type: "text", text: JSON.stringify(sp, null, 2) }]
32632
+ content: [{ type: "text", text: JSON.stringify(sp) }]
32656
32633
  };
32657
32634
  } catch (e) {
32658
32635
  if (e.message?.includes("UNIQUE constraint")) {
@@ -32668,14 +32645,14 @@ var init_mcp2 = __esm(() => {
32668
32645
  }
32669
32646
  });
32670
32647
  server.registerTool("list_spaces", {
32671
- title: "List Spaces",
32672
- description: "List spaces with member/message counts.",
32648
+ description: "List spaces with counts.",
32673
32649
  inputSchema: {
32674
- project_id: exports_external.string().optional().describe("Filter by project ID"),
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")
32650
+ project_id: exports_external.string().optional(),
32651
+ parent_id: exports_external.string().optional(),
32652
+ include_archived: exports_external.boolean().optional()
32677
32653
  }
32678
- }, async ({ project_id, parent_id, include_archived }) => {
32654
+ }, async (args) => {
32655
+ const { project_id, parent_id, include_archived } = args;
32679
32656
  const opts = {};
32680
32657
  if (project_id)
32681
32658
  opts.project_id = project_id;
@@ -32688,20 +32665,20 @@ var init_mcp2 = __esm(() => {
32688
32665
  opts.include_archived = true;
32689
32666
  const spaces = listSpaces(opts);
32690
32667
  return {
32691
- content: [{ type: "text", text: JSON.stringify(spaces, null, 2) }]
32668
+ content: [{ type: "text", text: JSON.stringify(spaces) }]
32692
32669
  };
32693
32670
  });
32694
32671
  server.registerTool("send_to_space", {
32695
- title: "Send to Space",
32696
- description: "Send a message to a space. All members can see it.",
32672
+ description: "Post a message to a space.",
32697
32673
  inputSchema: {
32698
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32699
- space: exports_external.string().describe("Space name"),
32700
- content: exports_external.string().describe("Message content"),
32701
- priority: exports_external.enum(["low", "normal", "high", "urgent"]).optional().describe("Message priority"),
32702
- blocking: exports_external.boolean().optional().describe("Blocking message \u2014 all space members must acknowledge")
32703
- }
32704
- }, async ({ from: fromParam, space, content, priority, blocking }) => {
32674
+ space: exports_external.string(),
32675
+ content: exports_external.string(),
32676
+ from: exports_external.string().optional(),
32677
+ priority: exports_external.string().optional(),
32678
+ blocking: exports_external.boolean().optional()
32679
+ }
32680
+ }, async (args) => {
32681
+ const { from: fromParam, space, content, priority, blocking } = args;
32705
32682
  const from = resolveIdentity(fromParam);
32706
32683
  const sp = getSpace(space);
32707
32684
  if (!sp) {
@@ -32720,31 +32697,31 @@ var init_mcp2 = __esm(() => {
32720
32697
  blocking
32721
32698
  });
32722
32699
  return {
32723
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
32700
+ content: [{ type: "text", text: JSON.stringify(msg) }]
32724
32701
  };
32725
32702
  });
32726
32703
  server.registerTool("read_space", {
32727
- title: "Read Space",
32728
32704
  description: "Read messages from a space.",
32729
32705
  inputSchema: {
32730
- space: exports_external.string().describe("Space name"),
32731
- since: exports_external.string().optional().describe("ISO timestamp lower bound"),
32732
- limit: exports_external.number().optional().describe("Max messages to return")
32706
+ space: exports_external.string(),
32707
+ since: exports_external.string().optional(),
32708
+ limit: exports_external.number().optional()
32733
32709
  }
32734
- }, async ({ space, since, limit }) => {
32710
+ }, async (args) => {
32711
+ const { space, since, limit } = args;
32735
32712
  const messages = readMessages({ space, since, limit });
32736
32713
  return {
32737
- content: [{ type: "text", text: JSON.stringify(messages, null, 2) }]
32714
+ content: [{ type: "text", text: JSON.stringify(messages) }]
32738
32715
  };
32739
32716
  });
32740
32717
  server.registerTool("join_space", {
32741
- title: "Join Space",
32742
- description: "Join a space to receive messages.",
32718
+ description: "Join a space as a member.",
32743
32719
  inputSchema: {
32744
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32745
- space: exports_external.string().describe("Space name to join")
32720
+ space: exports_external.string(),
32721
+ from: exports_external.string().optional()
32746
32722
  }
32747
- }, async ({ from: fromParam, space }) => {
32723
+ }, async (args) => {
32724
+ const { from: fromParam, space } = args;
32748
32725
  const agent = resolveIdentity(fromParam);
32749
32726
  const ok = joinSpace(space, agent);
32750
32727
  if (!ok) {
@@ -32754,33 +32731,33 @@ var init_mcp2 = __esm(() => {
32754
32731
  };
32755
32732
  }
32756
32733
  return {
32757
- content: [{ type: "text", text: JSON.stringify({ space, agent, joined: true }, null, 2) }]
32734
+ content: [{ type: "text", text: JSON.stringify({ space, agent, joined: true }) }]
32758
32735
  };
32759
32736
  });
32760
32737
  server.registerTool("leave_space", {
32761
- title: "Leave Space",
32762
32738
  description: "Leave a space.",
32763
32739
  inputSchema: {
32764
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32765
- space: exports_external.string().describe("Space name to leave")
32740
+ space: exports_external.string(),
32741
+ from: exports_external.string().optional()
32766
32742
  }
32767
- }, async ({ from: fromParam, space }) => {
32743
+ }, async (args) => {
32744
+ const { from: fromParam, space } = args;
32768
32745
  const agent = resolveIdentity(fromParam);
32769
32746
  const left = leaveSpace(space, agent);
32770
32747
  return {
32771
- content: [{ type: "text", text: JSON.stringify({ space, agent, left }, null, 2) }]
32748
+ content: [{ type: "text", text: JSON.stringify({ space, agent, left }) }]
32772
32749
  };
32773
32750
  });
32774
32751
  server.registerTool("update_space", {
32775
- title: "Update Space",
32776
- description: "Update a space's description, parent, or project.",
32752
+ description: "Update space description or parent.",
32777
32753
  inputSchema: {
32778
- name: exports_external.string().describe("Space name"),
32779
- description: exports_external.string().optional().describe("New description"),
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)")
32754
+ name: exports_external.string(),
32755
+ description: exports_external.string().optional(),
32756
+ parent_id: exports_external.string().optional(),
32757
+ project_id: exports_external.string().optional()
32782
32758
  }
32783
- }, async ({ name, description, parent_id, project_id }) => {
32759
+ }, async (args) => {
32760
+ const { name, description, parent_id, project_id } = args;
32784
32761
  const updates = {};
32785
32762
  if (description !== undefined)
32786
32763
  updates.description = description;
@@ -32791,7 +32768,7 @@ var init_mcp2 = __esm(() => {
32791
32768
  try {
32792
32769
  const sp = updateSpace(name, updates);
32793
32770
  return {
32794
- content: [{ type: "text", text: JSON.stringify(sp, null, 2) }]
32771
+ content: [{ type: "text", text: JSON.stringify(sp) }]
32795
32772
  };
32796
32773
  } catch (e) {
32797
32774
  return {
@@ -32801,16 +32778,15 @@ var init_mcp2 = __esm(() => {
32801
32778
  }
32802
32779
  });
32803
32780
  server.registerTool("archive_space", {
32804
- title: "Archive Space",
32805
- description: "Archive a space. Hidden from list by default.",
32781
+ description: "Archive a space.",
32806
32782
  inputSchema: {
32807
- name: exports_external.string().describe("Space name to archive")
32783
+ name: exports_external.string()
32808
32784
  }
32809
32785
  }, async ({ name }) => {
32810
32786
  try {
32811
32787
  const sp = archiveSpace(name);
32812
32788
  return {
32813
- content: [{ type: "text", text: JSON.stringify(sp, null, 2) }]
32789
+ content: [{ type: "text", text: JSON.stringify(sp) }]
32814
32790
  };
32815
32791
  } catch (e) {
32816
32792
  return {
@@ -32820,16 +32796,15 @@ var init_mcp2 = __esm(() => {
32820
32796
  }
32821
32797
  });
32822
32798
  server.registerTool("unarchive_space", {
32823
- title: "Unarchive Space",
32824
- description: "Unarchive a previously archived space.",
32799
+ description: "Unarchive a space.",
32825
32800
  inputSchema: {
32826
- name: exports_external.string().describe("Space name to unarchive")
32801
+ name: exports_external.string()
32827
32802
  }
32828
32803
  }, async ({ name }) => {
32829
32804
  try {
32830
32805
  const sp = unarchiveSpace(name);
32831
32806
  return {
32832
- content: [{ type: "text", text: JSON.stringify(sp, null, 2) }]
32807
+ content: [{ type: "text", text: JSON.stringify(sp) }]
32833
32808
  };
32834
32809
  } catch (e) {
32835
32810
  return {
@@ -32839,19 +32814,19 @@ var init_mcp2 = __esm(() => {
32839
32814
  }
32840
32815
  });
32841
32816
  server.registerTool("create_project", {
32842
- title: "Create Project",
32843
- description: "Create a project for spaces and agent collaboration.",
32817
+ description: "Create a project for agent collaboration.",
32844
32818
  inputSchema: {
32845
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
32846
- name: exports_external.string().describe("Project name (unique)"),
32847
- description: exports_external.string().optional().describe("Project description"),
32848
- path: exports_external.string().optional().describe("Absolute path on disk"),
32849
- repository: exports_external.string().optional().describe("Repository URL"),
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")
32853
- }
32854
- }, async ({ from: fromParam, name, description, path, repository, tags, metadata, settings }) => {
32819
+ name: exports_external.string(),
32820
+ from: exports_external.string().optional(),
32821
+ description: exports_external.string().optional(),
32822
+ path: exports_external.string().optional(),
32823
+ repository: exports_external.string().optional(),
32824
+ tags: exports_external.string().optional(),
32825
+ metadata: exports_external.string().optional(),
32826
+ settings: exports_external.string().optional()
32827
+ }
32828
+ }, async (args) => {
32829
+ const { from: fromParam, name, description, path, repository, tags, metadata, settings } = args;
32855
32830
  const agent = resolveIdentity(fromParam);
32856
32831
  let parsedTags;
32857
32832
  if (tags) {
@@ -32898,7 +32873,7 @@ var init_mcp2 = __esm(() => {
32898
32873
  settings: parsedSettings
32899
32874
  });
32900
32875
  return {
32901
- content: [{ type: "text", text: JSON.stringify(project, null, 2) }]
32876
+ content: [{ type: "text", text: JSON.stringify(project) }]
32902
32877
  };
32903
32878
  } catch (e) {
32904
32879
  if (e.message?.includes("UNIQUE constraint")) {
@@ -32914,22 +32889,21 @@ var init_mcp2 = __esm(() => {
32914
32889
  }
32915
32890
  });
32916
32891
  server.registerTool("list_projects", {
32917
- title: "List Projects",
32918
- description: "List all registered projects.",
32892
+ description: "List all projects.",
32919
32893
  inputSchema: {
32920
- status: exports_external.enum(["active", "archived"]).optional().describe("Filter by status")
32894
+ status: exports_external.string().optional()
32921
32895
  }
32922
- }, async ({ status }) => {
32896
+ }, async (args) => {
32897
+ const { status } = args;
32923
32898
  const projects = listProjects(status ? { status } : undefined);
32924
32899
  return {
32925
- content: [{ type: "text", text: JSON.stringify(projects, null, 2) }]
32900
+ content: [{ type: "text", text: JSON.stringify(projects) }]
32926
32901
  };
32927
32902
  });
32928
32903
  server.registerTool("get_project", {
32929
- title: "Get Project",
32930
- description: "Get full details of a project by ID or name.",
32904
+ description: "Get a project by ID or name.",
32931
32905
  inputSchema: {
32932
- id: exports_external.string().describe("Project ID (UUID) or name")
32906
+ id: exports_external.string()
32933
32907
  }
32934
32908
  }, async ({ id }) => {
32935
32909
  let project = getProject(id);
@@ -32943,24 +32917,24 @@ var init_mcp2 = __esm(() => {
32943
32917
  };
32944
32918
  }
32945
32919
  return {
32946
- content: [{ type: "text", text: JSON.stringify(project, null, 2) }]
32920
+ content: [{ type: "text", text: JSON.stringify(project) }]
32947
32921
  };
32948
32922
  });
32949
32923
  server.registerTool("update_project", {
32950
- title: "Update Project",
32951
- description: "Update a project's fields.",
32924
+ description: "Update project fields by ID.",
32952
32925
  inputSchema: {
32953
- id: exports_external.string().describe("Project ID (UUID)"),
32954
- name: exports_external.string().optional().describe("New name"),
32955
- description: exports_external.string().optional().describe("New description"),
32956
- path: exports_external.string().optional().describe("New path"),
32957
- status: exports_external.enum(["active", "archived"]).optional().describe("New status"),
32958
- repository: exports_external.string().optional().describe("New repository URL"),
32959
- tags: exports_external.string().optional().describe("JSON array of tags"),
32960
- metadata: exports_external.string().optional().describe("JSON metadata"),
32961
- settings: exports_external.string().optional().describe("JSON settings")
32962
- }
32963
- }, async ({ id, name, description, path, status, repository, tags, metadata, settings }) => {
32926
+ id: exports_external.string(),
32927
+ name: exports_external.string().optional(),
32928
+ description: exports_external.string().optional(),
32929
+ path: exports_external.string().optional(),
32930
+ status: exports_external.string().optional(),
32931
+ repository: exports_external.string().optional(),
32932
+ tags: exports_external.string().optional(),
32933
+ metadata: exports_external.string().optional(),
32934
+ settings: exports_external.string().optional()
32935
+ }
32936
+ }, async (args) => {
32937
+ const { id, name, description, path, status, repository, tags, metadata, settings } = args;
32964
32938
  const updates = {};
32965
32939
  if (name !== undefined)
32966
32940
  updates.name = name;
@@ -33005,7 +32979,7 @@ var init_mcp2 = __esm(() => {
33005
32979
  try {
33006
32980
  const project = updateProject(id, updates);
33007
32981
  return {
33008
- content: [{ type: "text", text: JSON.stringify(project, null, 2) }]
32982
+ content: [{ type: "text", text: JSON.stringify(project) }]
33009
32983
  };
33010
32984
  } catch (e) {
33011
32985
  return {
@@ -33015,10 +32989,9 @@ var init_mcp2 = __esm(() => {
33015
32989
  }
33016
32990
  });
33017
32991
  server.registerTool("delete_project", {
33018
- title: "Delete Project",
33019
- description: "Delete a project permanently. Fails if spaces reference it.",
32992
+ description: "Delete a project permanently.",
33020
32993
  inputSchema: {
33021
- id: exports_external.string().describe("Project ID (UUID)")
32994
+ id: exports_external.string()
33022
32995
  }
33023
32996
  }, async ({ id }) => {
33024
32997
  try {
@@ -33030,7 +33003,7 @@ var init_mcp2 = __esm(() => {
33030
33003
  };
33031
33004
  }
33032
33005
  return {
33033
- content: [{ type: "text", text: JSON.stringify({ id, deleted: true }, null, 2) }]
33006
+ content: [{ type: "text", text: JSON.stringify({ id, deleted: true }) }]
33034
33007
  };
33035
33008
  } catch (e) {
33036
33009
  return {
@@ -33040,13 +33013,13 @@ var init_mcp2 = __esm(() => {
33040
33013
  }
33041
33014
  });
33042
33015
  server.registerTool("delete_message", {
33043
- title: "Delete Message",
33044
- description: "Delete a message. Sender only.",
33016
+ description: "Delete a message (sender only).",
33045
33017
  inputSchema: {
33046
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
33047
- id: exports_external.number().describe("Message ID to delete")
33018
+ id: exports_external.number(),
33019
+ from: exports_external.string().optional()
33048
33020
  }
33049
- }, async ({ from: fromParam, id }) => {
33021
+ }, async (args) => {
33022
+ const { from: fromParam, id } = args;
33050
33023
  const agent = resolveIdentity(fromParam);
33051
33024
  const deleted = deleteMessage(id, agent);
33052
33025
  if (!deleted) {
@@ -33056,18 +33029,18 @@ var init_mcp2 = __esm(() => {
33056
33029
  };
33057
33030
  }
33058
33031
  return {
33059
- content: [{ type: "text", text: JSON.stringify({ deleted: true }, null, 2) }]
33032
+ content: [{ type: "text", text: JSON.stringify({ deleted: true }) }]
33060
33033
  };
33061
33034
  });
33062
33035
  server.registerTool("edit_message", {
33063
- title: "Edit Message",
33064
- description: "Edit a message's content. Sender only.",
33036
+ description: "Edit message content (sender only).",
33065
33037
  inputSchema: {
33066
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
33067
- id: exports_external.number().describe("Message ID to edit"),
33068
- content: exports_external.string().describe("New message content")
33038
+ id: exports_external.number(),
33039
+ content: exports_external.string(),
33040
+ from: exports_external.string().optional()
33069
33041
  }
33070
- }, async ({ from: fromParam, id, content }) => {
33042
+ }, async (args) => {
33043
+ const { from: fromParam, id, content } = args;
33071
33044
  const agent = resolveIdentity(fromParam);
33072
33045
  const msg = editMessage(id, agent, content);
33073
33046
  if (!msg) {
@@ -33077,14 +33050,13 @@ var init_mcp2 = __esm(() => {
33077
33050
  };
33078
33051
  }
33079
33052
  return {
33080
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
33053
+ content: [{ type: "text", text: JSON.stringify(msg) }]
33081
33054
  };
33082
33055
  });
33083
33056
  server.registerTool("pin_message", {
33084
- title: "Pin Message",
33085
- description: "Pin a message in a space or session.",
33057
+ description: "Pin a message.",
33086
33058
  inputSchema: {
33087
- id: exports_external.number().describe("Message ID to pin")
33059
+ id: exports_external.number()
33088
33060
  }
33089
33061
  }, async ({ id }) => {
33090
33062
  const msg = pinMessage(id);
@@ -33095,14 +33067,13 @@ var init_mcp2 = __esm(() => {
33095
33067
  };
33096
33068
  }
33097
33069
  return {
33098
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
33070
+ content: [{ type: "text", text: JSON.stringify(msg) }]
33099
33071
  };
33100
33072
  });
33101
33073
  server.registerTool("unpin_message", {
33102
- title: "Unpin Message",
33103
- description: "Unpin a previously pinned message.",
33074
+ description: "Unpin a message.",
33104
33075
  inputSchema: {
33105
- id: exports_external.number().describe("Message ID to unpin")
33076
+ id: exports_external.number()
33106
33077
  }
33107
33078
  }, async ({ id }) => {
33108
33079
  const msg = unpinMessage(id);
@@ -33113,70 +33084,70 @@ var init_mcp2 = __esm(() => {
33113
33084
  };
33114
33085
  }
33115
33086
  return {
33116
- content: [{ type: "text", text: JSON.stringify(msg, null, 2) }]
33087
+ content: [{ type: "text", text: JSON.stringify(msg) }]
33117
33088
  };
33118
33089
  });
33119
33090
  server.registerTool("get_pinned_messages", {
33120
- title: "Get Pinned Messages",
33121
- description: "Get pinned messages, filtered by space or session.",
33091
+ description: "Get pinned messages by space or session.",
33122
33092
  inputSchema: {
33123
- space: exports_external.string().optional().describe("Filter by space"),
33124
- session_id: exports_external.string().optional().describe("Filter by session ID"),
33125
- limit: exports_external.number().optional().describe("Max messages to return")
33093
+ space: exports_external.string().optional(),
33094
+ session_id: exports_external.string().optional(),
33095
+ limit: exports_external.number().optional()
33126
33096
  }
33127
- }, async ({ space, session_id, limit }) => {
33097
+ }, async (args) => {
33098
+ const { space, session_id, limit } = args;
33128
33099
  const messages = getPinnedMessages({ space, session_id, limit });
33129
33100
  return {
33130
- content: [{ type: "text", text: JSON.stringify(messages, null, 2) }]
33101
+ content: [{ type: "text", text: JSON.stringify(messages) }]
33131
33102
  };
33132
33103
  });
33133
33104
  server.registerTool("heartbeat", {
33134
- title: "Heartbeat",
33135
- description: "Send heartbeat. Optionally set agent status.",
33105
+ description: "Send presence heartbeat.",
33136
33106
  inputSchema: {
33137
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
33138
- status: exports_external.string().optional().describe("Agent status (e.g. 'online', 'busy', 'idle'). Defaults to 'online'.")
33107
+ from: exports_external.string().optional(),
33108
+ status: exports_external.string().optional()
33139
33109
  }
33140
- }, async ({ from: fromParam, status }) => {
33110
+ }, async (args) => {
33111
+ const { from: fromParam, status } = args;
33141
33112
  const agent = resolveIdentity(fromParam);
33142
33113
  heartbeat(agent, status);
33143
33114
  return {
33144
- content: [{ type: "text", text: JSON.stringify({ agent, status: status || "online", heartbeat: true }, null, 2) }]
33115
+ content: [{ type: "text", text: JSON.stringify({ agent, status: status || "online", heartbeat: true }) }]
33145
33116
  };
33146
33117
  });
33147
33118
  server.registerTool("list_agents", {
33148
- title: "List Agents",
33149
33119
  description: "List agents with presence status.",
33150
33120
  inputSchema: {
33151
- online_only: exports_external.boolean().optional().describe("Only return agents online within last 60s")
33121
+ online_only: exports_external.boolean().optional()
33152
33122
  }
33153
- }, async ({ online_only }) => {
33123
+ }, async (args) => {
33124
+ const { online_only } = args;
33154
33125
  const agents = listAgents({ online_only });
33155
33126
  return {
33156
- content: [{ type: "text", text: JSON.stringify(agents, null, 2) }]
33127
+ content: [{ type: "text", text: JSON.stringify(agents) }]
33157
33128
  };
33158
33129
  });
33159
33130
  server.registerTool("get_blockers", {
33160
- title: "Get Blockers",
33161
- description: "Check for unread blocking messages. Must acknowledge.",
33131
+ description: "Check for unread blocking messages.",
33162
33132
  inputSchema: {
33163
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var.")
33133
+ from: exports_external.string().optional()
33164
33134
  }
33165
- }, async ({ from: fromParam }) => {
33135
+ }, async (args) => {
33136
+ const { from: fromParam } = args;
33166
33137
  const agent = resolveIdentity(fromParam);
33167
33138
  const blockers = getUnreadBlockers(agent);
33168
33139
  return {
33169
- content: [{ type: "text", text: JSON.stringify(blockers, null, 2) }]
33140
+ content: [{ type: "text", text: JSON.stringify(blockers) }]
33170
33141
  };
33171
33142
  });
33172
33143
  server.registerTool("remove_agent", {
33173
- title: "Remove Agent",
33174
- description: "Remove an agent from the presence list.",
33144
+ description: "Remove an agent from presence.",
33175
33145
  inputSchema: {
33176
- from: exports_external.string().optional().describe("Your agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
33177
- agent: exports_external.string().optional().describe("Agent to remove (defaults to yourself)")
33146
+ from: exports_external.string().optional(),
33147
+ agent: exports_external.string().optional()
33178
33148
  }
33179
- }, async ({ from: fromParam, agent: targetAgent }) => {
33149
+ }, async (args) => {
33150
+ const { from: fromParam, agent: targetAgent } = args;
33180
33151
  const self = resolveIdentity(fromParam);
33181
33152
  const agent = targetAgent?.trim() || self;
33182
33153
  const removed = removePresence(agent);
@@ -33187,17 +33158,17 @@ var init_mcp2 = __esm(() => {
33187
33158
  };
33188
33159
  }
33189
33160
  return {
33190
- content: [{ type: "text", text: JSON.stringify({ agent, removed: true }, null, 2) }]
33161
+ content: [{ type: "text", text: JSON.stringify({ agent, removed: true }) }]
33191
33162
  };
33192
33163
  });
33193
33164
  server.registerTool("rename_agent", {
33194
- title: "Rename Agent",
33195
- description: "Rename an agent in the presence list.",
33165
+ description: "Rename your agent in presence.",
33196
33166
  inputSchema: {
33197
- from: exports_external.string().optional().describe("Your current agent ID. Falls back to CONVERSATIONS_AGENT_ID env var."),
33198
- new_name: exports_external.string().describe("The new name for the agent")
33167
+ new_name: exports_external.string(),
33168
+ from: exports_external.string().optional()
33199
33169
  }
33200
- }, async ({ from: fromParam, new_name }) => {
33170
+ }, async (args) => {
33171
+ const { from: fromParam, new_name } = args;
33201
33172
  const oldName = resolveIdentity(fromParam);
33202
33173
  const newName = new_name.trim();
33203
33174
  if (!newName) {
@@ -33215,7 +33186,7 @@ var init_mcp2 = __esm(() => {
33215
33186
  };
33216
33187
  }
33217
33188
  return {
33218
- content: [{ type: "text", text: JSON.stringify({ old_name: oldName, new_name: newName, renamed: true }, null, 2) }]
33189
+ content: [{ type: "text", text: JSON.stringify({ old_name: oldName, new_name: newName, renamed: true }) }]
33219
33190
  };
33220
33191
  } catch (e) {
33221
33192
  return {
@@ -33225,12 +33196,12 @@ var init_mcp2 = __esm(() => {
33225
33196
  }
33226
33197
  });
33227
33198
  server.registerTool("search_tools", {
33228
- title: "Search Tools",
33229
- description: "List tool names, optionally filtered by keyword.",
33199
+ description: "List tool names by keyword.",
33230
33200
  inputSchema: {
33231
- query: exports_external.string().optional().describe("Keyword filter")
33201
+ query: exports_external.string().optional()
33232
33202
  }
33233
- }, async ({ query }) => {
33203
+ }, async (args) => {
33204
+ const { query } = args;
33234
33205
  const all = [
33235
33206
  "send_message",
33236
33207
  "read_messages",
@@ -33271,26 +33242,45 @@ var init_mcp2 = __esm(() => {
33271
33242
  return { content: [{ type: "text", text: matches.join(", ") }] };
33272
33243
  });
33273
33244
  server.registerTool("describe_tools", {
33274
- title: "Describe Tools",
33275
- description: "Get descriptions for specific tools by name.",
33245
+ description: "Get descriptions for tools by name.",
33276
33246
  inputSchema: {
33277
- names: exports_external.array(exports_external.string()).describe("Tool names from search_tools")
33247
+ names: exports_external.array(exports_external.string())
33278
33248
  }
33279
33249
  }, async ({ names }) => {
33280
33250
  const descriptions = {
33281
- send_message: "Send DM to agent. Params: to, content, from?, priority?",
33282
- read_messages: "Read messages. Params: space?, from?, to?, unread_only?, limit?",
33283
- list_sessions: "List sessions. Params: agent?",
33284
- reply: "Reply to message. Params: id, content, from?",
33285
- send_to_space: "Send message to space. Params: space, content, from?",
33286
- read_space: "Read space messages. Params: space, limit?, since?",
33287
- join_space: "Join a space. Params: space, from?",
33288
- create_space: "Create space. Params: name, description?, parent_id?",
33289
- list_spaces: "List spaces with counts. No required params.",
33290
- heartbeat: "Send heartbeat. Params: from?, status?",
33291
- list_agents: "List agents with presence. No required params.",
33292
- get_blockers: "Check for blocking messages. Params: name?",
33293
- search_messages: "Search messages. Params: query, space?, limit?"
33251
+ send_message: "Send DM to agent. Required: to, content. Optional: from?, priority?(low|normal|high|urgent), blocking?",
33252
+ read_messages: "Read messages with filters. Optional: session_id?, from?, to?, space?, since?(ISO), limit?, unread_only?",
33253
+ list_sessions: "List all DM sessions. Optional: agent?(filter by participant)",
33254
+ reply: "Reply to a message in same session. Required: message_id, content. Optional: from?",
33255
+ mark_read: "Mark messages as read. Optional: from?, ids?(array), all?(bool \u2014 mark all unread)",
33256
+ search_messages: "Full-text search messages. Required: query. Optional: space?, from?, to?, limit?",
33257
+ export_messages: "Export messages as JSON or CSV. Optional: space?, session_id?, from?, since?, until?, format?(json|csv)",
33258
+ create_space: "Create space and auto-join. Required: name. Optional: from?, description?, parent_id?(max 3 levels), project_id?",
33259
+ list_spaces: "List spaces with member/message counts. Optional: project_id?, parent_id?(use 'null' for top-level), include_archived?",
33260
+ send_to_space: "Post message to space. Required: space, content. Optional: from?, priority?(low|normal|high|urgent), blocking?",
33261
+ read_space: "Read messages in a space. Required: space. Optional: since?(ISO), limit?",
33262
+ join_space: "Join a space. Required: space. Optional: from?",
33263
+ leave_space: "Leave a space. Required: space. Optional: from?",
33264
+ update_space: "Update space fields. Required: name. Optional: description?, parent_id?(use 'null' to remove), project_id?(use 'null' to remove)",
33265
+ archive_space: "Archive a space (hidden from default list). Required: name",
33266
+ unarchive_space: "Restore archived space. Required: name",
33267
+ create_project: "Create a project. Required: name. Optional: from?, description?, path?, repository?, tags?(JSON array), metadata?(JSON), settings?(JSON)",
33268
+ list_projects: "List projects. Optional: status?(active|archived)",
33269
+ get_project: "Get project by UUID or name. Required: id",
33270
+ update_project: "Update project fields. Required: id. Optional: name?, description?, path?, status?(active|archived), repository?, tags?(JSON), metadata?(JSON), settings?(JSON)",
33271
+ delete_project: "Delete project (fails if spaces reference it). Required: id",
33272
+ delete_message: "Delete a message (sender only). Required: id. Optional: from?",
33273
+ edit_message: "Edit message content (sender only). Required: id, content. Optional: from?",
33274
+ pin_message: "Pin a message. Required: id",
33275
+ unpin_message: "Unpin a message. Required: id",
33276
+ get_pinned_messages: "Get pinned messages. Optional: space?, session_id?, limit?",
33277
+ heartbeat: "Register/refresh agent presence. Optional: from?, status?(online|busy|idle, default: online)",
33278
+ list_agents: "List agents with presence timestamps. Optional: online_only?(only agents seen in last 60s)",
33279
+ get_blockers: "Get unread blocking messages for agent. Optional: from?",
33280
+ remove_agent: "Remove agent from presence list. Optional: from?, agent?(defaults to self)",
33281
+ rename_agent: "Rename agent in presence list. Required: new_name. Optional: from?",
33282
+ search_tools: "Search tool names by keyword. Optional: query?",
33283
+ describe_tools: "Get full descriptions for tools. Required: names(array of tool names)"
33294
33284
  };
33295
33285
  const result = names.map((n) => `${n}: ${descriptions[n] || "See tool schema"}`).join(`
33296
33286
  `);
@@ -33331,6 +33321,33 @@ function securityHeaders(base) {
33331
33321
  }
33332
33322
  return headers;
33333
33323
  }
33324
+ function applyFields(data, fields) {
33325
+ if (!fields)
33326
+ return data;
33327
+ const keys = fields.split(",").map((s) => s.trim()).filter(Boolean);
33328
+ if (!keys.length)
33329
+ return data;
33330
+ if (Array.isArray(data)) {
33331
+ return data.map((item) => {
33332
+ if (item && typeof item === "object") {
33333
+ const out = {};
33334
+ for (const k of keys)
33335
+ if (k in item)
33336
+ out[k] = item[k];
33337
+ return out;
33338
+ }
33339
+ return item;
33340
+ });
33341
+ }
33342
+ if (data && typeof data === "object") {
33343
+ const out = {};
33344
+ for (const k of keys)
33345
+ if (k in data)
33346
+ out[k] = data[k];
33347
+ return out;
33348
+ }
33349
+ return data;
33350
+ }
33334
33351
  function jsonResponse(data, status = 200) {
33335
33352
  return new Response(JSON.stringify(data), {
33336
33353
  status,
@@ -33403,8 +33420,9 @@ function startDashboardServer(port = 0, host) {
33403
33420
  const space = url2.searchParams.get("space") || undefined;
33404
33421
  const from = url2.searchParams.get("from") || undefined;
33405
33422
  const to = url2.searchParams.get("to") || undefined;
33406
- const messages = readMessages({ session_id: session, space, from, to, limit, order: "desc" });
33407
- return jsonResponse(messages);
33423
+ const compact = url2.searchParams.get("compact") === "true";
33424
+ const messages = readMessages({ session_id: session, space, from, to, limit, order: "desc", compact });
33425
+ return jsonResponse(applyFields(messages, url2.searchParams.get("fields")));
33408
33426
  }
33409
33427
  if (path === "/api/messages" && req.method === "POST") {
33410
33428
  if (!isSameOrigin(req)) {
@@ -33549,7 +33567,7 @@ function startDashboardServer(port = 0, host) {
33549
33567
  }
33550
33568
  if (path === "/api/sessions") {
33551
33569
  const agent = url2.searchParams.get("agent") || undefined;
33552
- return jsonResponse(listSessions(agent));
33570
+ return jsonResponse(applyFields(listSessions(agent), url2.searchParams.get("fields")));
33553
33571
  }
33554
33572
  if (path === "/api/spaces" && req.method === "GET") {
33555
33573
  const projectId = url2.searchParams.get("project_id") || undefined;
@@ -33559,7 +33577,7 @@ function startDashboardServer(port = 0, host) {
33559
33577
  listOpts.project_id = projectId;
33560
33578
  if (includeArchived)
33561
33579
  listOpts.include_archived = true;
33562
- return jsonResponse(listSpaces(Object.keys(listOpts).length > 0 ? listOpts : undefined));
33580
+ return jsonResponse(applyFields(listSpaces(Object.keys(listOpts).length > 0 ? listOpts : undefined), url2.searchParams.get("fields")));
33563
33581
  }
33564
33582
  if (path === "/api/spaces" && req.method === "POST") {
33565
33583
  if (!isSameOrigin(req)) {
@@ -33638,7 +33656,7 @@ function startDashboardServer(port = 0, host) {
33638
33656
  }
33639
33657
  if (path === "/api/projects" && req.method === "GET") {
33640
33658
  const status = url2.searchParams.get("status");
33641
- return jsonResponse(listProjects(status ? { status } : undefined));
33659
+ return jsonResponse(applyFields(listProjects(status ? { status } : undefined), url2.searchParams.get("fields")));
33642
33660
  }
33643
33661
  if (path === "/api/projects" && req.method === "POST") {
33644
33662
  if (!isSameOrigin(req)) {
@@ -33708,7 +33726,7 @@ function startDashboardServer(port = 0, host) {
33708
33726
  if (path === "/api/agents" && req.method === "GET") {
33709
33727
  const onlineOnly = url2.searchParams.get("online_only") === "true";
33710
33728
  const agents = listAgents({ online_only: onlineOnly });
33711
- return jsonResponse(agents);
33729
+ return jsonResponse(applyFields(agents, url2.searchParams.get("fields")));
33712
33730
  }
33713
33731
  if (path === "/api/version" && req.method === "GET") {
33714
33732
  try {