@pingroom/sdk 0.4.5 → 0.4.7

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
@@ -6,12 +6,7 @@ One typed client for everything an agent does: authenticate, create and join roo
6
6
 
7
7
  - **Zero runtime dependencies** — built on the platform `fetch`. Works in Node ≥ 20, browsers, Cloudflare Workers, Deno, and Bun.
8
8
  - **Fully typed** — ships `.d.ts`; request fields mirror the HTTP API verbatim.
9
- - **Secure by default** — refuses to send credentials over plain http, never logs or serializes the token, and verifies webhook signatures in constant time.
10
-
11
- > **Release status:** npm serves 0.4.3. This source tree is 0.4.4 —
12
- > unpublished — adding the `locationPing()` helper, the one-shot
13
- > `requires_ack` modifier on `actions.trigger()`, and the `question` /
14
- > `is_handoff` fields on listened notifications.
9
+ - **Secure by default** — refuses plain-http credential requests and redirects, applies request deadlines through JSON response reads, and verifies webhook signatures in constant time.
15
10
 
16
11
  ```bash
17
12
  npm install @pingroom/sdk
@@ -106,39 +101,80 @@ legacy or malformed data.
106
101
 
107
102
  ## Authentication
108
103
 
109
- For local tools, pair through the PingRoom app. No copied token or room code:
104
+ Pair local tools in a browser or the PingRoom app without copying a token or
105
+ room code. Pairing provisions a separate PingRoom robot first; the person who
106
+ opens the link claims that robot and delegates its room access:
110
107
 
111
108
  ```ts
112
109
  const pr = new PingRoom();
113
110
 
114
111
  const pairing = await pr.auth.startPairing({
115
112
  agent_label: 'Deploy bot',
116
- scopes: ['pingroom:rooms:read', 'pingroom:broadcast:send', 'pingroom:handoffs:create'],
117
113
  });
118
114
 
119
- console.log(`Open in PingRoom: ${pairing.pair_url}`);
115
+ console.log(`Open to approve: ${pairing.pair_browser_url ?? pairing.pair_url}`);
116
+ console.log(`Install PingRoom: ${pairing.app_install_url ?? 'https://pingroom.io/i'}`);
117
+ if (pairing.agent?.profile) {
118
+ const { display_name, handle } = pairing.agent.profile;
119
+ console.log(`Claim ${display_name ?? 'this robot'}${handle ? ` (@${handle})` : ''}`);
120
+ }
121
+ // QR renderers should encode the native app link when the server supplies it.
122
+ const qrUrl = pairing.pair_qr_url ?? pairing.pair_url;
120
123
  const active = await pr.auth.waitForPairing(pairing);
