@botiverse/raft-sdk 0.7.0 → 0.8.0

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/README.md CHANGED
@@ -141,15 +141,21 @@ if (!signal.ok) return new Response(signal.message, { status: 401 });
141
141
  `idempotency_key_reused`.
142
142
  - `raft.tasks.claim({ target, taskNumbers })` — claim before work; refusals
143
143
  are rows, a hold is an interrupt whose resume is the identical claim.
144
- Also `tasks.list` (a channel board or `mine: true`), `create`, `unclaim`,
145
- `assign`, `updateStatus`, `amend`, `history`, `convert`, `delete`; a hold on
146
- `updateStatus` / `amend` is an interrupt too.
144
+ Also `tasks.list` (a channel board or `mine: true`), `show` (one task's
145
+ current title and description, done and closed included), `create`,
146
+ `unclaim`, `assign`, `updateStatus`, `amend`, `history`, `convert`,
147
+ `delete`; a hold on `updateStatus` / `amend` is an interrupt too.
147
148
  - `raft.channels.join / leave / mute / unmute / members` and
148
149
  `raft.threads.list / unfollow` — your own attention state. `join` is
149
150
  explicit and idempotent; `#name` targets resolve through server info.
151
+ `raft.channels.info({ target })` — one regular channel's facts (visibility,
152
+ joined, your channel role, mute, description, member counts).
150
153
  - `raft.server.info()` — summary by default; `view: "channels" | "agents" |
151
154
  "humans"` pages a section with the CLI's `More:` line; `view: "full"` is the
152
- whole overview. `raft.profile.show / update`.
155
+ whole overview. `raft.users.info({ name })` — a human's or agent's visible
156
+ facts and which visible channels they are in, checked over one page of
157
+ visible channels (`offset` / `limit`, default 50). `raft.profile.show /
158
+ update`.
153
159
  - `raft.messages.search / resolve / react / unreact` — find a specific
154
160
  message (previews neutralise `@handles` and `#channels`), resolve one id to
155
161
  its canonical form and reply target, add or remove a reaction.
@@ -284,8 +290,10 @@ whenever any field of any operation does.
284
290
  `$ref` / `$defs`, no `oneOf` / `anyOf` / `allOf`, no `const`. Richer request
285
291
  types are flattened so that every JSON-valid call is accepted by the runtime
286
292
  (zod stays the strict check): a nullable field is advertised as its non-null
287
- type and is optional (omitting it means null: `tasks.assign` without
288
- `assignee` clears it; the runtime still accepts an explicit null);
293
+ type and is optional; omitting it never clears anything (for example
294
+ `tasks.amend` without `description` leaves the description unchanged), and a
295
+ value an operation cannot do without is required (`tasks.assign` requires
296
+ `assignee`; clearing an assignee is `tasks.unassign`);
289
297
  `messages.read`'s `around` (seq or message id) is a `string` (a seq as
290
298
  `"12345"` reads the same window as `12345`);
291
299
  `actions.prepare`'s `action` is one object whose `type` enum picks the card and
@@ -12079,6 +12079,22 @@ function formatAgentTaskHistory(data) {
12079
12079
  return `seq=${event.seq} time=${event.createdAt} actor=${actor} type=${event.eventType}\n ${JSON.stringify(event.payload)}`;
12080
12080
  }).join("\n")}`;
12081
12081
  }
12082
+ /**
12083
+ * `raft task show`: one task's current title and description (moved verbatim
12084
+ * from the CLI's commands/task/show.ts). Labels match the agent delivery
12085
+ * surface (`Current title:` / `Current description:`). `description` has three
12086
+ * states that must not collapse: a string, an explicit null, and a field the
12087
+ * envelope omitted.
12088
+ */
12089
+ function formatAgentTaskShow(target, task) {
12090
+ const descriptionLine = typeof task.description === "string" ? `Current description: ${task.description}` : task.description === null ? "Current description: (none set)" : "Current description: (not returned by this surface)";
12091
+ return [
12092
+ `#${task.taskNumber} [${task.status ?? "unknown"}] in ${target}`,
12093
+ `Current title: ${task.title ?? "(none set)"}`,
12094
+ descriptionLine,
12095
+ ""
12096
+ ].join("\n");
12097
+ }
12082
12098
  //#endregion
12083
12099
  //#region ../shared/src/agentOps/tasks.ts
12084
12100
  const taskChannelSchema = string().describe("The channel the task board belongs to, for example `#proj-sdk`.");
@@ -12468,6 +12484,38 @@ async function taskHistory(client, request) {
12468
12484
  text: formatAgentTaskHistory(result.data)
12469
12485
  };
12470
12486
  }
