@recursiv/sdk 0.7.50 → 0.7.52

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.
Files changed (44) hide show
  1. package/README.md +69 -12
  2. package/dist/client.js +3 -1
  3. package/dist/index.d.ts +13 -6
  4. package/dist/index.js +5 -1
  5. package/dist/realtime.d.ts +79 -9
  6. package/dist/realtime.js +339 -76
  7. package/dist/resources/admin.d.ts +13 -0
  8. package/dist/resources/agents.d.ts +41 -4
  9. package/dist/resources/agents.js +45 -24
  10. package/dist/resources/app-subscriptions.d.ts +102 -4
  11. package/dist/resources/app-subscriptions.js +43 -3
  12. package/dist/resources/auth.d.ts +198 -2
  13. package/dist/resources/auth.js +397 -3
  14. package/dist/resources/boosts.d.ts +170 -0
  15. package/dist/resources/boosts.js +75 -0
  16. package/dist/resources/chat.d.ts +33 -3
  17. package/dist/resources/chat.js +38 -2
  18. package/dist/resources/communities.d.ts +23 -11
  19. package/dist/resources/communities.js +20 -6
  20. package/dist/resources/curator.d.ts +24 -6
  21. package/dist/resources/curator.js +2 -1
  22. package/dist/resources/deployments.d.ts +8 -3
  23. package/dist/resources/discovery.d.ts +15 -1
  24. package/dist/resources/discovery.js +29 -1
  25. package/dist/resources/invite-codes-admin.d.ts +13 -0
  26. package/dist/resources/invite-codes.d.ts +10 -0
  27. package/dist/resources/invite-codes.js +6 -6
  28. package/dist/resources/notifications.d.ts +74 -5
  29. package/dist/resources/notifications.js +38 -8
  30. package/dist/resources/posts.d.ts +28 -5
  31. package/dist/resources/posts.js +13 -4
  32. package/dist/resources/profiles.d.ts +45 -9
  33. package/dist/resources/profiles.js +54 -3
  34. package/dist/resources/protocols.d.ts +195 -14
  35. package/dist/resources/protocols.js +77 -12
  36. package/dist/resources/settings.d.ts +25 -3
  37. package/dist/resources/settings.js +28 -2
  38. package/dist/resources/video.d.ts +19 -0
  39. package/dist/resources/video.js +8 -0
  40. package/dist/resources/wallet.d.ts +41 -1
  41. package/dist/resources/wallet.js +8 -0
  42. package/dist/types.d.ts +217 -6
  43. package/llm.md +68 -20
  44. package/package.json +2 -2
@@ -27,6 +27,17 @@ export interface VideoPlaybackToken {
27
27
  token: string;
28
28
  expires: number;
29
29
  }
30
+ /** Whether the caller may publish video in this app, and how much storage is left. */
31
+ export interface VideoEntitlement {
32
+ allowed: boolean;
33
+ /** The caller's active app-subscription tier ('free' when none, canceled or past due). */
34
+ tier: string;
35
+ /** Why video is not allowed: a tier without video, or a used-up quota. */
36
+ reason?: 'tier' | 'quota';
37
+ quotaSeconds: number;
38
+ usedSeconds: number;
39
+ remainingSeconds: number;
40
+ }
30
41
  /**
31
42
  * Video primitive. Upload is gated by the caller's paid tier + storage quota
32
43
  * (so apps stay profitable); viewing is open with a signed playback URL.
@@ -34,6 +45,14 @@ export interface VideoPlaybackToken {
34
45
  export declare class VideoResource {
35
46
  private client;
36
47
  constructor(client: HttpClient);
48
+ /**
49
+ * The check `createUpload` runs, without starting an upload: lets a composer
50
+ * gate or explain video before the member picks a file. Needs an app-bound
51
+ * key with `uploads:write`.
52
+ */
53
+ entitlement(): Promise<{
54
+ data: VideoEntitlement;
55
+ }>;
37
56
  /** Begin an upload. Returns Bunny direct-upload creds + the playbackId to attach to a post. */
