@ziggs-ai/api-client 0.37.7 → 0.37.8

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.
@@ -6,7 +6,7 @@
6
6
  * keeps the people who actually receive (`participantSummary`) and drops the
7
7
  * other two unless `fields` asks for them.
8
8
  */
9
- export declare const CHAT_LIST_DEFAULT_FIELDS: readonly ["chatId", "name", "updatedAt", "lastMessage", "unreadCount", "participantSummary"];
9
+ export declare const CHAT_LIST_DEFAULT_FIELDS: readonly ["chatId", "name", "updatedAt", "lastMessage", "unreadCount", "participantSummary", "readable", "requestAccess"];
10
10
  /** Apply `fields`, or the MCP default when the caller omitted it. */
11
11
  export declare function projectChatListRows(chats: unknown[], fieldsRaw?: unknown): unknown[];
12
12
  export declare function utf8Bytes(value: unknown): number;
@@ -14,6 +14,9 @@ export const CHAT_LIST_DEFAULT_FIELDS = [
14
14
  'lastMessage',
15
15
  'unreadCount',
16
16
  'participantSummary',
17
+ // A room you may only list says so, with the read request ready to file.
18
+ 'readable',
19
+ 'requestAccess',
17
20
  ];
18
21
  function slimParticipant(row) {
19
22
  if (!row || typeof row !== 'object' || Array.isArray(row))
@@ -425,14 +425,14 @@ export const accessRequestCapability = {
425
425
  title: 'Request access for yourself or named readers',
426
426
  annotation: 'destructive', needsAgentId: true,
427
427
  descriptions: {
428
- sdk: 'Request optional bounded access to one artifact, chat, agreement context or task. Creates only a pending approval; never grants access or approves. Name who to ask in recipientId: your work brief offers them for this wake — workBrief.actingFor.customer.id (the customer of the hire you are working in, for their own accounts and resources) or workBrief.actingFor.operator.id (your operator, for tools you bring). Anyone else is refused, and the refusal lists who you can ask. Artifact requests also need chatId, the conversation they approve in. To create work under an agreement you can read but not work on (a task create refused with WORK_ACCESS_REQUIRED), request permission=work on it; only someone who can work on it may approve, and it lasts until the agreement ends. Use scopeId for a known artifact; or scopeKind=artifact with agreementId of your active hire to request its system-maintained workspace summary (workspace name/type and agents, including future updates, not private conversations or document bodies). Send the returned appUrl, wait for human approval, then open the returned scope. To arrange reading of one artifact for others, name them in holders (agents by id, people or workspaces by id or the participant reference this room shows you); include yourself only if you need to read it too. The owner approves that exact list once and each reader gets its own grant; readers who can already read it come back as already_readable. Hiring alone grants no source access. Revocation and expiry are checked by the system.',
428
+ sdk: 'Request optional bounded access to one artifact, chat, agreement context or task. Creates only a pending approval; never grants access or approves. Name who to ask in recipientId: your work brief offers them for this wake — workBrief.actingFor.customer.id (the customer of the hire you are working in, for their own accounts and resources) or workBrief.actingFor.operator.id (your operator, for tools you bring). Anyone else is refused, and the refusal lists who you can ask. Artifact requests also need chatId, the conversation they approve in. To create work under an agreement you can read but not work on (a task create refused with WORK_ACCESS_REQUIRED), request permission=work on it; only someone who can work on it may approve, and it lasts until the agreement ends. Use scopeId for a known artifact; or scopeKind=artifact with agreementId of your active hire to request its system-maintained workspace summary (workspace name/type and agents, including future updates, not private conversations or document bodies). Send the returned appUrl, wait for human approval, then open the returned scope. To arrange reading of one artifact for others, name them in holders (agents by id, people or workspaces by id or the participant reference this room shows you); include yourself only if you need to read it too. The owner approves that exact list once and each reader gets its own grant; readers who can already read it come back as already_readable. To see which rooms a person is in (to find the room they mean), request scopeKind=person, scopeId=their person id, permission=list, from that person; once they approve, your chat list shows their rooms, each marked readable or not, and reading one still needs its own request. Hiring alone grants no source access. Revocation and expiry are checked by the system.',
429
429
  },
430
430
  params: {
431
- scopeKind: { type: 'string', required: true, enum: ['artifact', 'chat', 'agreement', 'task'] },
431
+ scopeKind: { type: 'string', required: true, enum: ['artifact', 'chat', 'agreement', 'task', 'person'] },
432
432
  scopeId: { type: 'string', description: 'Original resource id. Omit when using a hire agreementId to request its workspace summary.' },
433
433
  agreementId: { type: 'string', description: 'Artifact scope only: current hire id, used instead of scopeId to request the system-maintained workspace summary.' },
434
434
  reason: { type: 'string', required: true, description: 'Why access is needed and who will receive the reply or summary' },
435
- permission: { type: 'string', enum: ['read', 'reply', 'work'], description: 'read by default; reply is read and reply and is only valid for a chat; work lets you create work under an agreement you can read but not work on, and lasts until it ends' },
435
+ permission: { type: 'string', enum: ['read', 'reply', 'work', 'list'], description: 'read by default; reply is read and reply and is only valid for a chat; work lets you create work under an agreement you can read but not work on, and lasts until it ends; list is required for a person scope and shows which rooms they are in, never their messages' },
436
436
  temporal: { type: 'string', enum: ['from-now', 'from-start'], description: 'Chat history requested; default from-now. Earlier messages need from-start. Other resources use from-start.' },
437
437
  durationHours: { type: 'number', description: 'Integer 1–168 hours after approval; default 24' },
438
438
  chatId: { type: 'string', description: 'Artifact or workspace requests only: existing conversation with the owner' },
@@ -462,14 +462,16 @@ export const accessRequestCapability = {
462
462
  throw new Error(`${key} is required`);
463
463
  }
464
464
  const scopeKind = args.scopeKind;
465
- if (!['artifact', 'chat', 'agreement', 'task'].includes(scopeKind))
465
+ if (!['artifact', 'chat', 'agreement', 'task', 'person'].includes(scopeKind))
466
466
  throw new Error('Unsupported scopeKind');
467
467
  const agreementId = typeof args.agreementId === 'string' ? args.agreementId.trim() : undefined;
468
468
  const scopeId = typeof args.scopeId === 'string' ? args.scopeId.trim() : undefined;
469
469
  if (Boolean(agreementId) === Boolean(scopeId) || (agreementId && scopeKind !== 'artifact'))
470
470
  throw new Error('Provide scopeId, or agreementId for its workspace summary artifact');
471
- const permission = args.permission ?? 'read';
472
- if (!['read', 'reply', 'work'].includes(String(permission)) || (permission === 'reply' && scopeKind !== 'chat'))
471
+ const permission = args.permission ?? (scopeKind === 'person' ? 'list' : 'read');
472
+ if ((permission === 'list') !== (scopeKind === 'person'))
473
+ throw new Error('A person scope is requested with permission=list, and list only for a person');
474
+ if (!['read', 'reply', 'work', 'list'].includes(String(permission)) || (permission === 'reply' && scopeKind !== 'chat'))
473
475
  throw new Error('Only chat access may request reply permission');
474
476
  if (permission === 'work' && scopeKind !== 'agreement')
475
477
  throw new Error('Only agreement access may request work permission');
@@ -503,7 +505,10 @@ export const accessRequestCapability = {
503
505
  ...(actingAgentId ? { actingAgentId } : {}),
504
506
  scope: result.scope ?? { kind: scopeKind, id: scopeId },
505
507
  appUrl: `${(env.webUrl ?? 'https://ziggsai.com').replace(/\/$/, '')}/app/agreements/${encodeURIComponent(result.agreementId)}`,
506
- resumeAfterApproval: { tool: env.surface === 'mcp' ? 'ziggs_open' : 'open', args: result.scope ? { [`${result.scope.kind}Id`]: result.scope.id } : { [`${scopeKind}Id`]: scopeId } },
508
+ // A person scope opens nothing: the yes shows up in the chat list.
509
+ ...(scopeKind === 'person'
510
+ ? env.surface === 'mcp' ? { resumeAfterApproval: { tool: 'ziggs_chat_list', args: {} } } : {}
511
+ : { resumeAfterApproval: { tool: env.surface === 'mcp' ? 'ziggs_open' : 'open', args: result.scope ? { [`${result.scope.kind}Id`]: result.scope.id } : { [`${scopeKind}Id`]: scopeId } } }),
507
512
  note: `${result.message ?? 'A request card is open.'} No access granted until they approve; then open the original resource using the same agent identity.`,
508
513
  };
509
514
  },
@@ -100,7 +100,7 @@ const BRIEFS = {
100
100
  },
101
101
  // Rooms
102
102
  ziggs_chat_list: {
103
- does: 'Lists rooms you hold a grant on, with last message and unread count. fields adds members or rosterSummary.',
103
+ does: 'Lists rooms you hold a grant on, with last message and unread count, plus the rooms a person let you list, marked readable: false with no message and the read request to file. fields adds members or rosterSummary.',
104
104
  },
105
105
  ziggs_chat_open: {
106
106
  does: 'Opens or reuses a conversation with a person or agent (participantId), starts a group (participantIds), or invites people into a room (chatId).',
@@ -153,7 +153,10 @@ export declare function addChatMember(input: AddChatMemberInput, creds: Creds):
153
153
  * an existing participant and `chatId` is omitted.
154
154
  */
155
155
  export declare function sendChatMessage(input: SendChatMessageInput, creds: Creds): Promise<SendChatMessageResult>;
156
- export declare function listMyChats(creds: Creds): Promise<ChatSummary[]>;
156
+ export declare function listMyChats(creds: Creds, filters?: {
157
+ participantId?: string;
158
+ readable?: boolean;
159
+ }): Promise<ChatSummary[]>;
157
160
  export declare class ChatClient {
158
161
  private creds;
159
162
  /**
@@ -154,14 +154,20 @@ export async function sendChatMessage(input, creds) {
154
154
  ...(coverage ? { coverage } : {}),
155
155
  };
156
156
  }
157
- export async function listMyChats(creds) {
157
+ export async function listMyChats(creds, filters = {}) {
158
158
  assertCreds(creds, 'list my chats');
159
+ const query = new URLSearchParams();
160
+ if (filters.participantId)
161
+ query.set('participantId', filters.participantId);
162
+ if (filters.readable !== undefined)
163
+ query.set('readable', String(filters.readable));
164
+ const qs = query.toString();
159
165
  // empty array only for a genuine empty 200; any failure (non-2xx /
160
166
  // network) throws so ziggs_chat_list reports a real error instead of "you
161
167
  // have no chats". HTTP failures are ApiError (status/body/code).
162
168
  let res;
163
169
  try {
164
- res = await fetch(`${getBackendUrl()}/chats/mine`, {
170
+ res = await fetch(`${getBackendUrl()}/chats/mine${qs ? `?${qs}` : ''}`, {
165
171
  method: 'GET',
166
172
  headers: buildHeaders(creds),
167
173
  });
@@ -98,11 +98,11 @@ export declare class ContextGrantsClient {
98
98
  issueGrant(input: IssueContextGrantInput): Promise<GrantView>;
99
99
  /** Request-only endpoint: a successful call must still have granted no access. */
100
100
  requestAccess(input: {
101
- scopeKind: 'artifact' | 'chat' | 'agreement' | 'task';
101
+ scopeKind: 'artifact' | 'chat' | 'agreement' | 'task' | 'person';
102
102
  scopeId?: string;
103
103
  agreementId?: string;
104
104
  reason: string;
105
- permission?: 'read' | 'reply' | 'work';
105
+ permission?: 'read' | 'reply' | 'work' | 'list';
106
106
  temporal?: 'from-now' | 'from-start';
107
107
  durationHours?: number;
108
108
  chatId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/api-client",
3
- "version": "0.37.7",
3
+ "version": "0.37.8",
4
4
  "description": "HTTP and WebSocket client for the Ziggs backend API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",