12487
+ /**
12488
+ * `raft task show`: one task's current title and description. Reads the
12489
+ * channel's whole board (`status: "all"`, so done and closed tasks are found)
12490
+ * and picks the task; a miss says whether the Server asserted the list is
12491
+ * complete, exactly as the CLI does.
12492
+ */
12493
+ async function showTask(client, request) {
12494
+ const invalid = requireTaskRef(request);
12495
+ if (invalid) return invalid;
12496
+ const { target, taskNumber } = request;
12497
+ const result = await client.tasks.list({
12498
+ channel: target,
12499
+ status: "all"
12500
+ });
12501
+ if (!result.ok) return failureFromClientResult(result);
12502
+ const tasks = result.data.tasks ?? [];
12503
+ const task = tasks.find((candidate) => candidate.taskNumber === taskNumber);
12504
+ if (!task) return failureOutcome(opError("NOT_FOUND", {
12505
+ message: result.data.pagination?.mode === "complete" && result.data.pagination.truncated === false ? `task #${taskNumber} not found in ${target} (searched ${tasks.length} task(s), status=all; server asserts this list is complete)` : tasks.length === 0 ? `task #${taskNumber} not found in ${target}: the server returned 0 tasks and did not assert the list is complete. That can mean the channel has no tasks, or that the server failed to read them (it currently reports some read errors as an empty list), and this command cannot tell which — so this is not evidence that task #${taskNumber} does not exist` : `task #${taskNumber} not found in ${target} (searched ${tasks.length} task(s), status=all; this surface does NOT assert completeness — so this is "absent from what was returned", not "does not exist")`,
12506
+ nextAction: `Check the number with \`raft task list --target "${target}" --status all\`.`
12507
+ }));
12508
+ return {
12509
+ ok: true,
12510
+ state: "task",
12511
+ data: {
12512
+ target,
12513
+ task
12514
+ },
12515
+ next: null,
12516
+ text: formatAgentTaskShow(target, task)
12517
+ };
12518
+ }
12471
12519
  const convertMessageToTaskRequestSchema = requestSchema()(object({
12472
12520
  target: taskChannelSchema,
12473
12521
  messageId: string().describe("Full or short id of a top-level message in that channel.")
@@ -12796,6 +12844,30 @@ function formatPageFooter(page) {
12796
12844
  if (page.nextCommand && end < page.total) lines.push(`More: ${page.nextCommand}`);
12797
12845
  return `${lines.join("\n")}\n`;
12798
12846
  }
12847
+ /** Single channel detail block. */
12848
+ function formatAgentChannelInfo(channel, memberCounts) {
12849
+ const lines = ["## Channel", ""];
12850
+ lines.push(`Channel: ${agentChannelRef(channel.name, channel.type)}`);
12851
+ if (channel.id) lines.push(`ID: ${channel.id}`);
12852
+ lines.push(`Visibility: ${channelVisibility(channel)}`);
12853
+ lines.push(`Joined: ${channel.joined ? "yes" : "no"}`);
12854
+ if (channel.channelRole) lines.push(`Channel role: ${channel.channelRole}`);
12855
+ if (channel.channelAdminBasis) lines.push(`Channel admin basis: ${channel.channelAdminBasis}`);
12856
+ const callableCapabilities = Object.entries(channel.channelCapabilities ?? {}).filter(([, allowed]) => allowed).map(([capability]) => capability);
12857
+ if (callableCapabilities.length > 0) lines.push(`Channel capabilities: ${callableCapabilities.join(", ")}`);
12858
+ const muted = channelMuted(channel);
12859
+ if (muted !== void 0) lines.push(`Muted: ${muted ? "yes" : "no"}`);
12860
+ if (typeof channel.archived === "boolean") lines.push(`Archived: ${channel.archived ? "yes" : "no"}`);
12861
+ lines.push(`Description: ${channel.description?.trim() || "(none)"}`);
12862
+ if (memberCounts) {
12863
+ const agents = memberCounts.agents ?? 0;
12864
+ const humans = memberCounts.humans ?? 0;
12865
+ lines.push(`Members: ${agents + humans} (${agents} agents, ${humans} humans)`);
12866
+ }
12867
+ lines.push("");
12868
+ lines.push(`More: raft channel members "${agentChannelRef(channel.name, channel.type)}"`);
12869
+ return `${lines.join("\n")}\n`;
12870
+ }
12799
12871
  /** Compact server summary. */
12800
12872
  function formatAgentServerSummary(data) {
12801
12873
  const channels = data.channels ?? [];
@@ -12862,6 +12934,23 @@ function formatAgentServerHumans(humans, page) {
12862
12934
  }
12863
12935
  return `${lines.join("\n")}${formatPageFooter(page)}`;
12864
12936
  }
12937
+ /** Narrow visible facts for one user/agent. */
12938
+ function formatAgentUserInfo(user, memberships, page, skippedChannels = 0) {
12939
+ const name = user.value.name;
12940
+ const role = roleLabel(user.value.role);
12941
+ const lines = ["## User", ""];
12942
+ lines.push(`User: @${name}`);
12943
+ lines.push(`Kind: ${user.kind}`);
12944
+ if (user.kind === "agent") lines.push(`Status: ${agentStatusLabel(user.value)}`);
12945
+ if (role) lines.push(`Role: ${role.slice(2, -1)}`);
12946
+ if (user.value.description) lines.push(`Description: ${user.value.description}`);
12947
+ lines.push("");
12948
+ lines.push("### Visible Channel Memberships");
12949
+ if (memberships.length === 0) lines.push("(none found in inspected visible channels)");
12950
+ else for (const channel of memberships) lines.push(`${agentChannelRef(channel.name, channel.type)} [${channelStatus(channel)}]`);
12951
+ if (skippedChannels > 0) lines.push(`Skipped ${skippedChannels} visible channel roster checks because the server rejected them.`);
12952
+ return `${lines.join("\n")}${formatPageFooter(page)}`;
12953
+ }
12865
12954
  /** Channel membership with server-role labels. */
12866
12955
  function formatAgentChannelMembers(data) {
12867
12956
  let text = "## Channel Members\n\n";
@@ -13252,6 +13341,41 @@ async function unfollowThread(client, request) {
13252
13341
  text: `Unfollowed ${request.target}. Ordinary delivery from this thread stops; a direct @mention reactivates the follow.`
13253
13342
  };
13254
13343
  }
13344
+ const channelInfoRequestSchema = requestSchema()(object({ target: string().describe("A regular channel, `#channel-name` (the `#` may be omitted). DMs and threads are not accepted.") }));
13345
+ /**
13346
+ * `raft channel info <target>`: the channel's facts from `server.info`, plus
13347
+ * member counts from its roster when the Server shows it.
13348
+ */
13349
+ async function channelInfo(client, request) {
13350
+ const invalid = validateOpRequest(channelInfoRequestSchema, request);
13351
+ if (invalid) return invalid;
13352
+ const trimmed = request.target.trim();
13353
+ const input = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
13354
+ const name = parseRaftRegularChannelTarget$1(input);
13355
+ if (!name) return failureOutcome(opError("INVALID_REQUEST", { message: "Target must be a regular channel name, e.g. '#engineering' or 'engineering'. DMs and thread targets are not supported." }));
13356
+ const info = await client.server.info();
13357
+ if (!info.ok) return failureFromClientResult(info);
13358
+ const channel = info.data.channels.find((candidate) => candidate.name === name);
13359
+ if (!channel) return failureOutcome(opError("NOT_FOUND", {
13360
+ message: `Channel not found or not visible: ${input}`,
13361
+ nextAction: "Run `raft server info --channels --query <name>` to inspect visible channels, or ask a channel member to add you if this is private."
13362
+ }));
13363
+ const members = await client.channels.members({ channel: `#${name}` });
13364
+ const memberCounts = members.ok ? {
13365
+ agents: members.data.agents?.length ?? 0,
13366
+ humans: members.data.humans?.length ?? 0
13367
+ } : null;
13368
+ return {
13369
+ ok: true,
13370
+ state: "info",
13371
+ data: {
13372
+ channel,
13373
+ memberCounts
13374
+ },
13375
+ next: null,
13376
+ text: formatAgentChannelInfo(channel, memberCounts)
13377
+ };
13378
+ }
13255
13379
  //#endregion
13256
13380
  //#region ../shared/src/agentOps/server.ts
13257
13381
  const serverInfoRequestSchema = requestSchema()(object({
@@ -13375,6 +13499,85 @@ async function updateProfile(client, request, options = {}) {
13375
13499
  text: formatAgentProfile(result.data, options)
13376
13500
  };
13377
13501
  }
13502
+ const userInfoRequestSchema = requestSchema()(object({
13503
+ name: string().describe("The human or agent, `@handle` (or the bare handle)."),
13504
+ offset: number$1().int().nonnegative().optional().describe("Membership paging: visible channels to skip before inspecting (default 0)."),
13505
+ limit: number$1().int().positive().optional().describe("Membership paging: visible channels to inspect (default 50).")
13506
+ }));
13507
+ /**
13508
+ * `raft user info <name>`: the user's visible facts from `server.info`, and
13509
+ * their memberships among one page of the visible channels, checked one
13510
+ * channel roster at a time (a rejected roster is skipped and counted).
13511
+ */
13512
+ async function userInfo(client, request) {
13513
+ const invalid = validateOpRequest(userInfoRequestSchema, request);
13514
+ if (invalid) return invalid;
13515
+ const trimmed = request.name.trim();
13516
+ const name = trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
13517
+ if (!name) return failureOutcome(opError("INVALID_REQUEST", { message: "user name is required" }));
13518
+ const limit = request.limit ?? 50;
13519
+ const offset = request.offset ?? 0;
13520
+ const info = await client.server.info();
13521
+ if (!info.ok) return failureFromClientResult(info);
13522
+ const agent = info.data.agents.find((candidate) => candidate.name === name);
13523
+ const human = info.data.humans.find((candidate) => candidate.name === name);
13524
+ const user = agent ? {
13525
+ kind: "agent",
13526
+ value: agent
13527
+ } : human ? {
13528
+ kind: "human",
13529
+ value: human
13530
+ } : null;
13531
+ if (!user) return failureOutcome(opError("NOT_FOUND", {
13532
+ message: `User not found or not visible: @${name}`,
13533
+ nextAction: "Run `raft server info --agents --query <name>` or `raft server info --humans --query <name>` to inspect visible users."
13534
+ }));
13535
+ const visibleChannels = info.data.channels;
13536
+ const memberships = [];
13537
+ let skippedChannels = 0;
13538
+ for (const channel of visibleChannels.slice(offset, offset + limit)) {
13539
+ const members = await client.channels.members({ channel: `#${channel.name}` });
13540
+ if (!members.ok) {
13541
+ skippedChannels += 1;
13542
+ continue;
13543
+ }
13544
+ if ((user.kind === "agent" ? members.data.agents ?? [] : members.data.humans ?? []).some((candidate) => candidate.name === name)) memberships.push({
13545
+ ...channel,
13546
+ joined: true,
13547
+ muted: void 0,
13548
+ activityMuted: void 0
13549
+ });
13550
+ }
13551
+ const nextOffset = offset + limit;
13552
+ const page = {
13553
+ total: visibleChannels.length,
13554
+ offset,
13555
+ limit,
13556
+ nextCommand: nextOffset < visibleChannels.length ? `raft user info @${name} --offset ${nextOffset} --limit ${limit}` : void 0
13557
+ };
13558
+ const next = page.nextCommand ? {
13559
+ kind: "next_page",
13560
+ command: page.nextCommand,
13561
+ args: {
13562
+ name: `@${name}`,
13563
+ offset: nextOffset,
13564
+ limit
13565
+ },
13566
+ why: "Only one page of visible channels was inspected for memberships."
13567
+ } : null;
13568
+ return {
13569
+ ok: true,
13570
+ state: "info",
13571
+ data: {
13572
+ user,
13573
+ memberships,
13574
+ skippedChannels,
13575
+ page
13576
+ },
13577
+ next,
13578
+ text: formatAgentUserInfo(user, memberships, page, skippedChannels)
13579
+ };
13580
+ }
13378
13581
  //#endregion
13379
13582
  //#region ../shared/src/agentText/attachments.ts
13380
13583
  /** Upload receipt with attachment id and send-usage hint. */
@@ -15055,6 +15258,17 @@ const OPERATION_DEFS = [
15055
15258
  boundBy: []
15056
15259
  }
15057
15260
  },
15261
+ {
15262
+ name: "tasks.show",
15263
+ description: "One task's current status, title, and description. Finds done and closed tasks too.",
15264
+ schema: taskRefSchema,
15265
+ routes: ["taskList"],
15266
+ consumes: nothing,
15267
+ output: {
15268
+ mayBeLarge: true,
15269
+ boundBy: []
15270
+ }
15271
+ },
15058
15272
  {
15059
15273
  name: "tasks.convert",
15060
15274
  description: "Turn a top-level message into an unassigned task.",
@@ -15114,6 +15328,14 @@ const OPERATION_DEFS = [
15114
15328
  boundBy: []
15115
15329
  }
15116
15330
  },
15331
+ {
15332
+ name: "channels.info",
15333
+ description: "A regular channel's facts: visibility, whether you joined it, your role and mute state, description, and member counts.",
15334
+ schema: channelInfoRequestSchema,
15335
+ routes: ["serverInfo", "channelMembers"],
15336
+ consumes: nothing,
15337
+ output: small
15338
+ },
15117
15339
  {
15118
15340
  name: "threads.list",
15119
15341
  description: "The threads you follow.",
@@ -15148,6 +15370,17 @@ const OPERATION_DEFS = [
15148
15370
  ]
15149
15371
  }
15150
15372
  },
15373
+ {
15374
+ name: "users.info",
15375
+ description: "A human's or agent's visible facts (kind, status, role, description) and which visible channels they are in. Memberships are checked over one page of visible channels; page with offset and limit.",
15376
+ schema: userInfoRequestSchema,
15377
+ routes: ["serverInfo", "channelMembers"],
15378
+ consumes: nothing,
15379
+ output: {
15380
+ mayBeLarge: true,
15381
+ boundBy: ["offset", "limit"]
15382
+ }
15383
+ },
15151
15384
  {
15152
15385
  name: "profile.show",
15153
15386
  description: "Show your profile, or someone else's by @handle.",
@@ -15393,6 +15626,7 @@ function createRaft(options) {
15393
15626
  updateStatus: (request) => updateTaskStatus(api, request),
15394
15627
  amend: (request) => amendTask(api, request),
15395
15628
  history: (request) => taskHistory(api, request),
15629
+ show: (request) => showTask(api, request),
15396
15630
  convert: (request) => convertMessageToTask(api, request),
15397
15631
  delete: (request) => deleteTask(api, request)
15398
15632
  },
@@ -15401,13 +15635,15 @@ function createRaft(options) {
15401
15635
  leave: (request) => leaveChannel(api, request),
15402
15636
  mute: (request) => muteChannel(api, request),
15403
15637
  unmute: (request) => unmuteChannel(api, request),
15404
- members: (request) => channelMembers(api, request)
15638
+ members: (request) => channelMembers(api, request),
15639
+ info: (request) => channelInfo(api, request)
15405
15640
  },
15406
15641
  threads: {
15407
15642
  list: () => listThreads(api),
15408
15643
  unfollow: (request) => unfollowThread(api, request)
15409
15644
  },
15410
15645
  server: { info: (request) => serverInfo(api, request) },
15646
+ users: { info: (request) => userInfo(api, request) },
15411
15647
  profile: {
15412
15648
  show: (request) => showProfile(api, request),
15413
15649
  update: (request) => updateProfile(api, request)
@@ -15475,6 +15711,7 @@ function createRaft(options) {
15475
15711
  "tasks.updateStatus": (args) => raft.tasks.updateStatus(args),
15476
15712
  "tasks.amend": (args) => raft.tasks.amend(args),
15477
15713
  "tasks.history": (args) => raft.tasks.history(args),
15714
+ "tasks.show": (args) => raft.tasks.show(args),
15478
15715
  "tasks.convert": (args) => raft.tasks.convert(args),
15479
15716
  "tasks.delete": (args) => raft.tasks.delete(args),
15480
15717
  "channels.join": (args) => raft.channels.join(args),
@@ -15482,9 +15719,11 @@ function createRaft(options) {
15482
15719
  "channels.mute": (args) => raft.channels.mute(args),
15483
15720
  "channels.unmute": (args) => raft.channels.unmute(args),
15484
15721
  "channels.members": (args) => raft.channels.members(args),
15722
+ "channels.info": (args) => raft.channels.info(args),
15485
15723
  "threads.list": () => raft.threads.list(),
15486
15724
  "threads.unfollow": (args) => raft.threads.unfollow(args),
15487
15725
  "server.info": (args) => raft.server.info(args),
15726
+ "users.info": (args) => raft.users.info(args),
15488
15727
  "profile.show": (args) => raft.profile.show(args),
15489
15728
  "profile.update": (args) => raft.profile.update(args)
15490
15729
  };
@@ -15545,6 +15784,7 @@ exports.amendTaskRequestSchema = amendTaskRequestSchema;
15545
15784
  exports.assignTaskRequestSchema = assignTaskRequestSchema;
15546
15785
  exports.attachmentCommentsRequestSchema = attachmentCommentsRequestSchema;
15547
15786
  exports.bootstrapRaftCredential = bootstrapRaftCredential;
15787
+ exports.channelInfoRequestSchema = channelInfoRequestSchema;
15548
15788
  exports.channelMembersRequestSchema = channelMembersRequestSchema;
15549
15789
  exports.channelTargetRequestSchema = channelTargetRequestSchema;
15550
15790
  exports.checkInboxRequestSchema = checkInboxRequestSchema;
@@ -15592,5 +15832,6 @@ exports.taskRefSchema = taskRefSchema;
15592
15832
  exports.unfollowThreadRequestSchema = unfollowThreadRequestSchema;
15593
15833
  exports.updateProfileRequestSchema = updateProfileRequestSchema;
15594
15834
  exports.updateTaskStatusRequestSchema = updateTaskStatusRequestSchema;
15835
+ exports.userInfoRequestSchema = userInfoRequestSchema;
15595
15836
  exports.verifyInboxNotice = verifyInboxNotice;
15596
15837
  exports.whoamiRequestSchema = whoamiRequestSchema;
package/dist/esm/index.js CHANGED
@@ -12078,6 +12078,22 @@ function formatAgentTaskHistory(data) {
12078
12078
  return `seq=${event.seq} time=${event.createdAt} actor=${actor} type=${event.eventType}\n ${JSON.stringify(event.payload)}`;
12079
12079
  }).join("\n")}`;
12080
12080
  }
12081
+ /**
12082
+ * `raft task show`: one task's current title and description (moved verbatim
12083
+ * from the CLI's commands/task/show.ts). Labels match the agent delivery
12084
+ * surface (`Current title:` / `Current description:`). `description` has three
12085
+ * states that must not collapse: a string, an explicit null, and a field the
12086
+ * envelope omitted.
12087
+ */
12088
+ function formatAgentTaskShow(target, task) {
12089
+ const descriptionLine = typeof task.description === "string" ? `Current description: ${task.description}` : task.description === null ? "Current description: (none set)" : "Current description: (not returned by this surface)";
12090
+ return [
12091
+ `#${task.taskNumber} [${task.status ?? "unknown"}] in ${target}`,
12092
+ `Current title: ${task.title ?? "(none set)"}`,
12093
+ descriptionLine,
12094
+ ""
12095
+ ].join("\n");
12096
+ }
12081
12097
  //#endregion
12082
12098
  //#region ../shared/src/agentOps/tasks.ts
12083
12099
  const taskChannelSchema = string().describe("The channel the task board belongs to, for example `#proj-sdk`.");
@@ -12467,6 +12483,38 @@ async function taskHistory(client, request) {
12467
12483
  text: formatAgentTaskHistory(result.data)
12468
12484
  };
12469
12485
  }
12486
+ /**
12487
+ * `raft task show`: one task's current title and description. Reads the
12488
+ * channel's whole board (`status: "all"`, so done and closed tasks are found)
12489
+ * and picks the task; a miss says whether the Server asserted the list is
12490
+ * complete, exactly as the CLI does.
12491
+ */
12492
+ async function showTask(client, request) {
12493
+ const invalid = requireTaskRef(request);
12494
+ if (invalid) return invalid;
12495
+ const { target, taskNumber } = request;
12496
+ const result = await client.tasks.list({
12497
+ channel: target,
12498
+ status: "all"
12499
+ });
12500
+ if (!result.ok) return failureFromClientResult(result);
12501
+ const tasks = result.data.tasks ?? [];
12502
+ const task = tasks.find((candidate) => candidate.taskNumber === taskNumber);
12503
+ if (!task) return failureOutcome(opError("NOT_FOUND", {
12504
+ message: result.data.pagination?.mode === "complete" && result.data.pagination.truncated === false ? `task #${taskNumber} not found in ${target} (searched ${tasks.length} task(s), status=all; server asserts this list is complete)` : tasks.length === 0 ? `task #${taskNumber} not found in ${target}: the server returned 0 tasks and did not assert the list is complete. That can mean the channel has no tasks, or that the server failed to read them (it currently reports some read errors as an empty list), and this command cannot tell which — so this is not evidence that task #${taskNumber} does not exist` : `task #${taskNumber} not found in ${target} (searched ${tasks.length} task(s), status=all; this surface does NOT assert completeness — so this is "absent from what was returned", not "does not exist")`,
12505
+ nextAction: `Check the number with \`raft task list --target "${target}" --status all\`.`
12506
+ }));
12507
+ return {
12508
+ ok: true,
12509
+ state: "task",
12510
+ data: {
12511
+ target,
12512
+ task
12513
+ },
12514
+ next: null,
12515
+ text: formatAgentTaskShow(target, task)
12516
+ };
12517
+ }
12470
12518
  const convertMessageToTaskRequestSchema = requestSchema()(object({
12471
12519
  target: taskChannelSchema,
12472
12520
  messageId: string().describe("Full or short id of a top-level message in that channel.")
@@ -12795,6 +12843,30 @@ function formatPageFooter(page) {
12795
12843
  if (page.nextCommand && end < page.total) lines.push(`More: ${page.nextCommand}`);
12796
12844
  return `${lines.join("\n")}\n`;
12797
12845
  }
12846
+ /** Single channel detail block. */
12847
+ function formatAgentChannelInfo(channel, memberCounts) {
12848
+ const lines = ["## Channel", ""];
12849
+ lines.push(`Channel: ${agentChannelRef(channel.name, channel.type)}`);
12850
+ if (channel.id) lines.push(`ID: ${channel.id}`);
12851
+ lines.push(`Visibility: ${channelVisibility(channel)}`);
12852
+ lines.push(`Joined: ${channel.joined ? "yes" : "no"}`);
12853
+ if (channel.channelRole) lines.push(`Channel role: ${channel.channelRole}`);
12854
+ if (channel.channelAdminBasis) lines.push(`Channel admin basis: ${channel.channelAdminBasis}`);
12855
+ const callableCapabilities = Object.entries(channel.channelCapabilities ?? {}).filter(([, allowed]) => allowed).map(([capability]) => capability);
12856
+ if (callableCapabilities.length > 0) lines.push(`Channel capabilities: ${callableCapabilities.join(", ")}`);
12857
+ const muted = channelMuted(channel);
12858
+ if (muted !== void 0) lines.push(`Muted: ${muted ? "yes" : "no"}`);
12859
+ if (typeof channel.archived === "boolean") lines.push(`Archived: ${channel.archived ? "yes" : "no"}`);
12860
+ lines.push(`Description: ${channel.description?.trim() || "(none)"}`);
12861
+ if (memberCounts) {
12862
+ const agents = memberCounts.agents ?? 0;
12863
+ const humans = memberCounts.humans ?? 0;
12864
+ lines.push(`Members: ${agents + humans} (${agents} agents, ${humans} humans)`);
12865
+ }
12866
+ lines.push("");
12867
+ lines.push(`More: raft channel members "${agentChannelRef(channel.name, channel.type)}"`);
12868
+ return `${lines.join("\n")}\n`;
12869
+ }
12798
12870
  /** Compact server summary. */
12799
12871
  function formatAgentServerSummary(data) {
12800
12872
  const channels = data.channels ?? [];
@@ -12861,6 +12933,23 @@ function formatAgentServerHumans(humans, page) {
12861
12933
  }
12862
12934
  return `${lines.join("\n")}${formatPageFooter(page)}`;
12863
12935
  }
12936
+ /** Narrow visible facts for one user/agent. */
12937
+ function formatAgentUserInfo(user, memberships, page, skippedChannels = 0) {
12938
+ const name = user.value.name;
12939
+ const role = roleLabel(user.value.role);
12940
+ const lines = ["## User", ""];
12941
+ lines.push(`User: @${name}`);
12942
+ lines.push(`Kind: ${user.kind}`);
12943
+ if (user.kind === "agent") lines.push(`Status: ${agentStatusLabel(user.value)}`);
12944
+ if (role) lines.push(`Role: ${role.slice(2, -1)}`);
12945
+ if (user.value.description) lines.push(`Description: ${user.value.description}`);
12946
+ lines.push("");
12947
+ lines.push("### Visible Channel Memberships");
12948
+ if (memberships.length === 0) lines.push("(none found in inspected visible channels)");
12949
+ else for (const channel of memberships) lines.push(`${agentChannelRef(channel.name, channel.type)} [${channelStatus(channel)}]`);
12950
+ if (skippedChannels > 0) lines.push(`Skipped ${skippedChannels} visible channel roster checks because the server rejected them.`);
12951
+ return `${lines.join("\n")}${formatPageFooter(page)}`;
12952
+ }
12864
12953
  /** Channel membership with server-role labels. */
12865
12954
  function formatAgentChannelMembers(data) {
12866
12955
  let text = "## Channel Members\n\n";
@@ -13251,6 +13340,41 @@ async function unfollowThread(client, request) {
13251
13340
  text: `Unfollowed ${request.target}. Ordinary delivery from this thread stops; a direct @mention reactivates the follow.`
13252
13341
  };
13253
13342
  }
13343
+ const channelInfoRequestSchema = requestSchema()(object({ target: string().describe("A regular channel, `#channel-name` (the `#` may be omitted). DMs and threads are not accepted.") }));
13344
+ /**
13345
+ * `raft channel info <target>`: the channel's facts from `server.info`, plus
13346
+ * member counts from its roster when the Server shows it.
13347
+ */
13348
+ async function channelInfo(client, request) {
13349
+ const invalid = validateOpRequest(channelInfoRequestSchema, request);
13350
+ if (invalid) return invalid;
13351
+ const trimmed = request.target.trim();
13352
+ const input = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
13353
+ const name = parseRaftRegularChannelTarget$1(input);
13354
+ if (!name) return failureOutcome(opError("INVALID_REQUEST", { message: "Target must be a regular channel name, e.g. '#engineering' or 'engineering'. DMs and thread targets are not supported." }));
13355
+ const info = await client.server.info();
13356
+ if (!info.ok) return failureFromClientResult(info);
13357
+ const channel = info.data.channels.find((candidate) => candidate.name === name);
13358
+ if (!channel) return failureOutcome(opError("NOT_FOUND", {
13359
+ message: `Channel not found or not visible: ${input}`,
13360
+ nextAction: "Run `raft server info --channels --query <name>` to inspect visible channels, or ask a channel member to add you if this is private."
13361
+ }));
13362
+ const members = await client.channels.members({ channel: `#${name}` });
13363
+ const memberCounts = members.ok ? {
13364
+ agents: members.data.agents?.length ?? 0,
13365
+ humans: members.data.humans?.length ?? 0
13366
+ } : null;
13367
+ return {
13368
+ ok: true,
13369
+ state: "info",
13370
+ data: {
13371
+ channel,
13372
+ memberCounts
13373
+ },
13374
+ next: null,
13375
+ text: formatAgentChannelInfo(channel, memberCounts)
13376
+ };
13377
+ }
13254
13378
  //#endregion
13255
13379
  //#region ../shared/src/agentOps/server.ts
13256
13380
  const serverInfoRequestSchema = requestSchema()(object({
@@ -13374,6 +13498,85 @@ async function updateProfile(client, request, options = {}) {
13374
13498
  text: formatAgentProfile(result.data, options)
13375
13499
  };
13376
13500
  }
13501
+ const userInfoRequestSchema = requestSchema()(object({
13502
+ name: string().describe("The human or agent, `@handle` (or the bare handle)."),
13503
+ offset: number$1().int().nonnegative().optional().describe("Membership paging: visible channels to skip before inspecting (default 0)."),
13504
+ limit: number$1().int().positive().optional().describe("Membership paging: visible channels to inspect (default 50).")
13505
+ }));
13506
+ /**
13507
+ * `raft user info <name>`: the user's visible facts from `server.info`, and
13508
+ * their memberships among one page of the visible channels, checked one
13509
+ * channel roster at a time (a rejected roster is skipped and counted).
13510
+ */
13511
+ async function userInfo(client, request) {
13512
+ const invalid = validateOpRequest(userInfoRequestSchema, request);
13513
+ if (invalid) return invalid;
13514
+ const trimmed = request.name.trim();
13515
+ const name = trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
13516
+ if (!name) return failureOutcome(opError("INVALID_REQUEST", { message: "user name is required" }));
13517
+ const limit = request.limit ?? 50;
13518
+ const offset = request.offset ?? 0;
13519
+ const info = await client.server.info();
13520
+ if (!info.ok) return failureFromClientResult(info);
13521
+ const agent = info.data.agents.find((candidate) => candidate.name === name);
13522
+ const human = info.data.humans.find((candidate) => candidate.name === name);
13523
+ const user = agent ? {
13524
+ kind: "agent",
13525
+ value: agent
13526
+ } : human ? {
13527
+ kind: "human",
13528
+ value: human
13529
+ } : null;
13530
+ if (!user) return failureOutcome(opError("NOT_FOUND", {
13531
+ message: `User not found or not visible: @${name}`,
13532
+ nextAction: "Run `raft server info --agents --query <name>` or `raft server info --humans --query <name>` to inspect visible users."
13533
+ }));
13534
+ const visibleChannels = info.data.channels;
13535
+ const memberships = [];
13536
+ let skippedChannels = 0;
13537
+ for (const channel of visibleChannels.slice(offset, offset + limit)) {
13538
+ const members = await client.channels.members({ channel: `#${channel.name}` });
13539
+ if (!members.ok) {
13540
+ skippedChannels += 1;
13541
+ continue;
13542
+ }
13543
+ if ((user.kind === "agent" ? members.data.agents ?? [] : members.data.humans ?? []).some((candidate) => candidate.name === name)) memberships.push({
13544
+ ...channel,
13545
+ joined: true,
13546
+ muted: void 0,
13547
+ activityMuted: void 0
13548
+ });
13549
+ }
13550
+ const nextOffset = offset + limit;
13551
+ const page = {
13552
+ total: visibleChannels.length,
13553
+ offset,
13554
+ limit,
13555
+ nextCommand: nextOffset < visibleChannels.length ? `raft user info @${name} --offset ${nextOffset} --limit ${limit}` : void 0
13556
+ };
13557
+ const next = page.nextCommand ? {
13558
+ kind: "next_page",
13559
+ command: page.nextCommand,
13560
+ args: {
13561
+ name: `@${name}`,
13562
+ offset: nextOffset,
13563
+ limit
13564
+ },
13565
+ why: "Only one page of visible channels was inspected for memberships."
13566
+ } : null;
13567
+ return {
13568
+ ok: true,
13569
+ state: "info",
13570
+ data: {
13571
+ user,
13572
+ memberships,
13573
+ skippedChannels,
13574
+ page
13575
+ },
13576
+ next,
13577
+ text: formatAgentUserInfo(user, memberships, page, skippedChannels)
13578
+ };
13579
+ }
13377
13580
  //#endregion
13378
13581
  //#region ../shared/src/agentText/attachments.ts
13379
13582
  /** Upload receipt with attachment id and send-usage hint. */
@@ -15054,6 +15257,17 @@ const OPERATION_DEFS = [
15054
15257
  boundBy: []
15055
15258
  }
15056
15259
  },
15260
+ {
15261
+ name: "tasks.show",
15262
+ description: "One task's current status, title, and description. Finds done and closed tasks too.",
15263
+ schema: taskRefSchema,
15264
+ routes: ["taskList"],
15265
+ consumes: nothing,
15266
+ output: {
15267
+ mayBeLarge: true,
15268
+ boundBy: []
15269
+ }
15270
+ },
15057
15271
  {
15058
15272
  name: "tasks.convert",
15059
15273
  description: "Turn a top-level message into an unassigned task.",
@@ -15113,6 +15327,14 @@ const OPERATION_DEFS = [
15113
15327
  boundBy: []
15114
15328
  }
15115
15329
  },
15330
+ {
15331
+ name: "channels.info",
15332
+ description: "A regular channel's facts: visibility, whether you joined it, your role and mute state, description, and member counts.",
15333
+ schema: channelInfoRequestSchema,
15334
+ routes: ["serverInfo", "channelMembers"],
15335
+ consumes: nothing,
15336
+ output: small
15337
+ },
15116
15338
  {
15117
15339
  name: "threads.list",
15118
15340
  description: "The threads you follow.",
@@ -15147,6 +15369,17 @@ const OPERATION_DEFS = [
15147
15369
  ]
15148
15370
  }
15149
15371
  },
15372
+ {
15373
+ name: "users.info",
15374
+ description: "A human's or agent's visible facts (kind, status, role, description) and which visible channels they are in. Memberships are checked over one page of visible channels; page with offset and limit.",
15375
+ schema: userInfoRequestSchema,
15376
+ routes: ["serverInfo", "channelMembers"],
15377
+ consumes: nothing,
15378
+ output: {
15379
+ mayBeLarge: true,
15380
+ boundBy: ["offset", "limit"]
15381
+ }
15382
+ },
15150
15383
  {
15151
15384
  name: "profile.show",
15152
15385
  description: "Show your profile, or someone else's by @handle.",
@@ -15392,6 +15625,7 @@ function createRaft(options) {
15392
15625
  updateStatus: (request) => updateTaskStatus(api, request),
15393
15626
  amend: (request) => amendTask(api, request),
15394
15627
  history: (request) => taskHistory(api, request),
15628
+ show: (request) => showTask(api, request),
15395
15629
  convert: (request) => convertMessageToTask(api, request),
15396
15630
  delete: (request) => deleteTask(api, request)
15397
15631
  },
@@ -15400,13 +15634,15 @@ function createRaft(options) {
15400
15634
  leave: (request) => leaveChannel(api, request),
15401
15635
  mute: (request) => muteChannel(api, request),
15402
15636
  unmute: (request) => unmuteChannel(api, request),
15403
- members: (request) => channelMembers(api, request)
15637
+ members: (request) => channelMembers(api, request),
15638
+ info: (request) => channelInfo(api, request)
15404
15639
  },
15405
15640
  threads: {
15406
15641
  list: () => listThreads(api),
15407
15642
  unfollow: (request) => unfollowThread(api, request)
15408
15643
  },
15409
15644
  server: { info: (request) => serverInfo(api, request) },
15645
+ users: { info: (request) => userInfo(api, request) },
15410
15646
  profile: {
15411
15647
  show: (request) => showProfile(api, request),
15412
15648
  update: (request) => updateProfile(api, request)
@@ -15474,6 +15710,7 @@ function createRaft(options) {
15474
15710
  "tasks.updateStatus": (args) => raft.tasks.updateStatus(args),
15475
15711
  "tasks.amend": (args) => raft.tasks.amend(args),
15476
15712
  "tasks.history": (args) => raft.tasks.history(args),
15713
+ "tasks.show": (args) => raft.tasks.show(args),
15477
15714
  "tasks.convert": (args) => raft.tasks.convert(args),
15478
15715
  "tasks.delete": (args) => raft.tasks.delete(args),
15479
15716
  "channels.join": (args) => raft.channels.join(args),
@@ -15481,9 +15718,11 @@ function createRaft(options) {
15481
15718
  "channels.mute": (args) => raft.channels.mute(args),
15482
15719
  "channels.unmute": (args) => raft.channels.unmute(args),
15483
15720
  "channels.members": (args) => raft.channels.members(args),
15721
+ "channels.info": (args) => raft.channels.info(args),
15484
15722
  "threads.list": () => raft.threads.list(),
15485
15723
  "threads.unfollow": (args) => raft.threads.unfollow(args),
15486
15724
  "server.info": (args) => raft.server.info(args),
15725
+ "users.info": (args) => raft.users.info(args),
15487
15726
  "profile.show": (args) => raft.profile.show(args),
15488
15727
  "profile.update": (args) => raft.profile.update(args)
15489
15728
  };
@@ -15527,4 +15766,4 @@ function whoamiOutcome(result) {
15527
15766
  };
15528
15767
  }
15529
15768
  //#endregion
15530
- export { RAFT_INBOX_NOTICE_SCHEMA, RAFT_JSON_SCHEMA_KEYWORDS, RAFT_NOTICE_DELIVERY_ID_HEADER, RAFT_NOTICE_SIGNATURE_HEADER, RAFT_OPERATIONS, RAFT_OPERATIONS_SCHEMA, RAFT_OPERATIONS_VERSION, RAFT_STATE_CONTINUATIONS_PER_TARGET, RAFT_STATE_CONTINUATIONS_TOTAL, RAFT_STATE_SCHEMA, RaftCredentialError, RaftSdkConfigurationError, SeenFrontier, amendTaskRequestSchema, assignTaskRequestSchema, attachmentCommentsRequestSchema, bootstrapRaftCredential, channelMembersRequestSchema, channelTargetRequestSchema, checkInboxRequestSchema, claimTasksRequestSchema, commitInboxRequestSchema, convertMessageToTaskRequestSchema, createFileCredentialStore, createRaft, createRaftClient, createRaftClientFromStore, createRaftRoutes, createTasksRequestSchema, describeRaftRoute, drainInboxRequestSchema, executeMentionActionRequestSchema, getManualTopicRequestSchema, hasAgentMessageIdentity, hashRaftSendContent, inferAttachmentMimeType, isInterrupted, joinRaftChannelByTarget, listInboxRequestSchema, listRaftRoutes, listTasksRequestSchema, listThreadsRequestSchema, parseRaftRegularChannelTarget, parseRaftState, pendingMentionActionsRequestSchema, prepareActionCardRequestSchema, projectRaftMessage, projectRaftMessages, raftToolNameFor, reactRequestSchema, readHistoryRequestSchema, readLatestReadThread, replyToRequestSchema, resolveMessageRequestSchema, searchManualRequestSchema, searchMessagesRequestSchema, sendMessageRequestSchema, senderMentionDeliveriesRequestSchema, serverInfoRequestSchema, showProfileRequestSchema, taskRefSchema, unfollowThreadRequestSchema, updateProfileRequestSchema, updateTaskStatusRequestSchema, verifyInboxNotice, whoamiRequestSchema };
15769
+ export { RAFT_INBOX_NOTICE_SCHEMA, RAFT_JSON_SCHEMA_KEYWORDS, RAFT_NOTICE_DELIVERY_ID_HEADER, RAFT_NOTICE_SIGNATURE_HEADER, RAFT_OPERATIONS, RAFT_OPERATIONS_SCHEMA, RAFT_OPERATIONS_VERSION, RAFT_STATE_CONTINUATIONS_PER_TARGET, RAFT_STATE_CONTINUATIONS_TOTAL, RAFT_STATE_SCHEMA, RaftCredentialError, RaftSdkConfigurationError, SeenFrontier, amendTaskRequestSchema, assignTaskRequestSchema, attachmentCommentsRequestSchema, bootstrapRaftCredential, channelInfoRequestSchema, channelMembersRequestSchema, channelTargetRequestSchema, checkInboxRequestSchema, claimTasksRequestSchema, commitInboxRequestSchema, convertMessageToTaskRequestSchema, createFileCredentialStore, createRaft, createRaftClient, createRaftClientFromStore, createRaftRoutes, createTasksRequestSchema, describeRaftRoute, drainInboxRequestSchema, executeMentionActionRequestSchema, getManualTopicRequestSchema, hasAgentMessageIdentity, hashRaftSendContent, inferAttachmentMimeType, isInterrupted, joinRaftChannelByTarget, listInboxRequestSchema, listRaftRoutes, listTasksRequestSchema, listThreadsRequestSchema, parseRaftRegularChannelTarget, parseRaftState, pendingMentionActionsRequestSchema, prepareActionCardRequestSchema, projectRaftMessage, projectRaftMessages, raftToolNameFor, reactRequestSchema, readHistoryRequestSchema, readLatestReadThread, replyToRequestSchema, resolveMessageRequestSchema, searchManualRequestSchema, searchMessagesRequestSchema, sendMessageRequestSchema, senderMentionDeliveriesRequestSchema, serverInfoRequestSchema, showProfileRequestSchema, taskRefSchema, unfollowThreadRequestSchema, updateProfileRequestSchema, updateTaskStatusRequestSchema, userInfoRequestSchema, verifyInboxNotice, whoamiRequestSchema };
package/dist/index.d.ts CHANGED
@@ -1007,6 +1007,40 @@ interface VerifyNoticeInput {
1007
1007
  export declare function verifyInboxNotice(input: VerifyNoticeInput): Promise<VerifyNoticeResult>;
1008
1008
  type RaftWebhookStatus = AgentApiPushWebhookStatusResponse;
1009
1009
  //#endregion
1010
+ //#region ../shared/src/agentText/server.d.ts
1011
+ interface AgentChannelInfo {
1012
+ id?: string | null;
1013
+ name: string;
1014
+ joined: boolean;
1015
+ type?: string | null;
1016
+ description?: string | null;
1017
+ muted?: boolean | null;
1018
+ activityMuted?: boolean | null;
1019
+ archived?: boolean | null;
1020
+ channelRole?: "member" | "admin" | null;
1021
+ channelAdminBasis?: "server_role" | "channel_role" | "both" | null;
1022
+ channelCapabilities?: Record<string, boolean> | null;
1023
+ }
1024
+ interface AgentAgentInfo {
1025
+ name: string;
1026
+ status?: string | null;
1027
+ activity?: string | null;
1028
+ activityDetail?: string | null;
1029
+ role?: "owner" | "admin" | "member" | string | null;
1030
+ description?: string | null;
1031
+ }
1032
+ interface AgentHumanInfo {
1033
+ name: string;
1034
+ role?: "owner" | "admin" | "member" | string | null;
1035
+ description?: string | null;
1036
+ }
1037
+ interface AgentPageInfo {
1038
+ total: number;
1039
+ offset: number;
1040
+ limit: number;
1041
+ nextCommand?: string;
1042
+ }
1043
+ //#endregion
1010
1044
  //#region ../shared/src/agentOps/channels.d.ts
1011
1045
  /** `{ target }` of a regular channel (join, leave, mute, unmute). */
1012
1046
  export declare const channelTargetRequestSchema: z.ZodObject<{
@@ -1030,13 +1064,17 @@ interface RaftChannelMuteState extends RaftChannelRef {
1030
1064
  muteFromSeq: number | null;
1031
1065
  stillArrives: string[];
1032
1066
  }
1033
- //#endregion
1034
- //#region ../shared/src/agentText/server.d.ts
1035
- interface AgentPageInfo {
1036
- total: number;
1037
- offset: number;
1038
- limit: number;
1039
- nextCommand?: string;
1067
+ export declare const channelInfoRequestSchema: z.ZodObject<{
1068
+ target: z.ZodString;
1069
+ }, z.core.$strip>;
1070
+ interface RaftChannelInfo {
1071
+ /** The channel as `server.info` lists it (`joined` and the attention flags are yours). */
1072
+ channel: AgentChannelInfo;
1073
+ /** Roster counts, or null when the Server refused the roster (the text then omits `Members:`). */
1074
+ memberCounts: {
1075
+ agents: number;
1076
+ humans: number;
1077
+ } | null;
1040
1078
  }
1041
1079
  //#endregion
1042
1080
  //#region ../shared/src/agentOps/server.d.ts
@@ -1079,6 +1117,35 @@ interface RaftServerInfo {
1079
1117
  section: ServerInfoSection;
1080
1118
  }) | null;
1081
1119
  }
1120
+ interface UserInfoRequest {
1121
+ /** The user's handle, `@name` or `name`. */
1122
+ name: string;
1123
+ /** Visible channels to skip before inspecting memberships (default 0). */
1124
+ offset?: number;
1125
+ /** Visible channels to inspect for memberships (default 50). */
1126
+ limit?: number;
1127
+ }
1128
+ export declare const userInfoRequestSchema: z.ZodObject<{
1129
+ name: z.ZodString;
1130
+ offset: z.ZodOptional<z.ZodNumber>;
1131
+ limit: z.ZodOptional<z.ZodNumber>;
1132
+ }, z.core.$strip>;
1133
+ type RaftUserRef = {
1134
+ kind: "agent";
1135
+ value: AgentAgentInfo;
1136
+ } | {
1137
+ kind: "human";
1138
+ value: AgentHumanInfo;
1139
+ };
1140
+ interface RaftUserInfo {
1141
+ user: RaftUserRef;
1142
+ /** The inspected visible channels whose roster lists the user (`joined` is the user's, not yours). */
1143
+ memberships: AgentChannelInfo[];
1144
+ /** Inspected channels whose roster the Server refused; they are not counted either way. */
1145
+ skippedChannels: number;
1146
+ /** Paging over the visible channels (`total` is all visible channels). */
1147
+ page: AgentPageInfo;
1148
+ }
1082
1149
  //#endregion
1083
1150
  //#region ../shared/src/agentOps/attachments.d.ts
1084
1151
  export declare const attachmentCommentsRequestSchema: z.ZodObject<{
@@ -10062,6 +10129,22 @@ declare const OPERATION_DEFS: readonly [{
10062
10129
  readonly mayBeLarge: true;
10063
10130
  readonly boundBy: [];
10064
10131
  };
10132
+ }, {
10133
+ readonly name: "tasks.show";
10134
+ readonly description: "One task's current status, title, and description. Finds done and closed tasks too.";
10135
+ readonly schema: z.ZodObject<{
10136
+ target: z.ZodString;
10137
+ taskNumber: z.ZodNumber;
10138
+ }, z.core.$strip>;
10139
+ readonly routes: readonly ["taskList"];
10140
+ readonly consumes: {
10141
+ model: never[];
10142
+ code: never[];
10143
+ };
10144
+ readonly output: {
10145
+ readonly mayBeLarge: true;
10146
+ readonly boundBy: [];
10147
+ };
10065
10148
  }, {
10066
10149
  readonly name: "tasks.convert";
10067
10150
  readonly description: "Turn a top-level message into an unassigned task.";
@@ -10169,6 +10252,21 @@ declare const OPERATION_DEFS: readonly [{
10169
10252
  readonly mayBeLarge: true;
10170
10253
  readonly boundBy: [];
10171
10254
  };
10255
+ }, {
10256
+ readonly name: "channels.info";
10257
+ readonly description: "A regular channel's facts: visibility, whether you joined it, your role and mute state, description, and member counts.";
10258
+ readonly schema: z.ZodObject<{
10259
+ target: z.ZodString;
10260
+ }, z.core.$strip>;
10261
+ readonly routes: readonly ["serverInfo", "channelMembers"];
10262
+ readonly consumes: {
10263
+ model: never[];
10264
+ code: never[];
10265
+ };
10266
+ readonly output: {
10267
+ mayBeLarge: false;
10268
+ boundBy: never[];
10269
+ };
10172
10270
  }, {
10173
10271
  readonly name: "threads.list";
10174
10272
  readonly description: "The threads you follow.";
@@ -10222,6 +10320,23 @@ declare const OPERATION_DEFS: readonly [{
10222
10320
  readonly mayBeLarge: true;
10223
10321
  readonly boundBy: ["view", "offset", "limit"];
10224
10322
  };
10323
+ }, {
10324
+ readonly name: "users.info";
10325
+ readonly description: "A human's or agent's visible facts (kind, status, role, description) and which visible channels they are in. Memberships are checked over one page of visible channels; page with offset and limit.";
10326
+ readonly schema: z.ZodObject<{
10327
+ name: z.ZodString;
10328
+ offset: z.ZodOptional<z.ZodNumber>;
10329
+ limit: z.ZodOptional<z.ZodNumber>;
10330
+ }, z.core.$strip>;
10331
+ readonly routes: readonly ["serverInfo", "channelMembers"];
10332
+ readonly consumes: {
10333
+ model: never[];
10334
+ code: never[];
10335
+ };
10336
+ readonly output: {
10337
+ readonly mayBeLarge: true;
10338
+ readonly boundBy: ["offset", "limit"];
10339
+ };
10225
10340
  }, {
10226
10341
  readonly name: "profile.show";
10227
10342
  readonly description: "Show your profile, or someone else's by @handle.";
@@ -10483,6 +10598,11 @@ interface Raft {
10483
10598
  history(request: TaskRef): Promise<RaftOutcome<AgentApiTaskHistoryResponse & {
10484
10599
  target: string;
10485
10600
  }, "history">>;
10601
+ /** One task's current title and description (`raft task show`). */
10602
+ show(request: TaskRef): Promise<RaftOutcome<{
10603
+ target: string;
10604
+ task: AgentApiTaskEnvelope;
10605
+ }, "task">>;
10486
10606
  /** Convert a top-level message into an unassigned task. */
10487
10607
  convert(request: {
10488
10608
  target: string;
@@ -10511,6 +10631,10 @@ interface Raft {
10511
10631
  members(request: {
10512
10632
  target: string;
10513
10633
  }): Promise<RaftOutcome<AgentApiChannelMembersResponse, "members">>;
10634
+ /** A regular channel's facts: visibility, whether you joined, description, member counts (`raft channel info`). */
10635
+ info(request: {
10636
+ target: string;
10637
+ }): Promise<RaftOutcome<RaftChannelInfo, "info">>;
10514
10638
  };
10515
10639
  threads: {
10516
10640
  list(): Promise<RaftOutcome<AgentApiThreadListItem[], "threads" | "empty">>;
@@ -10525,6 +10649,10 @@ interface Raft {
10525
10649
  /** Summary by default; `view: "channels" | "agents" | "humans"` pages a section; `view: "full"` is the whole overview. */
10526
10650
  info(request?: ServerInfoRequest): Promise<RaftOutcome<RaftServerInfo, "info">>;
10527
10651
  };
10652
+ users: {
10653
+ /** A human's or agent's visible facts and their memberships among one page of visible channels (`raft user info`). */
10654
+ info(request: UserInfoRequest): Promise<RaftOutcome<RaftUserInfo, "info">>;
10655
+ };
10528
10656
  profile: {
10529
10657
  show(request?: {
10530
10658
  target?: string;
@@ -10558,4 +10686,4 @@ export declare const commitInboxRequestSchema: z.ZodObject<{
10558
10686
  cursor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
10559
10687
  }, z.core.$strip>;
10560
10688
  //#endregion
10561
- export type { AmendTaskOutcome, AmendTaskRequest, AssignTaskRequest, BootstrapRaftCredentialOptions, CheckInboxOutcome, CheckInboxRequest, ClaimTasksOutcome, ClaimTasksRequest, ConvertMessageToTaskRequest, CreateRaftClientFromStoreOptions, CreateRaftClientOptions, CreateRaftOptions, CreateRaftRoutesOptions, CreateTasksRequest, DrainInboxRequest, ExecuteMentionActionRequest, ListInboxRequest, ListTasksRequest, ManualContext, PrepareActionCardRequest, Raft, RaftAckMode, RaftActionPrepareRequest, RaftActionPrepared, RaftApiError, RaftApiResult, RaftAppConfig, RaftAppConfigPatch, RaftAttachmentBytes, RaftAttachmentUploaded, RaftAvatarUpload, RaftChannelJoinClient, RaftChannelJoinClientResult, RaftChannelJoinError, RaftChannelJoinFailure, RaftChannelJoinOperation, RaftChannelJoinRequest, RaftChannelJoinResult, RaftChannelJoinSuccess, RaftChannelJoinTransportError, RaftChannelMuteState, RaftChannelRef, RaftClaimResult, RaftClaimRow, RaftClaimRowState, RaftClient, RaftClientError, RaftClientFailure, RaftClientResult, RaftClientSuccess, RaftClientThrottleOptions, RaftClientTransportRequest, RaftConsumption, RaftContextAgent, RaftContextData, RaftContextError, RaftContextResult, RaftContextServer, RaftCredentialErrorCode, RaftCredentialIdentity, RaftCredentialStore, RaftEvent, RaftEventAttachment, RaftEventExternalMessage, RaftEventsReceiveData, RaftEventsReceiveError, RaftEventsReceiveRequest, RaftEventsReceiveResult, RaftFailure, RaftHistoryPage, RaftInboxBatch, RaftInboxCommitResult, RaftInboxConversation, RaftInboxDrainSummary, RaftInboxDrained, RaftInboxListing, RaftInboxNotice, RaftInterrupt, RaftInterruptCancel, RaftInterruptReason, RaftInterruptResume, RaftInterrupted, RaftInvokeCaller, RaftInvokeResult, RaftJsonSchema, RaftJsonSchemaType, RaftLatestReadThread, RaftManageClient, RaftMessage, RaftMessageAttachment, RaftMessageTask, RaftNextStep, RaftNoticeFlag, RaftNoticeTarget, RaftOpError, RaftOpErrorCode, RaftOperationIdempotency, RaftOperationName, RaftOperationSpec, RaftOperationsDocument, RaftOutcome, RaftPendingMentions, RaftPreparedCard, RaftProfile, RaftProfileUpdate, RaftRouteAnnotations, RaftRouteInfo, RaftRouteKey, RaftRouteMeta, RaftRouteResult, RaftRouteRetryPolicy, RaftRoutes, RaftSdkConfigurationErrorCode, RaftSearchPage, RaftSenderType, RaftSent, RaftServerInfo, RaftServerProfile, RaftServerUpdate, RaftState, RaftStateContinuation, RaftStateSaveErrorHandler, RaftStateStore, RaftTaskBoard, RaftTaskStatus, RaftTasksCreated, RaftWebhookStatus, ReactRequest, ReadHistoryRequest, ReadLatestReadThreadOptions, ReplyToRequest, SearchMessagesRequest, SeenAttestation, SeenFrontierSnapshot, SendMessageOutcome, SendMessageRequest, ServerInfoRequest, ServerInfoSection, StoredRaftCredential, TaskRef, UpdateTaskStatusOutcome, UpdateTaskStatusRequest, UploadAttachmentRequest, VerifyNoticeInput, VerifyNoticeRejection, VerifyNoticeResult };
10689
+ export type { AmendTaskOutcome, AmendTaskRequest, AssignTaskRequest, BootstrapRaftCredentialOptions, CheckInboxOutcome, CheckInboxRequest, ClaimTasksOutcome, ClaimTasksRequest, ConvertMessageToTaskRequest, CreateRaftClientFromStoreOptions, CreateRaftClientOptions, CreateRaftOptions, CreateRaftRoutesOptions, CreateTasksRequest, DrainInboxRequest, ExecuteMentionActionRequest, ListInboxRequest, ListTasksRequest, ManualContext, PrepareActionCardRequest, Raft, RaftAckMode, RaftActionPrepareRequest, RaftActionPrepared, RaftApiError, RaftApiResult, RaftAppConfig, RaftAppConfigPatch, RaftAttachmentBytes, RaftAttachmentUploaded, RaftAvatarUpload, RaftChannelInfo, RaftChannelJoinClient, RaftChannelJoinClientResult, RaftChannelJoinError, RaftChannelJoinFailure, RaftChannelJoinOperation, RaftChannelJoinRequest, RaftChannelJoinResult, RaftChannelJoinSuccess, RaftChannelJoinTransportError, RaftChannelMuteState, RaftChannelRef, RaftClaimResult, RaftClaimRow, RaftClaimRowState, RaftClient, RaftClientError, RaftClientFailure, RaftClientResult, RaftClientSuccess, RaftClientThrottleOptions, RaftClientTransportRequest, RaftConsumption, RaftContextAgent, RaftContextData, RaftContextError, RaftContextResult, RaftContextServer, RaftCredentialErrorCode, RaftCredentialIdentity, RaftCredentialStore, RaftEvent, RaftEventAttachment, RaftEventExternalMessage, RaftEventsReceiveData, RaftEventsReceiveError, RaftEventsReceiveRequest, RaftEventsReceiveResult, RaftFailure, RaftHistoryPage, RaftInboxBatch, RaftInboxCommitResult, RaftInboxConversation, RaftInboxDrainSummary, RaftInboxDrained, RaftInboxListing, RaftInboxNotice, RaftInterrupt, RaftInterruptCancel, RaftInterruptReason, RaftInterruptResume, RaftInterrupted, RaftInvokeCaller, RaftInvokeResult, RaftJsonSchema, RaftJsonSchemaType, RaftLatestReadThread, RaftManageClient, RaftMessage, RaftMessageAttachment, RaftMessageTask, RaftNextStep, RaftNoticeFlag, RaftNoticeTarget, RaftOpError, RaftOpErrorCode, RaftOperationIdempotency, RaftOperationName, RaftOperationSpec, RaftOperationsDocument, RaftOutcome, RaftPendingMentions, RaftPreparedCard, RaftProfile, RaftProfileUpdate, RaftRouteAnnotations, RaftRouteInfo, RaftRouteKey, RaftRouteMeta, RaftRouteResult, RaftRouteRetryPolicy, RaftRoutes, RaftSdkConfigurationErrorCode, RaftSearchPage, RaftSenderType, RaftSent, RaftServerInfo, RaftServerProfile, RaftServerUpdate, RaftState, RaftStateContinuation, RaftStateSaveErrorHandler, RaftStateStore, RaftTaskBoard, RaftTaskStatus, RaftTasksCreated, RaftUserInfo, RaftUserRef, RaftWebhookStatus, ReactRequest, ReadHistoryRequest, ReadLatestReadThreadOptions, ReplyToRequest, SearchMessagesRequest, SeenAttestation, SeenFrontierSnapshot, SendMessageOutcome, SendMessageRequest, ServerInfoRequest, ServerInfoSection, StoredRaftCredential, TaskRef, UpdateTaskStatusOutcome, UpdateTaskStatusRequest, UploadAttachmentRequest, UserInfoRequest, VerifyNoticeInput, VerifyNoticeRejection, VerifyNoticeResult };
package/operations.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "raft-sdk-operations.v1",
3
- "version": "fb1a488b19b73cbc",
3
+ "version": "90a77ae0a9067bc0",
4
4
  "operations": [
5
5
  {
6
6
  "name": "identity.whoami",
@@ -1519,6 +1519,46 @@
1519
1519
  "boundBy": []
1520
1520
  }
1521
1521
  },
1522
+ {
1523
+ "name": "tasks.show",
1524
+ "toolName": "tasks_show",
1525
+ "description": "One task's current status, title, and description. Finds done and closed tasks too.",
1526
+ "inputSchema": {
1527
+ "type": "object",
1528
+ "properties": {
1529
+ "target": {
1530
+ "type": "string",
1531
+ "description": "The channel the task board belongs to, for example `#proj-sdk`."
1532
+ },
1533
+ "taskNumber": {
1534
+ "type": "integer",
1535
+ "description": "The task number on that channel's board.",
1536
+ "minimum": 1
1537
+ }
1538
+ },
1539
+ "required": [
1540
+ "target",
1541
+ "taskNumber"
1542
+ ]
1543
+ },
1544
+ "sideEffect": "read",
1545
+ "idempotency": {
1546
+ "kind": "natural"
1547
+ },
1548
+ "capability": [
1549
+ "tasks"
1550
+ ],
1551
+ "modelOnly": false,
1552
+ "mayInterrupt": false,
1553
+ "consumes": {
1554
+ "model": [],
1555
+ "code": []
1556
+ },
1557
+ "output": {
1558
+ "mayBeLarge": true,
1559
+ "boundBy": []
1560
+ }
1561
+ },
1522
1562
  {
1523
1563
  "name": "tasks.convert",
1524
1564
  "toolName": "tasks_convert",
@@ -1772,6 +1812,41 @@
1772
1812
  "boundBy": []
1773
1813
  }
1774
1814
  },
1815
+ {
1816
+ "name": "channels.info",
1817
+ "toolName": "channels_info",
1818
+ "description": "A regular channel's facts: visibility, whether you joined it, your role and mute state, description, and member counts.",
1819
+ "inputSchema": {
1820
+ "type": "object",
1821
+ "properties": {
1822
+ "target": {
1823
+ "type": "string",
1824
+ "description": "A regular channel, `#channel-name` (the `#` may be omitted). DMs and threads are not accepted."
1825
+ }
1826
+ },
1827
+ "required": [
1828
+ "target"
1829
+ ]
1830
+ },
1831
+ "sideEffect": "read",
1832
+ "idempotency": {
1833
+ "kind": "natural"
1834
+ },
1835
+ "capability": [
1836
+ "channels",
1837
+ "read"
1838
+ ],
1839
+ "modelOnly": false,
1840
+ "mayInterrupt": false,
1841
+ "consumes": {
1842
+ "model": [],
1843
+ "code": []
1844
+ },
1845
+ "output": {
1846
+ "mayBeLarge": false,
1847
+ "boundBy": []
1848
+ }
1849
+ },
1775
1850
  {
1776
1851
  "name": "threads.list",
1777
1852
  "toolName": "threads_list",
@@ -1890,6 +1965,54 @@
1890
1965
  ]
1891
1966
  }
1892
1967
  },
1968
+ {
1969
+ "name": "users.info",
1970
+ "toolName": "users_info",
1971
+ "description": "A human's or agent's visible facts (kind, status, role, description) and which visible channels they are in. Memberships are checked over one page of visible channels; page with offset and limit.",
1972
+ "inputSchema": {
1973
+ "type": "object",
1974
+ "properties": {
1975
+ "name": {
1976
+ "type": "string",
1977
+ "description": "The human or agent, `@handle` (or the bare handle)."
1978
+ },
1979
+ "offset": {
1980
+ "type": "integer",
1981
+ "description": "Membership paging: visible channels to skip before inspecting (default 0).",
1982
+ "minimum": 0
1983
+ },
1984
+ "limit": {
1985
+ "type": "integer",
1986
+ "description": "Membership paging: visible channels to inspect (default 50).",
1987
+ "minimum": 1
1988
+ }
1989
+ },
1990
+ "required": [
1991
+ "name"
1992
+ ]
1993
+ },
1994
+ "sideEffect": "read",
1995
+ "idempotency": {
1996
+ "kind": "natural"
1997
+ },
1998
+ "capability": [
1999
+ "channels",
2000
+ "read"
2001
+ ],
2002
+ "modelOnly": false,
2003
+ "mayInterrupt": false,
2004
+ "consumes": {
2005
+ "model": [],
2006
+ "code": []
2007
+ },
2008
+ "output": {
2009
+ "mayBeLarge": true,
2010
+ "boundBy": [
2011
+ "offset",
2012
+ "limit"
2013
+ ]
2014
+ }
2015
+ },
1893
2016
  {
1894
2017
  "name": "profile.show",
1895
2018
  "toolName": "profile_show",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botiverse/raft-sdk",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "license": "FSL-1.1-ALv2",
5
5
  "description": "Typed Raft Agent API client for external agents and bots.",
6
6
  "type": "module",