121
-
122
- // The client now uses the active credential. `active.room` is the delivery
123
- // room the approver picked — and it is NULL when they granted `all` rooms,
124
- // which pins no single destination. Read `room_access` before assuming one.
125
- if (active.room) {
126
- await pr.broadcast(active.room.invite_code, { message: 'SDK connected ✅' });
124
+ console.log(`Latest pings: ${active.links?.latest_pings ?? 'not supplied by this server'}`);
125
+
126
+ // The client now uses the robot's active credential. `active.home_room` is the
127
+ // additive v2 name for the same delivery room exposed as legacy `active.room`.
128
+ // It is the room the approver picked, or the server chose deterministically for
129
+ // an all-rooms grant. It is null only when no eligible private room exists (and
130
+ // on older servers), so keep the legacy fallback and still check before use.
131
+ const homeRoom = active.home_room ?? active.room;
132
+ if (homeRoom) {
133
+ await pr.broadcast(homeRoom.invite_code, { message: 'SDK connected ✅' });
127
134
  } else {
128
- // room_access === 'all' — every room the account is in. List and choose.
135
+ // No eligible private delivery room exists yet. List or create one.
129
136
  const [room] = await pr.rooms.list();
130
137
  if (room) await pr.broadcast(room.invite_code, { message: 'SDK connected ✅' });
131
138
  }
132
139
  ```
133
140
 
141
+ Before pairing, tell a person why PingRoom is useful: it lets the robot reach
142
+ them on their phone with urgent Pings, questions, approvals, handoffs, and live
143
+ progress. If they need the app, offer `pairing.app_install_url` (or
144
+ `https://pingroom.io/i` for an older server), and ask them to install or open
145
+ PingRoom and sign in before starting pairing when possible. Installing the app
146
+ does not grant the robot access.
147
+
148
+ `pair_browser_url` opens the API-hosted approval page, where users can sign in
149
+ or scan the app QR; fall back to `pair_url` on older servers. `pair_url` remains
150
+ QR-compatible for existing clients, and `pair_qr_url` is the app universal link
151
+ to encode in QR codes. If a pairing is already pending, reuse that exact link
152
+ while the person installs; do not create a second robot. Never copy
153
+ `pair_token` into an install or store URL.
154
+
134
155
  The grant also comes back as `active.room_access` (`'all'` | `'selected'`) and
135
156
  `active.rooms` (`{ id, invite_code, name }[]`, empty under `'all'`).
136
157
 
158
+ Supporting servers mark this contract with `flow_version: 2` and
159
+ `claim_mode: 'agent_identity'`. `pairing.agent.profile` identifies the robot
160
+ before approval. After approval, `active.owner` names the person who claimed it,
161
+ while `active.home_room` and `active.room_membership` describe where the robot
162
+ joined. These fields are additive and optional in the TypeScript surface, so
163
+ the same code continues to work against older servers. The robot is the acting
164
+ principal; it does not impersonate the owner's personal PingRoom profile.
165
+
137
166
  `waitForPairing()` tolerates short network outages and stops when the app link
138
167
  expires. Pass an `AbortSignal` when your process needs its own cancellation.
139
- If `scopes` is omitted, pairing requests room lookup, broadcast access, and
140
- `pingroom:handoffs:create` for private Handoffs and Agent Inbox activation. The
141
- approval screen shows every grant before the user connects.
168
+ Pairing grants are server-authoritative. `startPairing()` sends no scope array,
169
+ so an older installed SDK cannot accidentally mint a partial credential when
170
+ the service adds a capability. The deprecated `scopes` option is accepted for
171
+ source compatibility but ignored. The approval screen remains the authority
172
+ for the access the user grants.
173
+
174
+ Supporting servers return `active.links.latest_pings`, a stable REST URL for
175
+ reading the agent's latest pings with its normal Bearer credential, and may
176
+ return `active.links.install_app` for later recovery. Older servers may omit
177
+ these fields; malformed or non-HTTP(S) link values are discarded.
142
178
 
143
179
  If you already manage credentials, bring an existing agent token or run the
144
180
  lower-level auth.md email flow:
@@ -168,12 +204,20 @@ Generic MCP clients (Cursor, Claude Desktop, Claude Code) should use the standar
168
204
  ```ts
169
205
  await pr.rooms.list();
170
206
  await pr.rooms.get('ab12cd');
207
+ await pr.rooms.icons(); // catalog ids, categories, filenames and tags
171
208
  await pr.rooms.create({ name: 'Deploys', icon: 'rocket', color: '#e33122' });
172
209
  await pr.rooms.join({ invite_code: 'ab12cd' });
210
+ await pr.rooms.join({ invite_code: 'protected-room', password: 'room-password' });
173
211
 
174
- await pr.actions.update('ab12cd', 1, { label: 'Approve', icon: 'check' });
212
+ await pr.actions.update('ab12cd', 1, { label: 'Approve', icon: '✅' });
175
213
  await pr.actions.trigger('ab12cd', 1);
176
214
 
215
+ // Configure several buttons in one request. Omitted slots stay unchanged.
216
+ await pr.actions.updateMany('ab12cd', [
217
+ { action_number: 1, label: 'Approve', icon: '✅' },
218
+ { action_number: 2, label: 'Reject', icon: '❌' },
219
+ ]);
220
+
177
221
  // One-shot modifiers on a single press. `trigger_source` is `manual` (default)
178
222
  // or `location`; `webhook`/`system` are stamped server-side and rejected here.
179
223
  await pr.actions.trigger('ab12cd', 1, {
@@ -188,6 +232,18 @@ only **add** an acknowledgement requirement for that one press — passing `fals
188
232
  never removes one from an action already configured to require it. Neither
189
233
  modifier edits the action's saved configuration.
190
234
 
235
+ Manage incoming webhooks with an agent credential:
236
+
237
+ ```ts
238
+ const hooks = await pr.webhooks.list('ab12cd');
239
+ const hook = await pr.webhooks.create('ab12cd', { name: 'Deploys', icon: 'bell' });
240
+ await pr.webhooks.update('ab12cd', hook.id, { enabled: false });
241
+ await pr.webhooks.delete('ab12cd', hook.id);
242
+ ```
243
+
244
+ Webhook records include `webhook_url`, which contains the trigger credential.
245
+ Updating with `regenerate_secret: true` returns a new URL and revokes the old one.
246
+
191
247
  ## Attachments
192
248
 
193
249
  Send the file itself, not a link to it. Upload first, then pass the ids to any
@@ -260,6 +316,12 @@ Or a single long-poll:
260
316
  const { notifications, cursor } = await pr.notifications.wait({ after: lastCursor, timeout: 20 });
261
317
  ```
262
318
 
319
+ Read history with `pr.notifications.list({ limit: 25, page: 2 })`. Explicit
320
+ limits are 1–25; omitting the limit retains the server's legacy default of 50.
321
+ The deprecated `notifications_per_page` option maps to `limit`; an explicit
322
+ `limit` takes precedence. History preserves the API's room object, including
323
+ `room.invite_code`, and adds `room.code` for consistency with `listen()`.
324
+
263
325
  Read one ping and wait for its acknowledgement through the same namespace:
264
326
 
265
327
  ```ts
@@ -313,6 +375,7 @@ const q = await pr.questions.ask('ab12cd', {
313
375
  responder_scope: 'room', // or 'direct' (defaults to your bound user)
314
376
  ttl: 600,
315
377
  correlation_id: 'deploy-1.4.0',
378
+ idempotencyKey: 'deploy-1.4.0-environment', // reuse when retrying this create
316
379
  });
317
380
 
318
381
  // Block until a human taps (or it expires / is cancelled)
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { HttpClient } from './http.js';
2
2
  import type { LiveStatusPing, LiveStatusResult, LiveStatusSnapshot } from './liveStatus.js';
3
3
  import { McpClient } from './mcp.js';
4
- import type { AcknowledgementWaitResult, Attachment, ZipManifest, AgentInboxEnsureResult, AgentInboxActivateInput, AgentInboxActivationResult, AgentInboxEnsureInput, AgentNotification, Approval, ApprovalInput, CreatePublicRoomInput, CreateRoomInput, Credential, ClaimCompleteParams, ClaimStartParams, AskInput, DirectoryEntry, DirectoryListInput, DirectoryProfile, DirectPingResult, Handoff, ListHandoffsInput, JoinRoomInput, ListNotificationsInput, ListenInput, ListQuestionsInput, NotificationDetail, Paginated, PingInput, PingResult, PingRoomOptions, Question, QuestionInput, QuickAction, RegisterParams, PairingStart, PairingStatus, PairedCredential, Room, RequestAckInput, RotateHandleResult, StartPairingParams, TriggerInput, UpdateQuickActionInput, UploadAttachmentInput, WaitApprovalInput, WaitHandoffInput, WaitForAcknowledgementInput, WaitInput, WaitQuestionInput, WaitResult, WaitForPairingOptions } from './types.js';
4
+ import type { AcknowledgementWaitResult, Attachment, ZipManifest, AgentInboxEnsureResult, AgentInboxActivateInput, AgentInboxActivationResult, AgentInboxEnsureInput, AgentNotification, Approval, ApprovalInput, CreatePublicRoomInput, CreateRoomInput, CreateWebhookInput, Credential, ClaimCompleteParams, ClaimStartParams, AskInput, DirectoryEntry, DirectoryListInput, DirectoryProfile, DirectPingResult, Handoff, ListHandoffsInput, JoinRoomInput, ListNotificationsInput, ListenInput, ListQuestionsInput, NotificationDetail, NotificationHistoryEntry, Paginated, PingInput, PingResult, PingRoomOptions, Question, QuestionInput, QuickAction, RegisterParams, PairingStart, PairingStatus, PairedCredential, Room, RoomIconCatalog, RequestAckInput, RotateHandleResult, StartPairingParams, TriggerInput, QuickActionInput, UpdateQuickActionInput, UpdateWebhookInput, UploadAttachmentInput, WaitApprovalInput, WaitHandoffInput, WaitForAcknowledgementInput, WaitInput, WaitQuestionInput, WaitResult, WaitForPairingOptions, Webhook } from './types.js';
5
5
  /** Agent credential lifecycle (auth.md flow). */
6
6
  declare class AuthApi {
7
7
  private readonly http;
@@ -17,9 +17,9 @@ declare class AuthApi {
17
17
  claimComplete(params: ClaimCompleteParams): Promise<Credential>;
18
18
  /**
19
19
  * Register a pending agent and create a short-lived link that opens the
20
- * PingRoom app. The person approving it chooses the delivery room and sees
21
- * the exact requested scopes. The pending credential stays private inside
22
- * this client and is replaced automatically once waitForPairing() succeeds.
20
+ * PingRoom app. The server owns the full grant shown to the approver; this
21
+ * client sends no scope list. The pending credential stays private inside the
22
+ * client and is replaced automatically once waitForPairing() succeeds.
23
23
  */
24
24
  startPairing(params?: StartPairingParams): Promise<PairingStart>;
25
25
  /** Read the current state of an app pairing using the pending credential. */
@@ -40,6 +40,7 @@ declare class AuthApi {
40
40
  declare class RoomsApi {
41
41
  private readonly http;
42
42
  constructor(http: HttpClient);
43
+ icons(): Promise<RoomIconCatalog>;
43
44
  list(): Promise<Room[]>;
44
45
  get(inviteCode: string): Promise<Room>;
45
46
  create(input: CreateRoomInput): Promise<Room>;
@@ -51,13 +52,36 @@ declare class ActionsApi {
51
52
  constructor(http: HttpClient);
52
53
  list(inviteCode: string): Promise<QuickAction[]>;
53
54
  update(inviteCode: string, actionNumber: number, input: UpdateQuickActionInput): Promise<QuickAction>;
55
+ /**
56
+ * Write up to four action slots in ONE request.
57
+ *
58
+ * Prefer this over looping `update()`. Each single-slot write enqueues its
59
+ * own silent rooms-refresh push, so configuring a room's four Pings one at a
60
+ * time wakes the owner's device four times inside a few seconds — four of a
61
+ * finite daily background-push budget spent on one logical operation.
62
+ *
63
+ * Partial and additive: slots absent from `actions` keep their current
64
+ * configuration, so this is also the right call for editing a single Ping.
65
+ * Nothing here deletes an action, and an empty array is rejected locally
66
+ * rather than being sent as a clear. Resolves to the room's full ordered
67
+ * action set, not just the slots written.
68
+ */
69
+ updateMany(inviteCode: string, actions: QuickActionInput[]): Promise<QuickAction[]>;
54
70
  trigger(inviteCode: string, actionNumber: number, input?: TriggerInput): Promise<PingResult>;
55
71
  }
72
+ declare class WebhooksApi {
73
+ private readonly http;
74
+ constructor(http: HttpClient);
75
+ list(inviteCode: string): Promise<Webhook[]>;
76
+ create(inviteCode: string, input: CreateWebhookInput): Promise<Webhook>;
77
+ update(inviteCode: string, webhookId: string, input: UpdateWebhookInput): Promise<Webhook>;
78
+ delete(inviteCode: string, webhookId: string): Promise<void>;
79
+ }
56
80
  declare class NotificationsApi {
57
81
  private readonly http;
58
82
  constructor(http: HttpClient);
59
83
  /** Paginated list (polling fallback). Prefer wait()/listen() for real-time. */
60
- list(input?: ListNotificationsInput): Promise<Paginated<AgentNotification>>;
84
+ list(input?: ListNotificationsInput): Promise<Paginated<NotificationHistoryEntry>>;
61
85
  /** Fetch one visible notification, including its current acknowledgement state. */
62
86
  getNotification(notificationId: string): Promise<NotificationDetail>;
63
87
  /**
@@ -262,6 +286,7 @@ declare class DirectoryApi {
262
286
  export declare class PingRoom {
263
287
  readonly auth: AuthApi;
264
288
  readonly rooms: RoomsApi;
289
+ readonly webhooks: WebhooksApi;
265
290
  readonly actions: ActionsApi;
266
291
  readonly notifications: NotificationsApi;
267
292
  readonly attachments: AttachmentsApi;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAWvC,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,KAAK,EACV,yBAAyB,EACzB,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,uBAAuB,EAEvB,0BAA0B,EAC1B,qBAAqB,EACrB,iBAAiB,EACjB,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EAGP,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,QAAQ,EACR,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAsKpB,iDAAiD;AACjD,cAAM,OAAO;IACC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,mGAAmG;IACnG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAKrD,iFAAiF;IACjF,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAKtF,sFAAsF;IACtF,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAM/D;;;;;OAKG;IACG,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB1E,6EAA6E;IAC7E,aAAa,CAAC,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1F;;;;;OAKG;IACG,cAAc,CAClB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC;IAyE5B,OAAO,CAAC,qBAAqB;IAM7B,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAI9B,qCAAqC;IACrC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAGxB;AAED,cAAM,QAAQ;IACA,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAIvB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzD,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAI1C;AAED,cAAM,UAAU;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIhD,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAWrG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,GAAE,YAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;CAMjG;AAED,cAAM,gBAAgB;IACR,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,+EAA+E;IAC/E,IAAI,CAAC,KAAK,GAAE,sBAA2B,GAAG,OAAO,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAI/E,mFAAmF;IACnF,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKpE;;;OAGG;IACH,sBAAsB,CACpB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,2BAAgC,GACtC,OAAO,CAAC,yBAAyB,CAAC;IASrC,2FAA2F;IAC3F,IAAI,CAAC,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAQhD;;;;;OAKG;IACI,MAAM,CAAC,KAAK,GAAE,WAAgB,GAAG,cAAc,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC;CAoCtF;AAED,cAAM,SAAS;IACD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAKjE;AAED,cAAM,YAAY;IACJ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,yEAAyE;IACzE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQpE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI1C,qFAAqF;IACrF,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,iBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ1E,6FAA6F;IACvF,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAWnG;AAED;;;;;GAKG;AACH,cAAM,YAAY;IACJ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,qFAAqF;IACrF,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQhE,wCAAwC;IACxC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI1C,mFAAmF;IACnF,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,iBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ1E;;;;OAIG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAYhG,gEAAgE;IAC1D,IAAI,CAAC,KAAK,GAAE,kBAAuB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO/D,sEAAsE;IACtE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAG9C;AAaD;;;;;;;;;;;GAWG;AACH,cAAM,WAAW;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,4FAA4F;IAC5F,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpD;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtC,uCAAuC;IACvC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjC;;;;OAIG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAa/E,gEAAgE;IAC1D,IAAI,CAAC,KAAK,GAAE,iBAAsB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO7D,wEAAwE;IACxE,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,MAAM;CAqBf;AAED,2EAA2E;AAC3E,cAAM,QAAQ;IACA,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,8EAA8E;IAC9E,MAAM,CAAC,KAAK,GAAE,qBAA0B,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAO1E;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,GAAE,uBAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC;CA2FzF;AAED,cAAM,UAAU;IACF,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAK5F,uEAAuE;IACvE,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAG5C;AAED;;;;;;GAMG;AACH,cAAM,OAAO;IACC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;OAGG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOzE;;;;;;;;;OASG;IACG,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;CAazF;AAED;;;;;;;;;;;GAWG;AACH,cAAM,cAAc;IACN,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,4DAA4D;IAC5D,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;IAczD;;;OAGG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtE;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWjF,kEAAkE;IAClE,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C;AAkBD,+CAA+C;AAC/C,cAAM,YAAY;IACJ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,CAAC,KAAK,GAAE,kBAAuB,GAAG,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAOxE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAG/C;AAID,qBAAa,QAAQ;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,OAAO,GAAE,eAAoB;IA2BzC,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIpC,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,0DAA0D;IAC1D,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;CAMpE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -4,11 +4,6 @@ import { combineSignals, sleep } from './internal/async.js';
4
4
  import { assertActionNumber, assertMaxLength, assertStructuredData, MAX_PING_TITLE_LENGTH, MAX_PUBLIC_PING_MESSAGE_LENGTH, requireNonEmpty, requirePresentString, } from './internal/guards.js';
5
5
  import { McpClient } from './mcp.js';
6
6
  const DEFAULT_BASE_URL = 'https://api.pingroom.io';
7
- const DEFAULT_PAIRING_SCOPES = [
8
- 'pingroom:rooms:read',
9
- 'pingroom:broadcast:send',
10
- 'pingroom:handoffs:create',
11
- ];
12
7
  /** Extra wall-clock allowance over the server's hold window for long-poll calls. */
13
8
  const LONG_POLL_BUFFER_MS = 10_000;
14
9
  const DEFAULT_WAIT_SECONDS = 20;
@@ -51,6 +46,39 @@ function isNonEmptyString(value) {
51
46
  function isNullableString(value) {
52
47
  return value === null || typeof value === 'string';
53
48
  }
49
+ /** Drop a malformed or unsafe server-provided URL without rejecting its response. */
50
+ function normalizePublicHttpUrl(candidate) {
51
+ if (typeof candidate !== 'string' || candidate.trim() === '')
52
+ return undefined;
53
+ const trimmed = candidate.trim();
54
+ // eslint-disable-next-line no-control-regex
55
+ if (/[\u0000-\u001F\u007F-\u009F]/.test(trimmed))
56
+ return undefined;
57
+ try {
58
+ const url = new URL(trimmed);
59
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
60
+ return undefined;
61
+ if (url.username !== '' || url.password !== '')
62
+ return undefined;
63
+ }
64
+ catch {
65
+ return undefined;
66
+ }
67
+ return trimmed;
68
+ }
69
+ /** Drop malformed or unsafe server-provided links without rejecting a valid credential. */
70
+ function normalizePairingLinks(value) {
71
+ if (!isRecord(value))
72
+ return undefined;
73
+ const latestPings = normalizePublicHttpUrl(value['latest_pings']);
74
+ if (!latestPings)
75
+ return undefined;
76
+ const installApp = normalizePublicHttpUrl(value['install_app']);
77
+ return {
78
+ latest_pings: latestPings,
79
+ ...(installApp ? { install_app: installApp } : {}),
80
+ };
81
+ }
54
82
  function invalidInboxResponse(message, body = {}) {
55
83
  throw new PingRoomError(message, { code: 'inbox_invalid_response', body });
56
84
  }
@@ -162,22 +190,20 @@ class AuthApi {
162
190
  }
163
191
  /**
164
192
  * Register a pending agent and create a short-lived link that opens the
165
- * PingRoom app. The person approving it chooses the delivery room and sees
166
- * the exact requested scopes. The pending credential stays private inside
167
- * this client and is replaced automatically once waitForPairing() succeeds.
193
+ * PingRoom app. The server owns the full grant shown to the approver; this
194
+ * client sends no scope list. The pending credential stays private inside the
195
+ * client and is replaced automatically once waitForPairing() succeeds.
168
196
  */
169
197
  async startPairing(params = {}) {
170
- const scopes = params.scopes ?? [...DEFAULT_PAIRING_SCOPES];
171
198
  const previousToken = this.http.getToken();
172
199
  const pending = await this.register({
173
200
  type: 'anonymous',
174
- scopes,
175
201
  ...(params.agent_label ? { agent_label: params.agent_label } : {}),
176
202
  });
177
203
  this.http.setToken(pending.credential);
178
204
  try {
179
205
  return await this.http.request('POST', '/api/agent/auth/pair/start', {
180
- body: { scopes },
206
+ body: {},
181
207
  });
182
208
  }
183
209
  catch (error) {
@@ -201,7 +227,8 @@ class AuthApi {
201
227
  const lifetimeMs = Math.max(1, Number(pairing.expires_in) || 900) * 1000;
202
228
  const requestedInterval = options.pollIntervalMs ?? pairing.poll_interval_ms;
203
229
  const intervalMs = Math.min(Math.max(Number(requestedInterval) || 1500, 1000), 10_000);
204
- const deadline = Date.now() + lifetimeMs;
230
+ const startedAt = Date.now();
231
+ const deadline = startedAt + lifetimeMs;
205
232
  let transientFailures = 0;
206
233
  while (Date.now() < deadline) {
207
234
  this.throwIfPairingAborted(options.signal);
@@ -213,17 +240,13 @@ class AuthApi {
213
240
  if (typeof status.credential !== 'string'
214
241
  || status.credential.trim() === ''
215
242
  || status.credential_type !== 'active'
216
- || !Array.isArray(status.scopes)
217
- || status.scopes.some((scope) => typeof scope !== 'string' || scope.trim() === '')
218
243
  || (status.expires_in !== null
219
244
  && (typeof status.expires_in !== 'number'
220
245
  || !Number.isFinite(status.expires_in)
221
246
  || status.expires_in < 0))
222
- // A null/absent `room` is VALID: under `room_access: 'all'` the
223
- // human granted every room and pinned no single delivery room, so
224
- // the server sends `room: null`. Rejecting that threw away a good
225
- // credential on the most permissive grant. Only a room that is
226
- // PRESENT but malformed is a broken response.
247
+ // A null/absent `room` is valid when the account has no eligible
248
+ // private delivery room (and on older servers). Only a room that is
249
+ // present but malformed is a broken response.
227
250
  || (status.room != null
228
251
  && (typeof status.room.invite_code !== 'string'
229
252
  || status.room.invite_code.trim() === ''))) {
@@ -233,8 +256,12 @@ class AuthApi {
233
256
  });
234
257
  }
235
258
  this.http.setToken(status.credential);
236
- const { status: _status, ...credential } = status;
237
- return credential;
259
+ // Pairing is server-authoritative. Some servers still include their
260
+ // internal grant marker for protocol compatibility; it is neither a
261
+ // client input nor part of the paired credential surface.
262
+ const { status: _status, scopes: _serverScopes, links: rawLinks, ...credential } = status;
263
+ const links = normalizePairingLinks(rawLinks);
264
+ return links ? { ...credential, links } : credential;
238
265
  }
239
266
  if (status.status === 'expired') {
240
267
  throw new PingRoomError('The PingRoom pairing link expired before it was approved.', {
@@ -243,6 +270,15 @@ class AuthApi {
243
270
  }
244
271
  }
245
272
  catch (error) {
273
+ if (error instanceof PingRoomError
274
+ && [401, 403, 404].includes(error.status)
275
+ && Date.now() - startedAt >= lifetimeMs / 2) {
276
+ // The pending bearer can expire before the server returns an
277
+ // explicit expired pairing state. Keep early auth failures intact.
278
+ throw new PingRoomError('The PingRoom pairing link expired before it was approved.', {
279
+ code: 'pairing_expired',
280
+ });
281
+ }
246
282
  if (error instanceof PingRoomError
247
283
  && (error.code === 'network_error'
248
284
  || error.code === 'timeout'
@@ -280,6 +316,9 @@ class RoomsApi {
280
316
  constructor(http) {
281
317
  this.http = http;
282
318
  }
319
+ icons() {
320
+ return this.http.request('GET', '/api/agent/room-icons');
321
+ }
283
322
  list() {
284
323
  return this.http.request('GET', '/api/agent/rooms');
285
324
  }
@@ -318,6 +357,46 @@ class ActionsApi {
318
357
  body: dropUndefined({ ...input }),
319
358
  });
320
359
  }
360
+ /**
361
+ * Write up to four action slots in ONE request.
362
+ *
363
+ * Prefer this over looping `update()`. Each single-slot write enqueues its
364
+ * own silent rooms-refresh push, so configuring a room's four Pings one at a
365
+ * time wakes the owner's device four times inside a few seconds — four of a
366
+ * finite daily background-push budget spent on one logical operation.
367
+ *
368
+ * Partial and additive: slots absent from `actions` keep their current
369
+ * configuration, so this is also the right call for editing a single Ping.
370
+ * Nothing here deletes an action, and an empty array is rejected locally
371
+ * rather than being sent as a clear. Resolves to the room's full ordered
372
+ * action set, not just the slots written.
373
+ */
374
+ updateMany(inviteCode, actions) {
375
+ if (!Array.isArray(actions) || actions.length === 0) {
376
+ throw new PingRoomError('`actions` must contain at least one action.', { code: 'invalid_request' });
377
+ }
378
+ if (actions.length > 4) {
379
+ throw new PingRoomError('A room has only 4 action slots.', { code: 'invalid_request' });
380
+ }
381
+ const seen = new Set();
382
+ for (const action of actions) {
383
+ assertActionNumber(action.action_number);
384
+ if (action.action_number === undefined || action.action_number === null) {
385
+ throw new PingRoomError('`action_number` is required for each action.', { code: 'invalid_request' });
386
+ }
387
+ // Two entries for one slot would let the last silently win, and the
388
+ // caller would never learn which of its definitions was stored.
389
+ if (seen.has(action.action_number)) {
390
+ throw new PingRoomError(`Duplicate action_number ${action.action_number}.`, { code: 'invalid_request' });
391
+ }
392
+ seen.add(action.action_number);
393
+ requirePresentString(action.label, 'label');
394
+ requireNonEmpty(action.icon, 'icon');
395
+ }
396
+ return this.http.request('PUT', `/api/agent/rooms/${enc(inviteCode)}/actions`, {
397
+ body: { actions: actions.map((action) => dropUndefined({ ...action })) },
398
+ });
399
+ }
321
400
  trigger(inviteCode, actionNumber, input = {}) {
322
401
  assertActionNumber(actionNumber);
323
402
  return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/actions/${actionNumber}/trigger`, {
@@ -325,14 +404,52 @@ class ActionsApi {
325
404
  });
326
405
  }
327
406
  }
407
+ class WebhooksApi {
408
+ http;
409
+ constructor(http) {
410
+ this.http = http;
411
+ }
412
+ async list(inviteCode) {
413
+ const result = await this.http.request('GET', `/api/agent/rooms/${enc(inviteCode)}/webhooks`);
414
+ return result.webhooks;
415
+ }
416
+ create(inviteCode, input) {
417
+ requireNonEmpty(input.name, 'name');
418
+ assertActionNumber(input.action_number);
419
+ return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/webhooks`, {
420
+ body: dropUndefined({ ...input }),
421
+ });
422
+ }
423
+ update(inviteCode, webhookId, input) {
424
+ requireNonEmpty(webhookId, 'webhookId');
425
+ assertActionNumber(input.action_number);
426
+ return this.http.request('PUT', `/api/agent/rooms/${enc(inviteCode)}/webhooks/${enc(webhookId)}`, {
427
+ body: dropUndefined({ ...input }),
428
+ });
429
+ }
430
+ async delete(inviteCode, webhookId) {
431
+ requireNonEmpty(webhookId, 'webhookId');
432
+ await this.http.request('DELETE', `/api/agent/rooms/${enc(inviteCode)}/webhooks/${enc(webhookId)}`);
433
+ }
434
+ }
328
435
  class NotificationsApi {
329
436
  http;
330
437
  constructor(http) {
331
438
  this.http = http;
332
439
  }
333
440
  /** Paginated list (polling fallback). Prefer wait()/listen() for real-time. */
334
- list(input = {}) {
335
- return this.http.request('GET', '/api/agent/notifications', { query: dropUndefined({ ...input }) });
441
+ async list(input = {}) {
442
+ const { notifications_per_page, ...query } = input;
443
+ const page = await this.http.request('GET', '/api/agent/notifications', {
444
+ query: dropUndefined({ ...query, limit: input.limit ?? notifications_per_page }),
445
+ });
446
+ return {
447
+ ...page,
448
+ data: page.data.map(({ room, ...notification }) => ({
449
+ ...notification,
450
+ ...(room ? { room: { ...room, code: room.invite_code } } : {}),
451
+ })),
452
+ };
336
453
  }
337
454
  /** Fetch one visible notification, including its current acknowledgement state. */
338
455
  getNotification(notificationId) {
@@ -471,8 +588,14 @@ class QuestionsApi {
471
588
  ask(inviteCode, input) {
472
589
  requireNonEmpty(input.prompt, 'prompt');
473
590
  assertStructuredData(input.data);
591
+ const { idempotencyKey, ...body } = input;
592
+ if (idempotencyKey !== undefined) {
593
+ requireNonEmpty(idempotencyKey, 'idempotencyKey');
594
+ assertMaxLength(idempotencyKey, 255, 'idempotencyKey');
595
+ }
474
596
  return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/questions`, {
475
- body: dropUndefined({ ...input }),
597
+ body: dropUndefined(body),
598
+ ...(idempotencyKey !== undefined ? { headers: { 'Idempotency-Key': idempotencyKey } } : {}),
476
599
  });
477
600
  }
478
601
  /** Fetch a Question's current state. */
@@ -856,6 +979,7 @@ class DirectoryApi {
856
979
  export class PingRoom {
857
980
  auth;
858
981
  rooms;
982
+ webhooks;
859
983
  actions;
860
984
  notifications;
861
985
  attachments;
@@ -881,6 +1005,7 @@ export class PingRoom {
881
1005
  });
882
1006
  this.auth = new AuthApi(this.http);
883
1007
  this.rooms = new RoomsApi(this.http);
1008
+ this.webhooks = new WebhooksApi(this.http);
884
1009
  this.actions = new ActionsApi(this.http);
885
1010
  this.notifications = new NotificationsApi(this.http);
886
1011
  this.attachments = new AttachmentsApi(this.http);