38
57
  createUpload(input?: {
39
58
  title?: string;
@@ -7,6 +7,14 @@ export class VideoResource {
7
7
  constructor(client) {
8
8
  this.client = client;
9
9
  }
10
+ /**
11
+ * The check `createUpload` runs, without starting an upload: lets a composer
12
+ * gate or explain video before the member picks a file. Needs an app-bound
13
+ * key with `uploads:write`.
14
+ */
15
+ entitlement() {
16
+ return this.client.get('/video/entitlement');
17
+ }
10
18
  /** Begin an upload. Returns Bunny direct-upload creds + the playbackId to attach to a post. */
11
19
  createUpload(input) {
12
20
  return this.client.post('/video/create-upload', input ?? {});
@@ -1,5 +1,5 @@
1
1
  import type { HttpClient } from '../client.js';
2
- import type { SingleResponse } from '../types.js';
2
+ import type { PaginatedResponse, SingleResponse } from '../types.js';
3
3
  interface WalletInfo {
4
4
  configured: boolean;
5
5
  address: string | null;
@@ -37,6 +37,39 @@ export interface PayoutState {
37
37
  payouts_enabled: boolean;
38
38
  country: string | null;
39
39
  }
40
+ /** A wallet the user linked and (optionally) verified. */
41
+ export interface LinkedTokenWallet {
42
+ chain: string;
43
+ address: string;
44
+ verified_at: string | null;
45
+ }
46
+ /** The user's MINDS token balance from the off-chain ledger. */
47
+ export interface TokenBalance {
48
+ /** Signed wei as a decimal string: it exceeds Number.MAX_SAFE_INTEGER, never parse it as a number. */
49
+ offchain_wei: string;
50
+ /** The same balance in MINDS, rounded to 6 decimal places. Display only. */
51
+ offchain_minds: number;
52
+ /** How many off-chain ledger entries make up the balance. */
53
+ entries: number;
54
+ linked_wallets: LinkedTokenWallet[];
55
+ base_wallet_address: string | null;
56
+ }
57
+ /** One token ledger movement. */
58
+ export interface TokenLedgerEntry {
59
+ id: string;
60
+ category: string | null;
61
+ /** Signed wei as a decimal string. */
62
+ amount_wei: string;
63
+ amount_minds: number;
64
+ asset: string;
65
+ settlement: string;
66
+ tx_hash: string | null;
67
+ counterparty_user_id: string | null;
68
+ subject_type: string | null;
69
+ subject_id: string | null;
70
+ status: string;
71
+ occurred_at: string;
72
+ }
40
73
  export declare class WalletResource {
41
74
  private client;
42
75
  constructor(client: HttpClient);
@@ -44,6 +77,13 @@ export declare class WalletResource {
44
77
  getMyWallet(): Promise<SingleResponse<WalletInfo>>;
45
78
  /** Get wallet balance for the current user */
46
79
  getBalance(): Promise<SingleResponse<WalletBalance>>;
80
+ /** The current user's MINDS token balance (off-chain ledger) and linked wallets. */
81
+ getTokenBalance(): Promise<SingleResponse<TokenBalance>>;
82
+ /** The current user's token ledger, newest first (limit up to 200, default 50). */
83
+ getTokenLedger(params?: {
84
+ limit?: number;
85
+ offset?: number;
86
+ }): Promise<PaginatedResponse<TokenLedgerEntry>>;
47
87
  /** USD payout eligibility for the current app user (Stripe Connect). */
48
88
  getPayouts(): Promise<SingleResponse<PayoutState>>;
49
89
  /** Start or resume payout onboarding. Open the returned URL in a browser. */
@@ -11,6 +11,14 @@ export class WalletResource {
11
11
  getBalance() {
12
12
  return this.client.get('/wallet/balance');
13
13
  }
14
+ /** The current user's MINDS token balance (off-chain ledger) and linked wallets. */
15
+ getTokenBalance() {
16
+ return this.client.get('/wallet/token-balance');
17
+ }
18
+ /** The current user's token ledger, newest first (limit up to 200, default 50). */
19
+ getTokenLedger(params) {
20
+ return this.client.get('/wallet/token-ledger', params);
21
+ }
14
22
  /** USD payout eligibility for the current app user (Stripe Connect). */
15
23
  getPayouts() {
16
24
  return this.client.get('/wallet/payouts');
package/dist/types.d.ts CHANGED
@@ -92,7 +92,14 @@ export interface User extends UserSummary {
92
92
  posts_count: number;
93
93
  created_at: string;
94
94
  }
95
- export interface FollowUser {
95
+ /** The caller's follow relationship with a listed account (both directions). */
96
+ export interface ViewerRelationship {
97
+ /** The caller follows this account. */
98
+ is_following: boolean;
99
+ /** This account follows the caller. */
100
+ follows_you: boolean;
101
+ }
102
+ export interface FollowUser extends ViewerRelationship {
96
103
  id: string;
97
104
  name: string;
98
105
  username: string;
@@ -155,7 +162,10 @@ export interface RepostedPost {
155
162
  created_at: string;
156
163
  }
157
164
  export interface PostDetail extends Post {
165
+ /** The newest replies (at most 50). */
158
166
  replies: PostReply[];
167
+ /** Present when the thread has more replies; pass it to `posts.replies(id, { cursor })` for the next, older page. */
168
+ replies_next_cursor?: string | null;
159
169
  }
160
170
  export interface PostReply {
161
171
  id: string;
@@ -164,8 +174,27 @@ export interface PostReply {
164
174
  author: UserSummary;
165
175
  tags: Tag[];
166
176
  reactions_count: number;
177
+ score?: number;
178
+ user_reaction?: string | null;
179
+ /** This reply's own reply count, so its sub-thread can be opened. */
180
+ reply_count?: number;
167
181
  created_at: string;
168
182
  }
183
+ export interface ListPostRepliesParams {
184
+ /** 1-100, default 50. */
185
+ limit?: number;
186
+ /** `replies_next_cursor` from `posts.get`, or `meta.next_cursor` from the previous page. */
187
+ cursor?: string;
188
+ }
189
+ /** One page of a post's replies, newest first. */
190
+ export interface PostRepliesPage {
191
+ data: PostReply[];
192
+ meta: {
193
+ limit: number;
194
+ has_more: boolean;
195
+ next_cursor: string | null;
196
+ };
197
+ }
169
198
  export interface CreatePostInput {
170
199
  content: string;
171
200
  content_format?: 'plain' | 'markdown';
@@ -197,7 +226,11 @@ export interface UpdatePostInput {
197
226
  }
198
227
  export type ReactionType = 'like' | 'heart' | 'fire' | 'laugh' | 'sad' | 'angry' | 'upvote' | 'downvote';
199
228
  export interface ListPostsParams extends PaginationParams {
200
- /** Public-only feed with a bounded Jev presentation hint. Limit <=25. */
229
+ /**
230
+ * Public-only feed with a bounded Jev presentation hint. Limit <=25.
231
+ * The safety floor does not depend on it: a category page and every app-wide
232
+ * `sort: 'hot'` or `'score'` read are screened with or without a layout.
233
+ */
201
234
  discovery?: boolean;
202
235
  /** Public-only broad category. Requires an enabled app experiment; limit <=25. */
203
236
  category?: string;
@@ -214,6 +247,10 @@ export interface ListPostsParams extends PaginationParams {
214
247
  export interface SearchPostsParams extends PaginationParams {
215
248
  q: string;
216
249
  tag_ids?: string;
250
+ /** `relevance` (default) or `new` (newest first). */
251
+ sort?: 'relevance' | 'new';
252
+ since?: string;
253
+ until?: string;
217
254
  }
218
255
  export type QueryParams = Record<string, unknown>;
219
256
  export interface CommunityCreator {
@@ -232,6 +269,10 @@ export interface Community {
232
269
  privacy: 'public' | 'private' | 'hidden';
233
270
  created_by: CommunityCreator;
234
271
  member_count: number;
272
+ /** Denormalized post count. */
273
+ post_count?: number;
274
+ /** Whether the caller is an accepted member. Returned by `list` and `search`. */
275
+ is_member?: boolean;
235
276
  created_at: string;
236
277
  }
237
278
  /** Filters accepted by the communities directory. */
@@ -240,11 +281,71 @@ export interface ListCommunitiesParams extends PaginationParams {
240
281
  member?: boolean;
241
282
  /** Restrict personal keys to one organization. Project-bound keys are already scoped. */
242
283
  organization_id?: string;
243
- /** Server-side directory ordering. */
284
+ /** Server-side directory ordering. With `q`, name matches come first and this breaks ties. */
244
285
  sort?: 'members' | 'active' | 'newest';
286
+ /**
287
+ * Case-insensitive text search over name and description, up to 200
288
+ * characters. With `member: true` it searches only the caller's own groups.
289
+ */
290
+ q?: string;
245
291
  }
292
+ /** The caller's own membership row in a group, if any. */
293
+ export type CommunityMembershipStatus = 'accepted' | 'pending' | 'invited' | 'banned';
246
294
  export interface CommunityDetail extends Community {
247
295
  post_count: number;
296
+ /** The caller's role when they are an accepted member (the creator is always `owner`). */
297
+ viewer_role?: 'owner' | 'admin' | 'moderator' | 'member' | null;
298
+ /** The caller's own membership state, whether or not it is accepted. */
299
+ membership_status?: CommunityMembershipStatus | null;
300
+ /** People waiting to join. Present only for moderators and up. */
301
+ pending_request_count?: number;
302
+ /** Always absent or false on a full detail; see `CommunityCard`. */
303
+ limited?: false;
304
+ }
305
+ /**
306
+ * A private group seen from outside: `communities.get` returns this to a
307
+ * signed-in person who is not an accepted member (including a pending
308
+ * requester or a banned account), so an app can offer "Request to join" or
309
+ * show "Requested". The description, creator, roster, post count and posts
310
+ * stay with members. Hidden groups still answer 404, and so does an app's
311
+ * private group to a caller outside that app (an app key sees its own app).
312
+ */
313
+ export interface CommunityCard {
314
+ id: string;
315
+ name: string;
316
+ slug: string;
317
+ image: string | null;
318
+ banner: string | null;
319
+ privacy: 'private';
320
+ member_count: number;
321
+ is_member: false;
322
+ viewer_role: null;
323
+ membership_status: CommunityMembershipStatus | null;
324
+ limited: true;
325
+ description?: undefined;
326
+ created_by?: undefined;
327
+ post_count?: undefined;
328
+ created_at?: undefined;
329
+ }
330
+ /** A row from `communities.related`: a public group, ranked by shared members. */
331
+ export interface RelatedCommunity {
332
+ id: string;
333
+ name: string;
334
+ slug: string;
335
+ description: string | null;
336
+ image: string | null;
337
+ banner: string | null;
338
+ privacy: 'public';
339
+ /** Whether the caller is an accepted member of this related group. */
340
+ is_member: boolean;
341
+ member_count: number;
342
+ post_count: number;
343
+ /** How many members this group shares with the one asked about. */
344
+ overlap: number;
345
+ }
346
+ /** Paging plus `q`: a case-insensitive name or username search, up to 200 characters. */
347
+ export interface CommunityPeopleParams extends PaginationParams {
348
+ q?: string;
248
349
  }
249
350
  export interface CommunityMember {
250
351
  id: string;
@@ -269,7 +370,8 @@ export interface CommunityBannedMember {
269
370
  }
270
371
  export interface CreateCommunityInput {
271
372
  name: string;
272
- slug: string;
373
+ /** Optional vanity slug. Omit it for a server-generated collision-resistant default. */
374
+ slug?: string;
273
375
  description?: string;
274
376
  privacy?: 'public' | 'private' | 'hidden';
275
377
  }
@@ -328,8 +430,25 @@ export interface Conversation {
328
430
  last_message: LastMessage | null;
329
431
  /** Omitted by API versions deployed before message requests. */
330
432
  request_status?: ChatRequestStatus;
433
+ /** The member who started it; null when it cannot be told (older threads). */
434
+ created_by?: string | null;
435
+ /** Whether `chat.deleteConversation()` is allowed for the caller. */
436
+ can_delete?: boolean;
437
+ /** Whether `chat.leave()` is allowed for the caller. */
438
+ can_leave?: boolean;
331
439
  created_at: string;
332
440
  }
441
+ export interface ConversationRequestResult {
442
+ id: string;
443
+ request_status: ChatRequestStatus;
444
+ /** False when the conversation was already in that state. */
445
+ changed: boolean;
446
+ }
447
+ export interface LeaveConversationResult {
448
+ left: true;
449
+ /** True when the caller was the last person in it, so the room was removed. */
450
+ conversation_deleted: boolean;
451
+ }
333
452
  export interface ConversationDetail {
334
453
  /** Missing on older APIs: treat as unknown, never as plaintext permission. */
335
454
  encryption?: ConversationEncryptionPolicy;
@@ -340,6 +459,12 @@ export interface ConversationDetail {
340
459
  members: ConversationMemberDetail[];
341
460
  /** Omitted by API versions deployed before message requests. */
342
461
  request_status?: ChatRequestStatus;
462
+ /** The member who started it; null when it cannot be told (older threads). */
463
+ created_by?: string | null;
464
+ /** Whether `chat.deleteConversation()` is allowed for the caller. */
465
+ can_delete?: boolean;
466
+ /** Whether `chat.leave()` is allowed for the caller. */
467
+ can_leave?: boolean;
343
468
  created_at: string;
344
469
  }
345
470
  export interface MessageReaction {
@@ -599,7 +724,8 @@ export interface AgentDetail extends Agent {
599
724
  }
600
725
  export interface CreateAgentInput {
601
726
  name: string;
602
- username: string;
727
+ /** Optional public handle. Omit it for a server-generated collision-resistant default. */
728
+ username?: string;
603
729
  bio?: string;
604
730
  model?: string;
605
731
  system_prompt?: string;
@@ -656,6 +782,12 @@ export interface AgentChatInput {
656
782
  conversation_id?: string;
657
783
  new_conversation?: boolean;
658
784
  }
785
+ /** Answer an existing message of yours again, without sending it a second time. */
786
+ export interface AgentChatRetryInput {
787
+ conversation_id: string;
788
+ /** Your message whose reply failed (or that you want answered again). Must be the latest one. */
789
+ retry_message_id: string;
790
+ }
659
791
  export interface AgentChatResult {
660
792
  message_id: string;
661
793
  conversation_id: string;
@@ -727,6 +859,24 @@ export interface Profile {
727
859
  is_ai: boolean;
728
860
  created_at: string;
729
861
  }
862
+ /** A row of a followers/following list: the profile plus the caller's relationship with it. */
863
+ export interface FollowListProfile extends Profile, ViewerRelationship {
864
+ }
865
+ /** An account the caller blocked. */
866
+ export interface BlockedProfile extends Profile {
867
+ blocked_at: string;
868
+ }
869
+ /** An account the caller muted. */
870
+ export interface MutedProfile extends Profile {
871
+ muted_at: string;
872
+ }
873
+ /** Paging and name/username filter for the caller's blocked and muted lists. */
874
+ export type ModerationListParams = {
875
+ limit?: number;
876
+ offset?: number;
877
+ /** Case-insensitive match on name or username. */
878
+ search?: string;
879
+ };
730
880
  export interface ProfileDetail extends Profile {
731
881
  followers_count: number;
732
882
  following_count: number;
@@ -736,6 +886,12 @@ export interface ProfileMe extends Profile {
736
886
  email_verified: boolean;
737
887
  role: string;
738
888
  two_factor_enabled: boolean | null;
889
+ /**
890
+ * Whether the account can confirm changes with a password. False for
891
+ * OTP-only accounts: they confirm email and two-factor changes with a code
892
+ * from `settings.requestConfirmationCode`. Absent on servers older than this field.
893
+ */
894
+ has_password?: boolean;
739
895
  followers_count: number;
740
896
  following_count: number;
741
897
  updated_at: string;
@@ -749,6 +905,20 @@ export interface UpdateProfileInput {
749
905
  export interface SearchProfilesParams extends PaginationParams {
750
906
  q: string;
751
907
  }
908
+ export interface SearchMentionsParams {
909
+ /** What the member typed after `@` (a leading `@` is ignored). */
910
+ q: string;
911
+ /** Default 8, max 25. */
912
+ limit?: number;
913
+ [key: string]: unknown;
914
+ }
915
+ /** An account a composer's @-picker may offer: a person or an agent. */
916
+ export interface MentionCandidate extends Profile {
917
+ /** True for an agent (a platform or app agent, not a person's own AI). */
918
+ is_agent: boolean;
919
+ /** True when the caller follows this account; followed accounts rank first. */
920
+ is_following: boolean;
921
+ }
752
922
  export interface LeaderboardEntry {
753
923
  id: string;
754
924
  name: string;
@@ -759,6 +929,8 @@ export interface LeaderboardEntry {
759
929
  post_count: number;
760
930
  reaction_count: number;
761
931
  engagement: number;
932
+ /** Whether the caller follows this account. */
933
+ is_following?: boolean;
762
934
  created_at: string;
763
935
  }
764
936
  export interface Organization {
@@ -868,7 +1040,39 @@ export interface ChangePasswordInput {
868
1040
  }
869
1041
  export interface RequestEmailChangeInput {
870
1042
  new_email: string;
871
- password: string;
1043
+ /** Required for an account with a password. */
1044
+ password?: string;
1045
+ /**
1046
+ * Required for an account with no password (`has_password: false`): the
1047
+ * code from `settings.requestConfirmationCode('email_change')`, which is
1048
+ * sent to the CURRENT address.
1049
+ */
1050
+ email_code?: string;
1051
+ }
1052
+ /** What a confirmation code is for. A code for one purpose never confirms another. */
1053
+ export type ConfirmationCodePurpose = 'email_change' | 'two_factor';
1054
+ export interface ConfirmationCodeSent {
1055
+ success: true;
1056
+ purpose: ConfirmationCodePurpose;
1057
+ /** ISO timestamp. Codes live ten minutes. */
1058
+ expires_at: string;
1059
+ }
1060
+ export interface RevokeOtherSessionsInput {
1061
+ /**
1062
+ * The Better Auth session token this device holds, if any. Proving it keeps
1063
+ * that session alive; without it every session is revoked. The calling API
1064
+ * key is always kept.
1065
+ */
1066
+ keep_session_token?: string;
1067
+ }
1068
+ export interface RevokeOtherSessionsResult {
1069
+ success: true;
1070
+ /** Better Auth sessions revoked. */
1071
+ revoked: number;
1072
+ /** Other API keys revoked (within this key's app when the key is app-bound). */
1073
+ api_keys_revoked: number;
1074
+ /** Whether keep_session_token named a session of this account, which was kept. */
1075
+ kept_session: boolean;
872
1076
  }
873
1077
  export interface DeletionStatus {
874
1078
  requested: boolean;
@@ -884,6 +1088,13 @@ export interface LoginHistoryEntry {
884
1088
  }
885
1089
  export interface RecursivConfig {
886
1090
  apiKey?: string;
1091
+ /**
1092
+ * Whether to fall back to `RECURSIV_API_KEY` when `apiKey` is omitted.
1093
+ * Defaults to true for backwards compatibility and branded pre-auth flows.
1094
+ * Set to false for public clients that must remain keyless even in a
1095
+ * credentialed server process.
1096
+ */
1097
+ inheritEnvironmentApiKey?: boolean;
887
1098
  baseUrl?: string;
888
1099
  timeout?: number;
889
1100
  maxRetries?: number;