@pnds/sdk 1.8.0 → 1.10.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/src/client.ts CHANGED
@@ -42,11 +42,11 @@ import type {
42
42
  Project,
43
43
  CreateProjectRequest,
44
44
  UpdateProjectRequest,
45
- AgentRunDB,
45
+ AgentSessionDB,
46
46
  AgentStep,
47
- CreateAgentRunRequest,
47
+ CreateAgentSessionRequest,
48
48
  CreateAgentStepRequest,
49
- UpdateAgentRunRequest,
49
+ UpdateAgentSessionRequest,
50
50
  OrgInvitation,
51
51
  InvitationPublicInfo,
52
52
  PlatformConfigResponse,
@@ -55,6 +55,10 @@ import type {
55
55
  WikiChangeset,
56
56
  WikiTreeResponse,
57
57
  WikiNodeSectionArtifact,
58
+ WikiSearchResponse,
59
+ WikiPageIndex,
60
+ WikiRefsResponse,
61
+ WikiRefsCheckResponse,
58
62
  WikiDiff,
59
63
  WikiPathScope,
60
64
  WikiAccessStatus,
@@ -69,9 +73,13 @@ import type {
69
73
  WikiBlameEntry,
70
74
  InboxItem,
71
75
  InboxUnreadCountResponse,
76
+ DispatchEvent,
72
77
  ResolveRefsResponse,
73
78
  BacklinksResponse,
74
79
  BrokenRefsResponse,
80
+ PushSubscribeRequest,
81
+ NotifPrefs,
82
+ NotificationPreferences,
75
83
  } from './types.js';
76
84
 
77
85
  export interface PondClientOptions {
@@ -80,6 +88,7 @@ export interface PondClientOptions {
80
88
  onTokenExpired?: () => void;
81
89
  getRefreshToken?: () => string | null;
82
90
  setTokens?: (tokens: { access_token: string; refresh_token: string }) => void;
91
+ swimlaneName?: string;
83
92
  }
84
93
 
85
94
  export class PondClient {
@@ -89,6 +98,7 @@ export class PondClient {
89
98
  private getRefreshToken?: () => string | null;
90
99
  private setTokens?: (tokens: { access_token: string; refresh_token: string }) => void;
91
100
  private refreshPromise: Promise<AuthTokens> | null = null;
101
+ private swimlaneName?: string;
92
102
 
93
103
  /** Auth endpoints excluded from automatic 401 refresh to prevent recursion. */
94
104
  private static readonly AUTH_PATHS = new Set([
@@ -99,12 +109,28 @@ export class PondClient {
99
109
  /** Proactive refresh when token expires within this window (seconds). */
100
110
  private static readonly REFRESH_THRESHOLD_S = 5 * 60;
101
111
 
112
+ /** Build headers common to all requests (auth, swimlane). */
113
+ private buildHeaders(extra?: Record<string, string>): Record<string, string> {
114
+ const headers: Record<string, string> = {
115
+ 'Content-Type': 'application/json',
116
+ ...extra,
117
+ };
118
+ if (this.token) {
119
+ headers['Authorization'] = `Bearer ${this.token}`;
120
+ }
121
+ if (this.swimlaneName) {
122
+ headers['X-Pnds-Swimlane'] = this.swimlaneName;
123
+ }
124
+ return headers;
125
+ }
126
+
102
127
  constructor(options: PondClientOptions = {}) {
103
128
  this.baseUrl = options.baseUrl ?? '';
104
129
  this.token = options.token ?? null;
105
130
  this.onTokenExpired = options.onTokenExpired;
106
131
  this.getRefreshToken = options.getRefreshToken;
107
132
  this.setTokens = options.setTokens;
133
+ this.swimlaneName = options.swimlaneName;
108
134
  }
109
135
 
110
136
  setToken(token: string | null) {
@@ -196,12 +222,7 @@ export class PondClient {
196
222
  if (qs) url += `?${qs}`;
197
223
  }
198
224
 
199
- const headers: Record<string, string> = {
200
- 'Content-Type': 'application/json',
201
- };
202
- if (this.token) {
203
- headers['Authorization'] = `Bearer ${this.token}`;
204
- }
225
+ const headers = this.buildHeaders();
205
226
 
206
227
  let res: Response;
207
228
  try {
@@ -534,31 +555,31 @@ export class PondClient {
534
555
  return this.request('GET', ENDPOINTS.AGENT_ME(orgId));
535
556
  }
536
557
 
537
- // ---- Agent Runs (org-scoped) ----
558
+ // ---- Agent Sessions (org-scoped) ----
538
559
 
539
- async createAgentRun(orgId: string, agentId: string, req: CreateAgentRunRequest): Promise<AgentRunDB> {
540
- return this.request('POST', ENDPOINTS.AGENT_RUNS(orgId, agentId), req);
560
+ async createAgentSession(orgId: string, agentId: string, req: CreateAgentSessionRequest): Promise<AgentSessionDB> {
561
+ return this.request('POST', ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
541
562
  }
542
563
 
543
- async getAgentRuns(orgId: string, agentId: string, params?: { limit?: number }): Promise<AgentRunDB[]> {
544
- const res = await this.request<{ data: AgentRunDB[] }>('GET', ENDPOINTS.AGENT_RUNS(orgId, agentId), undefined, params);
564
+ async getAgentSessions(orgId: string, agentId: string, params?: { limit?: number; status?: string }): Promise<AgentSessionDB[]> {
565
+ const res = await this.request<{ data: AgentSessionDB[] }>('GET', ENDPOINTS.AGENT_SESSIONS(orgId, agentId), undefined, params);
545
566
  return res.data;
546
567
  }
547
568
 
548
- async getAgentRun(orgId: string, agentId: string, runId: string): Promise<AgentRunDB> {
549
- return this.request('GET', ENDPOINTS.AGENT_RUN(orgId, agentId, runId));
569
+ async getAgentSession(orgId: string, agentId: string, sessionId: string): Promise<AgentSessionDB> {
570
+ return this.request('GET', ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId));
550
571
  }
551
572
 
552
- async updateAgentRun(orgId: string, agentId: string, runId: string, req: UpdateAgentRunRequest): Promise<AgentRunDB> {
553
- return this.request('PATCH', ENDPOINTS.AGENT_RUN(orgId, agentId, runId), req);
573
+ async updateAgentSession(orgId: string, agentId: string, sessionId: string, req: UpdateAgentSessionRequest): Promise<AgentSessionDB> {
574
+ return this.request('PATCH', ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId), req);
554
575
  }
555
576
 
556
- async createAgentStep(orgId: string, agentId: string, runId: string, req: CreateAgentStepRequest): Promise<AgentStep> {
557
- return this.request('POST', ENDPOINTS.AGENT_RUN_STEPS(orgId, agentId, runId), req);
577
+ async createAgentStep(orgId: string, agentId: string, sessionId: string, req: CreateAgentStepRequest): Promise<AgentStep> {
578
+ return this.request('POST', ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), req);
558
579
  }
559
580
 
560
- async getAgentRunSteps(orgId: string, agentId: string, runId: string, params?: { limit?: number }): Promise<AgentStep[]> {
561
- const res = await this.request<{ data: AgentStep[] }>('GET', ENDPOINTS.AGENT_RUN_STEPS(orgId, agentId, runId), undefined, params);
581
+ async getAgentSessionSteps(orgId: string, agentId: string, sessionId: string, params?: { limit?: number }): Promise<AgentStep[]> {
582
+ const res = await this.request<{ data: AgentStep[] }>('GET', ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), undefined, params);
562
583
  return res.data;
563
584
  }
564
585
 
@@ -635,7 +656,7 @@ export class PondClient {
635
656
  // ---- Inbox ----
636
657
 
637
658
  async getInbox(orgId: string, params?: {
638
- type?: string; reason?: string; read?: string;
659
+ type?: string; read?: string;
639
660
  limit?: number; cursor?: string;
640
661
  }): Promise<PaginatedResponse<InboxItem>> {
641
662
  return this.request('GET', ENDPOINTS.INBOX(orgId), undefined, params as Record<string, string>);
@@ -672,6 +693,26 @@ export class PondClient {
672
693
  return this.request('DELETE', ENDPOINTS.INBOX_ITEM(orgId, id));
673
694
  }
674
695
 
696
+ // ---- Dispatch (agent event delivery) ----
697
+
698
+ async getDispatch(orgId: string, params?: {
699
+ limit?: number; cursor?: string;
700
+ }): Promise<PaginatedResponse<DispatchEvent>> {
701
+ return this.request('GET', ENDPOINTS.DISPATCH(orgId), undefined, params as Record<string, string>);
702
+ }
703
+
704
+ async getDispatchPendingCount(orgId: string): Promise<{ count: number }> {
705
+ return this.request('GET', ENDPOINTS.DISPATCH_PENDING_COUNT(orgId));
706
+ }
707
+
708
+ async ackDispatch(orgId: string, source: { source_type: string; source_id: string }): Promise<void> {
709
+ return this.request('POST', ENDPOINTS.DISPATCH_ACK(orgId), source);
710
+ }
711
+
712
+ async ackDispatchByID(orgId: string, id: string): Promise<void> {
713
+ return this.request('POST', ENDPOINTS.DISPATCH_ACK_BY_ID(orgId, id));
714
+ }
715
+
675
716
  // ---- Platform Config ----
676
717
 
677
718
  /**
@@ -681,15 +722,11 @@ export class PondClient {
681
722
  */
682
723
  async getPlatformConfig(currentVersion?: string): Promise<PlatformConfigResponse | null> {
683
724
  const url = `${this.baseUrl}${ENDPOINTS.PLATFORM_CONFIG}`;
684
- const headers: Record<string, string> = {
685
- 'Content-Type': 'application/json',
686
- };
687
- if (this.token) {
688
- headers['Authorization'] = `Bearer ${this.token}`;
689
- }
725
+ const extra: Record<string, string> = {};
690
726
  if (currentVersion !== undefined) {
691
- headers['If-None-Match'] = currentVersion;
727
+ extra['If-None-Match'] = currentVersion;
692
728
  }
729
+ const headers = this.buildHeaders(extra);
693
730
 
694
731
  const res = await fetch(url, {
695
732
  method: 'GET',
@@ -842,6 +879,22 @@ export class PondClient {
842
879
  return this.request('GET', ENDPOINTS.WIKI_NODE_SECTIONS(orgId, wikiId), undefined, params);
843
880
  }
844
881
 
882
+ async searchWiki(orgId: string, wikiId: string, params: { q: string; limit?: number; path_prefix?: string; ref?: string }): Promise<WikiSearchResponse> {
883
+ return this.request('GET', ENDPOINTS.WIKI_SEARCH(orgId, wikiId), undefined, params);
884
+ }
885
+
886
+ async getWikiPageIndex(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiPageIndex> {
887
+ return this.request('GET', ENDPOINTS.WIKI_PAGE_INDEX(orgId, wikiId), undefined, params);
888
+ }
889
+
890
+ async getWikiRefs(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiRefsResponse> {
891
+ return this.request('GET', ENDPOINTS.WIKI_REFS(orgId, wikiId), undefined, params);
892
+ }
893
+
894
+ async checkWikiRefs(orgId: string, wikiId: string, params?: { ref?: string }): Promise<WikiRefsCheckResponse> {
895
+ return this.request('GET', ENDPOINTS.WIKI_REFS_CHECK(orgId, wikiId), undefined, params);
896
+ }
897
+
845
898
  async createWikiChangeset(orgId: string, wikiId: string, data: CreateWikiChangesetRequest): Promise<WikiChangeset> {
846
899
  return normalizeWikiChangeset(await this.request('POST', ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId), data));
847
900
  }
@@ -961,6 +1014,30 @@ export class PondClient {
961
1014
  async checkBrokenRefs(orgId: string): Promise<BrokenRefsResponse> {
962
1015
  return this.request('GET', ENDPOINTS.REFS_CHECK(orgId));
963
1016
  }
1017
+
1018
+ // ---- Push Notifications ----
1019
+
1020
+ async subscribePush(body: PushSubscribeRequest): Promise<void> {
1021
+ return this.request('POST', ENDPOINTS.PUSH_SUBSCRIBE, body);
1022
+ }
1023
+
1024
+ async unsubscribePush(token: string): Promise<void> {
1025
+ return this.request('DELETE', ENDPOINTS.PUSH_UNSUBSCRIBE, { token });
1026
+ }
1027
+
1028
+ async getVapidKey(): Promise<{ vapid_public_key: string }> {
1029
+ return this.request('GET', ENDPOINTS.PUSH_VAPID_KEY);
1030
+ }
1031
+
1032
+ // ---- Notification Preferences ----
1033
+
1034
+ async getNotificationPreferences(): Promise<NotificationPreferences> {
1035
+ return this.request('GET', ENDPOINTS.NOTIFICATION_PREFERENCES);
1036
+ }
1037
+
1038
+ async updateNotificationPreferences(prefs: Partial<NotifPrefs>): Promise<NotificationPreferences> {
1039
+ return this.request('PATCH', ENDPOINTS.NOTIFICATION_PREFERENCES, { prefs });
1040
+ }
964
1041
  }
965
1042
 
966
1043
  function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
package/src/constants.ts CHANGED
@@ -70,12 +70,12 @@ export const ENDPOINTS = {
70
70
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
71
71
  AGENT_ME: (orgId: string) =>
72
72
  `${API_BASE}/orgs/${orgId}/agents/me`,
73
- AGENT_RUNS: (orgId: string, agentId: string) =>
74
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs`,
75
- AGENT_RUN: (orgId: string, agentId: string, runId: string) =>
76
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs/${runId}`,
77
- AGENT_RUN_STEPS: (orgId: string, agentId: string, runId: string) =>
78
- `${API_BASE}/orgs/${orgId}/agents/${agentId}/runs/${runId}/steps`,
73
+ AGENT_SESSIONS: (orgId: string, agentId: string) =>
74
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
75
+ AGENT_SESSION: (orgId: string, agentId: string, sessionId: string) =>
76
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
77
+ AGENT_SESSION_STEPS: (orgId: string, agentId: string, sessionId: string) =>
78
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
79
79
  AGENT_TASKS: (orgId: string, agentId: string) =>
80
80
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/tasks`,
81
81
  // Machines (org-scoped)
@@ -135,6 +135,10 @@ export const ENDPOINTS = {
135
135
  WIKI_TREE: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
136
136
  WIKI_BLOB: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
137
137
  WIKI_NODE_SECTIONS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
138
+ WIKI_SEARCH: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/search`,
139
+ WIKI_PAGE_INDEX: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/page-index`,
140
+ WIKI_REFS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/refs`,
141
+ WIKI_REFS_CHECK: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/refs/check`,
138
142
  WIKI_CHANGESETS: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/changesets`,
139
143
  WIKI_CHANGESET: (orgId: string, wikiId: string, changesetId: string) =>
140
144
  `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/changesets/${changesetId}`,
@@ -180,6 +184,12 @@ export const ENDPOINTS = {
180
184
  INBOX_ITEM: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/inbox/${id}`,
181
185
  INBOX_ACK: (orgId: string) => `${API_BASE}/orgs/${orgId}/inbox/ack`,
182
186
 
187
+ // Dispatch (agent event delivery)
188
+ DISPATCH: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch`,
189
+ DISPATCH_PENDING_COUNT: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/pending-count`,
190
+ DISPATCH_ACK: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/ack`,
191
+ DISPATCH_ACK_BY_ID: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/dispatch/${id}/ack`,
192
+
183
193
  // Unread
184
194
  UNREAD: `${API_BASE}/me/unread`,
185
195
  CHAT_READ: (orgId: string, chatId: string) =>
@@ -193,6 +203,14 @@ export const ENDPOINTS = {
193
203
  // Platform config (agent-scoped, not org-scoped)
194
204
  PLATFORM_CONFIG: `${API_BASE}/agents/platform-config`,
195
205
 
206
+ // Push notifications
207
+ PUSH_SUBSCRIBE: `${API_BASE}/push/subscribe`,
208
+ PUSH_UNSUBSCRIBE: `${API_BASE}/push/unsubscribe`,
209
+ PUSH_VAPID_KEY: `${API_BASE}/push/vapid-key`,
210
+
211
+ // Notification preferences
212
+ NOTIFICATION_PREFERENCES: `${API_BASE}/notification-preferences`,
213
+
196
214
  } as const;
197
215
 
198
216
  // WebSocket event types
@@ -200,8 +218,6 @@ export const WS_EVENTS = {
200
218
  // Client -> Server
201
219
  PING: 'ping',
202
220
  TYPING: 'typing',
203
- ACK: 'ack',
204
- READ: 'read',
205
221
  WATCH: 'watch',
206
222
  AGENT_HEARTBEAT: 'agent.heartbeat',
207
223
 
@@ -228,8 +244,8 @@ export const WS_EVENTS = {
228
244
  PROJECT_CREATED: 'project.created',
229
245
  PROJECT_UPDATED: 'project.updated',
230
246
  PROJECT_DELETED: 'project.deleted',
231
- AGENT_RUN_NEW: 'agent_run.new',
232
- AGENT_RUN_UPDATE: 'agent_run.update',
247
+ AGENT_SESSION_NEW: 'agent_session.new',
248
+ AGENT_SESSION_UPDATE: 'agent_session.update',
233
249
  AGENT_STEP_NEW: 'agent_step.new',
234
250
  INVITATION_NEW: 'invitation.new',
235
251
  INVITATION_ACCEPTED: 'invitation.accepted',
@@ -238,7 +254,9 @@ export const WS_EVENTS = {
238
254
  PRESENCE_UPDATE: 'presence.update',
239
255
  WIKI_CHANGESET_CREATED: 'wiki.changeset.created',
240
256
  WIKI_CHANGESET_UPDATED: 'wiki.changeset.updated',
241
- NOTIFICATION_NEW: 'notification.new',
242
- NOTIFICATION_UPDATE: 'notification.update',
243
- NOTIFICATION_BULK_UPDATE: 'notification.bulk_update',
257
+ INBOX_NEW: 'inbox.new',
258
+ INBOX_UPDATE: 'inbox.update',
259
+ INBOX_BULK_UPDATE: 'inbox.bulk_update',
260
+ READ_POSITION_UPDATED: 'read_position.updated',
261
+ DISPATCH_NEW: 'dispatch.new',
244
262
  } as const;