@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
@@ -248,6 +248,8 @@ export interface HostedNostrIdentityProof {
248
248
  export type NativeNostrPrepareInput = {
249
249
  action: 'publish';
250
250
  content: string;
251
+ /** Your own post in this app (sdk.posts) that this note copies, so deleting it can offer this copy. */
252
+ crossPostOf?: string;
251
253
  } | {
252
254
  action: 'reply';
253
255
  content: string;
@@ -292,12 +294,27 @@ export interface SocialSourceRef {
292
294
  kind: 'actor' | 'post';
293
295
  nativeId: string;
294
296
  }
297
+ /**
298
+ * How a controlled source last looked when Minds observed it on its network: the latest public
299
+ * observation, not a copy saved with the control. Null when it was never observed or has aged out.
300
+ */
301
+ export interface SocialSourceControlDisplay {
302
+ handle: string | null;
303
+ displayName: string | null;
304
+ /** Null when the source, or a hidden post's author, is under an active app moderation action. */
305
+ avatarUrl: string | null;
306
+ /** A hidden post's text, at most 140 characters; null for accounts, deleted posts, and moderated posts or authors. */
307
+ excerpt: string | null;
308
+ observedAt: string;
309
+ }
295
310
  export interface SocialSourceControl {
296
311
  id: string;
297
312
  source: SocialSourceRef;
298
313
  control: 'block' | 'mute' | 'hide';
299
314
  scope: 'minds';
300
315
  createdAt: string;
316
+ /** Present on servers that label controls; null when the source has no recent observation. */
317
+ display?: SocialSourceControlDisplay | null;
301
318
  }
302
319
  export type SocialSourceControlChange = Omit<SocialSourceControl, 'id' | 'createdAt'> & {
303
320
  enabled: boolean;
@@ -377,6 +394,32 @@ export interface NativeFollowState extends NativeFollowReceipt {
377
394
  /** An earlier connection or another target profile has an unresolved attempt. Read again to reconcile; do not prepare a new write. */
378
395
  pendingActionBlocked: boolean;
379
396
  }
397
+ /** One connected account on the source's network, as the account lists describe it. */
398
+ export interface NativeFollowAccount {
399
+ id: string;
400
+ protocol: SocialSourceRef['protocol'];
401
+ nativeId: string;
402
+ handle: string;
403
+ serverUrl: string;
404
+ /** Includes `follow`/`unfollow` only when this account may follow here; otherwise offer a reconnect. */
405
+ capabilities: string[];
406
+ }
407
+ /** Every connected account's relationship with one source, from one read. */
408
+ export interface NativeFollowStates {
409
+ protocol: SocialSourceRef['protocol'];
410
+ nativeId: string;
411
+ /** False when native follows are off for this app; accounts are still listed, and no state is read. */
412
+ enabled: boolean;
413
+ accounts: Array<{
414
+ account: NativeFollowAccount;
415
+ /** Null when the account cannot follow, follows are off, or its read failed (see `error`). */
416
+ state: NativeFollowState | null;
417
+ error: {
418
+ code: string;
419
+ message: string;
420
+ } | null;
421
+ }>;
422
+ }
380
423
  export interface NativeFollowReview {
381
424
  id: string;
382
425
  clientMutationId: string;
@@ -624,6 +667,12 @@ export interface NativePostPrepareInput {
624
667
  protocol: 'bluesky';
625
668
  nativeId: string;
626
669
  };
670
+ /**
671
+ * Your own post in this app (sdk.posts, same app) that this publication copies. The server links
672
+ * them in the same write, so `nativePostHistory({ crossPostOf })` can list every copy when the post
673
+ * is deleted. Any other post answers not_found.
674
+ */
675
+ crossPostOf?: string;
627
676
  }
628
677
  export interface NativePostBatch {
629
678
  id: string;
@@ -643,14 +692,42 @@ export interface NativePostBatch {
643
692
  };
644
693
  }>;
645
694
  }
695
+ export interface NativeDelegatedPostHistoryItem {
696
+ id: string;
697
+ createdAt: string;
698
+ text: string;
699
+ textTruncated: boolean;
700
+ deliveries: Array<Omit<NativePostBatch['deliveries'][number], 'text' | 'wireText' | 'maxCharacters'>>;
701
+ /** The post in this app this publication copies, when it was prepared with crossPostOf. */
702
+ crossPostOf?: string;
703
+ }
704
+ /**
705
+ * An original Nostr note the member signed in this app. Reopen it with
706
+ * `getNativeNostrPost(identityId, eventId)` and delete it with the Nostr signing flow
707
+ * (`prepareNativeNostr(identityId, { action: 'delete', postId: eventId })`), not the
708
+ * delegated removal methods. `receipt.state` becomes 'deletion_requested' once a
709
+ * deletion request is confirmed on the relay.
710
+ */
711
+ export interface NativeNostrPostHistoryItem {
712
+ type: 'nostr';
713
+ id: string;
714
+ createdAt: string;
715
+ text: string;
716
+ textTruncated: boolean;
717
+ identityId: string;
718
+ pubkey: string;
719
+ relay: string;
720
+ eventId: string;
721
+ action: 'publish';
722
+ receipt: NativeNostrReceipt;
723
+ checkedAt: string | null;
724
+ lastReadBack: NativeNostrReceipt['readBack'];
725
+ /** The post in this app this note copies, when it was prepared with crossPostOf. */
726
+ crossPostOf?: string;
727
+ }
646
728
  export interface NativePostHistory {
647
- items: Array<{
648
- id: string;
649
- createdAt: string;
650
- text: string;
651
- textTruncated: boolean;
652
- deliveries: Array<Omit<NativePostBatch['deliveries'][number], 'text' | 'wireText' | 'maxCharacters'>>;
653
- }>;
729
+ /** Delegated Bluesky/ActivityPub posts and client-signed Nostr originals, newest first. */
730
+ items: Array<NativeDelegatedPostHistoryItem | NativeNostrPostHistoryItem>;
654
731
  cursor: string | null;
655
732
  }
656
733
  export interface NativeSocialCallbackInput {
@@ -712,6 +789,8 @@ export interface NativeNostrPrepared {
712
789
  relay: string;
713
790
  expiresAt: string;
714
791
  postId?: string;
792
+ /** The post in this app this note will be linked to on submit. */
793
+ crossPostOf?: string;
715
794
  parent?: {
716
795
  protocol: 'nostr';
717
796
  nativeId: string;
@@ -764,6 +843,21 @@ export interface NativeNostrReceipt {
764
843
  readBack: 'found' | 'absent' | 'unavailable';
765
844
  reason?: 'blocked' | 'rate_limited' | 'restricted' | 'invalid' | 'relay_error';
766
845
  }
846
+ /**
847
+ * Ask the app's own PDS to issue a Bluesky account. Only the label is sent: the
848
+ * app decides the domain (`alice` becomes `alice.pds.minds.com` on a test lane,
849
+ * `alice.minds.com` once handles move).
850
+ */
851
+ export interface CreateHostedIdentityInput {
852
+ protocol: 'atproto';
853
+ /** One lowercase label of 3 to 18 characters (the PDS's own bounds): letters, digits and inner hyphens. */
854
+ handle: string;
855
+ email: string;
856
+ }
857
+ /** The new identity, with the member's password: returned this once and stored nowhere. */
858
+ export interface CreatedHostedProtocolIdentity extends HostedProtocolIdentity {
859
+ password: string;
860
+ }
767
861
  export type ConnectHostedIdentityInput = {
768
862
  protocol: 'atproto';
769
863
  identifier: string; /** Prefer a native app password. Used once, never stored. */
@@ -940,6 +1034,16 @@ export interface SocialTrend {
940
1034
  /** A real image-bearing post from this topic, filtered by current source controls. */
941
1035
  preview?: SocialPost;
942
1036
  }
1037
+ /**
1038
+ * Present only on category pages of a feed the app's open-network source index serves (ActivityPub
1039
+ * and Nostr): the provider's posts come first, then posts the index judged into the category. The
1040
+ * page's `cursor` (it starts with `idx:`) carries both positions; pass it back unchanged like any other cursor.
1041
+ */
1042
+ export interface SocialTrendSourceIndex {
1043
+ /** Posts on this page that came from the index rather than the provider's ranking. */
1044
+ served: number;
1045
+ coverage: 'source_index';
1046
+ }
943
1047
  export type SocialTrends = SocialTrendProvenance & ({
944
1048
  kind: 'topics';
945
1049
  items: SocialTrend[];
@@ -948,6 +1052,10 @@ export type SocialTrends = SocialTrendProvenance & ({
948
1052
  kind: 'posts';
949
1053
  items: SocialPost[];
950
1054
  cursor: string | null;
1055
+ sourceIndex?: SocialTrendSourceIndex;
1056
+ safetyFilter?: {
1057
+ withheld: number;
1058
+ };
951
1059
  });
952
1060
  export interface SocialTrendFeed extends SocialTrendProvenance {
953
1061
  trend: SocialTrend;
@@ -1057,6 +1165,18 @@ export interface SocialRadarPosts {
1057
1165
  builtAt: string | null;
1058
1166
  items: SocialPost[];
1059
1167
  }
1168
+ /**
1169
+ * One radar story by id, with its social member posts.
1170
+ * `live`: on the current radar (`cluster` and `items` present). `aged_out`: on one of the last six
1171
+ * radars but not this one. `unknown`: not seen in that window (never existed, or aged out long ago).
1172
+ */
1173
+ export interface SocialRadarStory {
1174
+ id: string;
1175
+ builtAt: string | null;
1176
+ status: 'live' | 'aged_out' | 'unknown';
1177
+ cluster: SocialRadarCluster | null;
1178
+ items: SocialPost[];
1179
+ }
1060
1180
  /** Read options for callers that hold their own deadline, such as a discovery page. */
1061
1181
  export interface SocialReadOptions {
1062
1182
  retry?: boolean;
@@ -1135,7 +1255,10 @@ export declare class ProtocolsResource {
1135
1255
  limit?: number;
1136
1256
  cursor?: string;
1137
1257
  }): Promise<SingleResponse<SocialAuthorFeed>>;
1138
- /** Public, app-moderated discovery without account authority. Enrichment uses cached judgments only. */
1258
+ /**
1259
+ * Public, app-moderated discovery without account authority. Enrichment uses cached judgments only.
1260
+ * Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
1261
+ */
1139
1262
  getSharedTrends(projectId: string, params: {
1140
1263
  protocol: string;
1141
1264
  limit?: number;
@@ -1144,7 +1267,7 @@ export declare class ProtocolsResource {
1144
1267
  category?: string;
1145
1268
  discovery?: boolean;
1146
1269
  }): Promise<SingleResponse<SocialTrends>>;
1147
- /** Open a provider-listed topic through the same public-only app boundary. */
1270
+ /** Open a provider-listed topic through the same public-only app boundary, with the same safety floor. */
1148
1271
  getSharedTrendFeed(projectId: string, params: {
1149
1272
  protocol: string;
1150
1273
  topic: string;
@@ -1155,6 +1278,14 @@ export declare class ProtocolsResource {
1155
1278
  }): Promise<SingleResponse<SocialTrendFeed>>;
1156
1279
  /** Breaking and viral stories clustered across outlets, open networks and Minds, through the same public-only app boundary. */
1157
1280
  getSharedRadar(projectId: string, params?: SocialRadarParams): Promise<SingleResponse<SocialRadar>>;
1281
+ /** One radar story's social member posts without a key, so a signed-out story card can show the posts it counts. */
1282
+ getSharedRadarPosts(projectId: string, params: {
1283
+ cluster: string;
1284
+ }): Promise<SingleResponse<SocialRadarPosts>>;
1285
+ /** One radar story by id with its posts, without a key: a story page or shared link in one call. */
1286
+ getSharedRadarStory(projectId: string, params: {
1287
+ cluster: string;
1288
+ }): Promise<SingleResponse<SocialRadarStory>>;
1158
1289
  publicNetworks(): Promise<SingleResponse<SocialNetwork[]>>;
1159
1290
  /** Query the live public network. It does not import users or posts. */
1160
1291
  searchPublicPosts(params: SearchPublicPostsParams): Promise<SingleResponse<SocialPostSearch>>;
@@ -1186,7 +1317,10 @@ export declare class ProtocolsResource {
1186
1317
  post: string;
1187
1318
  readRef?: string;
1188
1319
  }): Promise<SingleResponse<SocialConversation>>;
1189
- /** Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content. */
1320
+ /**
1321
+ * Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content.
1322
+ * Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
1323
+ */
1190
1324
  getPublicTrends(params: {
1191
1325
  protocol: string;
1192
1326
  limit?: number;
@@ -1195,7 +1329,7 @@ export declare class ProtocolsResource {
1195
1329
  category?: string;
1196
1330
  discovery?: boolean;
1197
1331
  }, options?: SocialReadOptions): Promise<SingleResponse<SocialTrends>>;
1198
- /** Open a topic currently listed by the provider. Use its nativeId as topic and preserve the opaque cursor. */
1332
+ /** Open a topic currently listed by the provider. Use its nativeId as topic and preserve the opaque cursor. Screened like `getPublicTrends`. */
1199
1333
  getPublicTrendFeed(params: {
1200
1334
  protocol: string;
1201
1335
  topic: string;
@@ -1210,6 +1344,10 @@ export declare class ProtocolsResource {
1210
1344
  getPublicRadarPosts(params: {
1211
1345
  cluster: string;
1212
1346
  }, options?: SocialReadOptions): Promise<SingleResponse<SocialRadarPosts>>;
1347
+ /** One radar story by id with its posts under the app's own key; `status` tells an aged-out story from an unknown one. */
1348
+ getPublicRadarStory(params: {
1349
+ cluster: string;
1350
+ }, options?: SocialReadOptions): Promise<SingleResponse<SocialRadarStory>>;
1213
1351
  /** Provider-ranked public accounts with explicit provenance; served from the app's index when a fresh snapshot exists. */
1214
1352
  getPublicPopularProfiles(params: {
1215
1353
  protocol: string;
@@ -1218,6 +1356,12 @@ export declare class ProtocolsResource {
1218
1356
  }): Promise<SingleResponse<SocialPopularProfiles>>;
1219
1357
  /** Read this connected account's current native following; never infer it from a public count. */
1220
1358
  nativeFollowState(input: NativeFollowSourceInput): Promise<SingleResponse<NativeFollowState>>;
1359
+ /**
1360
+ * The viewer's connected accounts on a source's network and each one's follow state, in one read,
1361
+ * so a profile's Follow control is ready after one round trip instead of listing accounts first.
1362
+ * Resume any `pendingActionId` with `nativeFollowStatus`; never start a duplicate action.
1363
+ */
1364
+ nativeFollowStates(input: Omit<NativeFollowSourceInput, 'accountId'>): Promise<SingleResponse<NativeFollowStates>>;
1221
1365
  /** Prepare a follow/unfollow for explicit approval. Preserve the mutation ID after a lost response. */
1222
1366
  prepareNativeFollow(input: NativeFollowPrepareInput): Promise<SingleResponse<NativeFollowReview>>;
1223
1367
  /** Submit one approved action. Only Nostr supplies a public signed event. Automatic retries are disabled. */
@@ -1263,10 +1407,17 @@ export declare class ProtocolsResource {
1263
1407
  }>>;
1264
1408
  /** Read the signed-in owner's saved publication review and durable receipts. */
1265
1409
  nativePostStatus(id: string): Promise<SingleResponse<NativePostBatch>>;
1266
- /** Page the current app user's standalone publication history. This never sends. */
1410
+ /**
1411
+ * Page the current app user's standalone publication history. This never sends.
1412
+ * Items are delegated Bluesky/ActivityPub posts and client-signed Nostr originals (`type: 'nostr'`,
1413
+ * no `deliveries`); the server lists the Nostr ones only for clients that ask, as this method does.
1414
+ * With `crossPostOf`, only the network copies of that post in this app: delete each with
1415
+ * prepareNativePostRemoval/removeNativePost, or the Nostr signing flow for a `type: 'nostr'` item.
1416
+ */
1267
1417
  nativePostHistory(params?: {
1268
1418
  limit?: number;
1269
1419
  cursor?: string;
1420
+ crossPostOf?: string;
1270
1421
  }): Promise<SingleResponse<NativePostHistory>>;
1271
1422
  /** Review the current own posts before approving removal. */
1272
1423
  prepareNativePostRemoval(id: string, input: {
@@ -1325,11 +1476,17 @@ export declare class ProtocolsResource {
1325
1476
  nativeSocialAccounts(): Promise<SingleResponse<{
1326
1477
  enabled: boolean;
1327
1478
  accounts: NativeSocialAccount[];
1479
+ /** Protocols this app can connect with `redirect: 'native'`. Empty when no native callback is configured. */
1480
+ nativeRedirects?: NativeSocialProtocol[];
1328
1481
  }>>;
1329
- /** Private source controls in this app, with bounded pagination. */
1482
+ /**
1483
+ * Private source controls in this app, with bounded pagination. Pass `control` to list only
1484
+ * blocks, mutes or hidden posts; each item may carry a `display` label for the settings list.
1485
+ */
1330
1486
  sourceControls(params?: {
1331
1487
  limit?: number;
1332
1488
  cursor?: string;
1489
+ control?: SocialSourceControl['control'];
1333
1490
  }): Promise<SingleResponse<{
1334
1491
  enabled: boolean;
1335
1492
  items: SocialSourceControl[];
@@ -1356,13 +1513,22 @@ export declare class ProtocolsResource {
1356
1513
  existing: boolean;
1357
1514
  scope: 'minds';
1358
1515
  }>>;
1359
- /** Open the returned authorization URL in the user's browser; never submit passwords or tokens. */
1516
+ /**
1517
+ * Open the returned authorization URL in the user's browser; never submit passwords or tokens.
1518
+ * In a native app pass `redirect: 'native'` (when `nativeSocialAccounts().nativeRedirects` lists the
1519
+ * protocol) and open an in-app auth session on `callbackUrl`, e.g. expo-web-browser's
1520
+ * `openAuthSessionAsync(authorizationUrl, callbackUrl)`; then pass the returned `state`, `code`,
1521
+ * `iss` or `error` query values to `finishNativeSocialConnection`.
1522
+ */
1360
1523
  startNativeSocialConnection(input: {
1361
1524
  protocol: NativeSocialProtocol;
1362
1525
  identifier: string;
1526
+ redirect?: 'web' | 'native';
1363
1527
  }): Promise<SingleResponse<{
1364
1528
  protocol: NativeSocialProtocol;
1365
1529
  authorizationUrl: string;
1530
+ /** Where the provider returns: the app's web callback, or its operator-configured native callback. */
1531
+ callbackUrl: string;
1366
1532
  }>>;
1367
1533
  /** Complete a single-use callback with the same signed-in app user. Remove its query from browser history; do not log codes. */
1368
1534
  finishNativeSocialConnection(input: NativeSocialCallbackInput): Promise<SingleResponse<NativeSocialAccount>>;
@@ -1414,6 +1580,21 @@ export declare class ProtocolsResource {
1414
1580
  /** Request a short-lived, single-use proof bound to this app, account and relay. */
1415
1581
  hostedNostrChallenge(): Promise<SingleResponse<HostedNostrChallenge>>;
1416
1582
  connectHostedIdentity(input: ConnectHostedIdentityInput): Promise<SingleResponse<HostedProtocolIdentity>>;
1583
+ /**
1584
+ * Create a Bluesky account for the signed-in member on the app's own PDS.
1585
+ *
1586
+ * The response carries the member's password exactly once; show it to them and
1587
+ * keep it nowhere. The server either finishes the account or removes it again,
1588
+ * so a failure leaves nothing half made. Never retried automatically: a replay
1589
+ * after a lost response could not return the password a second time.
1590
+ *
1591
+ * Failures to expect: `handle_unavailable` (409, taken or reserved; choose
1592
+ * another), `identity_conflict` (409, the member already has one),
1593
+ * `creation_in_progress` (409), and the operator-side 503s
1594
+ * `handle_dns_unavailable`, `handle_unresolvable`, `handle_unverified` and
1595
+ * `hosted_server_unavailable`, which succeed unchanged once the operator is done.
1596
+ */
1597
+ createHostedIdentity(input: CreateHostedIdentityInput): Promise<SingleResponse<CreatedHostedProtocolIdentity>>;
1417
1598
  disconnectHostedIdentity(id: string): Promise<SingleResponse<{
1418
1599
  disconnected: true;
1419
1600
  }>>;
@@ -89,12 +89,15 @@ export class ProtocolsResource {
89
89
  return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/author-feed`, { protocol: params.protocol, actor: params.actor,
90
90
  limit: params.limit, cursor: params.cursor });
91
91
  }
92
- /** Public, app-moderated discovery without account authority. Enrichment uses cached judgments only. */
92
+ /**
93
+ * Public, app-moderated discovery without account authority. Enrichment uses cached judgments only.
94
+ * Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
95
+ */
93
96
  getSharedTrends(projectId, params) {
94
97
  return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/trends`, { protocol: params.protocol, limit: params.limit, cursor: params.cursor,
95
98
  includePreviews: params.includePreviews, category: params.category, discovery: params.discovery });
96
99
  }
97
- /** Open a provider-listed topic through the same public-only app boundary. */
100
+ /** Open a provider-listed topic through the same public-only app boundary, with the same safety floor. */
98
101
  getSharedTrendFeed(projectId, params) {
99
102
  return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/trend-feed`, { protocol: params.protocol, topic: params.topic,
100
103
  limit: params.limit, cursor: params.cursor, category: params.category, discovery: params.discovery });
@@ -103,6 +106,14 @@ export class ProtocolsResource {
103
106
  getSharedRadar(projectId, params = {}) {
104
107
  return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/radar`, radarQuery(params));
105
108
  }
109
+ /** One radar story's social member posts without a key, so a signed-out story card can show the posts it counts. */
110
+ getSharedRadarPosts(projectId, params) {
111
+ return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/radar/posts`, { cluster: params.cluster });
112
+ }
113
+ /** One radar story by id with its posts, without a key: a story page or shared link in one call. */
114
+ getSharedRadarStory(projectId, params) {
115
+ return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/radar/story`, { cluster: params.cluster });
116
+ }
106
117
  publicNetworks() {
107
118
  return this.client.get('/protocols/social/networks');
108
119
  }
@@ -140,14 +151,17 @@ export class ProtocolsResource {
140
151
  getPublicConversation(params) {
141
152
  return this.client.get('/protocols/social/conversation', { protocol: params.protocol, post: params.post, readRef: params.readRef });
142
153
  }
143
- /** Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content. */
154
+ /**
155
+ * Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content.
156
+ * Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
157
+ */
144
158
  getPublicTrends(params, options) {
145
159
  return this.client.get('/protocols/social/trends', { protocol: params.protocol, limit: params.limit, cursor: params.cursor,
146
160
  ...(params.includePreviews !== undefined ? { includePreviews: params.includePreviews } : {}),
147
161
  ...(params.category !== undefined ? { category: params.category } : {}),
148
162
  ...(params.discovery !== undefined ? { discovery: params.discovery } : {}) }, ...readOptions(options));
149
163
  }
150
- /** Open a topic currently listed by the provider. Use its nativeId as topic and preserve the opaque cursor. */
164
+ /** Open a topic currently listed by the provider. Use its nativeId as topic and preserve the opaque cursor. Screened like `getPublicTrends`. */
151
165
  getPublicTrendFeed(params, options) {
152
166
  return this.client.get('/protocols/social/trend-feed', { protocol: params.protocol, topic: params.topic, limit: params.limit, cursor: params.cursor,
153
167
  ...(params.category !== undefined ? { category: params.category } : {}),
@@ -161,6 +175,10 @@ export class ProtocolsResource {
161
175
  getPublicRadarPosts(params, options) {
162
176
  return this.client.get('/protocols/social/radar/posts', { cluster: params.cluster }, ...readOptions(options));
163
177
  }
178
+ /** One radar story by id with its posts under the app's own key; `status` tells an aged-out story from an unknown one. */
179
+ getPublicRadarStory(params, options) {
180
+ return this.client.get('/protocols/social/radar/story', { cluster: params.cluster }, ...readOptions(options));
181
+ }
164
182
  /** Provider-ranked public accounts with explicit provenance; served from the app's index when a fresh snapshot exists. */
165
183
  getPublicPopularProfiles(params) {
166
184
  return this.client.get('/protocols/social/popular-profiles', { protocol: params.protocol, limit: params.limit, cursor: params.cursor });
@@ -169,6 +187,14 @@ export class ProtocolsResource {
169
187
  nativeFollowState(input) {
170
188
  return this.client.get('/protocols/social/follows/state', { accountId: input.accountId, protocol: input.protocol, nativeId: input.nativeId });
171
189
  }
190
+ /**
191
+ * The viewer's connected accounts on a source's network and each one's follow state, in one read,
192
+ * so a profile's Follow control is ready after one round trip instead of listing accounts first.
193
+ * Resume any `pendingActionId` with `nativeFollowStatus`; never start a duplicate action.
194
+ */
195
+ nativeFollowStates(input) {
196
+ return this.client.get('/protocols/social/follows/states', { protocol: input.protocol, nativeId: input.nativeId });
197
+ }
172
198
  /** Prepare a follow/unfollow for explicit approval. Preserve the mutation ID after a lost response. */
173
199
  prepareNativeFollow(input) {
174
200
  return this.client.post('/protocols/social/follows/prepare', { clientMutationId: input.clientMutationId, accountId: input.accountId,
@@ -236,7 +262,8 @@ export class ProtocolsResource {
236
262
  return this.client.post('/protocols/social/posts/prepare', { clientMutationId: input.clientMutationId,
237
263
  text: input.text, accountIds: input.accountIds,
238
264
  ...(input.quote ? { quote: { protocol: input.quote.protocol, nativeId: input.quote.nativeId } } : {}),
239
- ...(input.media !== undefined ? { media: nativeMediaInput(input.media) } : {}) }, { retry: false });
265
+ ...(input.media !== undefined ? { media: nativeMediaInput(input.media) } : {}),
266
+ ...(input.crossPostOf !== undefined ? { crossPostOf: input.crossPostOf } : {}) }, { retry: false });
240
267
  }
241
268
  /** Explicitly approve selected deliveries; never auto-retry an uncertain write. */
242
269
  submitNativePost(id, input) {
@@ -248,9 +275,16 @@ export class ProtocolsResource {
248
275
  hostedIdentityPath(id);
249
276
  return this.client.get(`/protocols/social/posts/${encodeURIComponent(id)}`);
250
277
  }
251
- /** Page the current app user's standalone publication history. This never sends. */
278
+ /**
279
+ * Page the current app user's standalone publication history. This never sends.
280
+ * Items are delegated Bluesky/ActivityPub posts and client-signed Nostr originals (`type: 'nostr'`,
281
+ * no `deliveries`); the server lists the Nostr ones only for clients that ask, as this method does.
282
+ * With `crossPostOf`, only the network copies of that post in this app: delete each with
283
+ * prepareNativePostRemoval/removeNativePost, or the Nostr signing flow for a `type: 'nostr'` item.
284
+ */
252
285
  nativePostHistory(params = {}) {
253
- return this.client.get('/protocols/social/posts', { limit: params.limit, cursor: params.cursor });
286
+ return this.client.get('/protocols/social/posts', { limit: params.limit, cursor: params.cursor,
287
+ ...(params.crossPostOf !== undefined ? { crossPostOf: params.crossPostOf } : {}), include: 'nostr' });
254
288
  }
255
289
  /** Review the current own posts before approving removal. */
256
290
  prepareNativePostRemoval(id, input) {
@@ -300,9 +334,13 @@ export class ProtocolsResource {
300
334
  nativeSocialAccounts() {
301
335
  return this.client.get('/protocols/social/accounts');
302
336
  }
303
- /** Private source controls in this app, with bounded pagination. */
337
+ /**
338
+ * Private source controls in this app, with bounded pagination. Pass `control` to list only
339
+ * blocks, mutes or hidden posts; each item may carry a `display` label for the settings list.
340
+ */
304
341
  sourceControls(params = {}) {
305
- return this.client.get('/protocols/social/controls', { limit: params.limit, cursor: params.cursor });
342
+ return this.client.get('/protocols/social/controls', { limit: params.limit, cursor: params.cursor,
343
+ ...(params.control ? { control: params.control } : {}) });
306
344
  }
307
345
  /** Block/mute an actor or hide a post in Minds. This does not impersonate a native network block. */
308
346
  async setSourceControl(input) {
@@ -328,9 +366,17 @@ export class ProtocolsResource {
328
366
  return this.client.post('/protocols/social/reports', { source: { protocol: input.source.protocol, kind: input.source.kind, nativeId: input.source.nativeId },
329
367
  readRef: input.readRef, ...(input.accountId ? { accountId: input.accountId } : {}), reason: input.reason, details: input.details, scope: input.scope }, { retry: false });
330
368
  }
331
- /** Open the returned authorization URL in the user's browser; never submit passwords or tokens. */
369
+ /**
370
+ * Open the returned authorization URL in the user's browser; never submit passwords or tokens.
371
+ * In a native app pass `redirect: 'native'` (when `nativeSocialAccounts().nativeRedirects` lists the
372
+ * protocol) and open an in-app auth session on `callbackUrl`, e.g. expo-web-browser's
373
+ * `openAuthSessionAsync(authorizationUrl, callbackUrl)`; then pass the returned `state`, `code`,
374
+ * `iss` or `error` query values to `finishNativeSocialConnection`.
375
+ */
332
376
  startNativeSocialConnection(input) {
333
- return this.client.post('/protocols/social/oauth/start', { protocol: input.protocol, identifier: input.identifier }, { retry: false });
377
+ return this.client.post('/protocols/social/oauth/start', { protocol: input.protocol, identifier: input.identifier,
378
+ // Only the choice between operator-configured callbacks is sent; a callback URL never is.
379
+ ...(input.redirect === 'native' ? { redirect: 'native' } : {}) }, { retry: false });
334
380
  }
335
381
  /** Complete a single-use callback with the same signed-in app user. Remove its query from browser history; do not log codes. */
336
382
  finishNativeSocialConnection(input) {
@@ -362,7 +408,8 @@ export class ProtocolsResource {
362
408
  /** Prepare an exact event for review. A timeout never automatically creates another signing request. */
363
409
  prepareNativeNostr(id, input) {
364
410
  hostedIdentityPath(id);
365
- const body = input.action === 'publish' ? { action: input.action, content: input.content }
411
+ const body = input.action === 'publish' ? { action: input.action, content: input.content,
412
+ ...(input.crossPostOf !== undefined ? { crossPostOf: input.crossPostOf } : {}) }
366
413
  : input.action === 'reply' ? { action: input.action, content: input.content, parentId: input.parentId }
367
414
  : input.action === 'linked_post' ? { action: input.action, content: input.content,
368
415
  source: { protocol: input.source.protocol, nativeId: input.source.nativeId,
@@ -425,6 +472,24 @@ export class ProtocolsResource {
425
472
  connectHostedIdentity(input) {
426
473
  return this.client.post('/protocols/identities', input);
427
474
  }
475
+ /**
476
+ * Create a Bluesky account for the signed-in member on the app's own PDS.
477
+ *
478
+ * The response carries the member's password exactly once; show it to them and
479
+ * keep it nowhere. The server either finishes the account or removes it again,
480
+ * so a failure leaves nothing half made. Never retried automatically: a replay
481
+ * after a lost response could not return the password a second time.
482
+ *
483
+ * Failures to expect: `handle_unavailable` (409, taken or reserved; choose
484
+ * another), `identity_conflict` (409, the member already has one),
485
+ * `creation_in_progress` (409), and the operator-side 503s
486
+ * `handle_dns_unavailable`, `handle_unresolvable`, `handle_unverified` and
487
+ * `hosted_server_unavailable`, which succeed unchanged once the operator is done.
488
+ */
489
+ createHostedIdentity(input) {
490
+ const { protocol, handle, email } = input;
491
+ return this.client.post('/protocols/identities/create', { protocol, handle, email }, { retry: false });
492
+ }
428
493
  async disconnectHostedIdentity(id) {
429
494
  return this.client.delete(hostedIdentityPath(id));
430
495
  }
@@ -1,5 +1,5 @@
1
1
  import type { HttpClient } from '../client.js';
2
- import type { ChangePasswordInput, DeletionStatus, LoginHistoryEntry, PaginatedResponse, RequestEmailChangeInput, Session, SingleResponse, SuccessResponse, UpdateAppearanceInput, UpdateContentPreferencesInput, UpdateNotificationChannelsInput, UpdatePrivacyInput, UserPreferences } from '../types.js';
2
+ import type { ChangePasswordInput, ConfirmationCodePurpose, ConfirmationCodeSent, DeletionStatus, LoginHistoryEntry, PaginatedResponse, RequestEmailChangeInput, RevokeOtherSessionsInput, RevokeOtherSessionsResult, Session, SingleResponse, SuccessResponse, UpdateAppearanceInput, UpdateContentPreferencesInput, UpdateNotificationChannelsInput, UpdatePrivacyInput, UserPreferences } from '../types.js';
3
3
  export declare class SettingsResource {
4
4
  private client;
5
5
  constructor(client: HttpClient);
@@ -29,11 +29,33 @@ export declare class SettingsResource {
29
29
  listSessions(): Promise<SingleResponse<Session[]>>;
30
30
  /** Revoke a specific session */
31
31
  revokeSession(sessionId: string): Promise<SuccessResponse>;
32
- /** Revoke all sessions */
32
+ /**
33
+ * Revoke every session AND every API key of the account, including the key
34
+ * this client uses: after it resolves, this client is signed out too. For
35
+ * "sign out of all other devices", use `revokeOtherSessions`.
36
+ */
33
37
  revokeAllSessions(): Promise<SuccessResponse>;
38
+ /**
39
+ * Sign out of all other devices. Revokes every Better Auth session and the
40
+ * account's other API keys, and keeps this device: the calling key always
41
+ * survives, and so does the session named by `keep_session_token`. An
42
+ * app-bound key only revokes that app's keys.
43
+ */
44
+ revokeOtherSessions(input?: RevokeOtherSessionsInput): Promise<SingleResponse<RevokeOtherSessionsResult>>;
34
45
  /** Change password */
35
46
  changePassword(input: ChangePasswordInput): Promise<SuccessResponse>;
36
- /** Request email change */
47
+ /**
48
+ * Email a six-digit confirmation code to the account's current address.
49
+ * Only for accounts with no password (`profiles.me().has_password === false`);
50
+ * a password account answers `password_required`. Send the code as
51
+ * `email_code` to `requestEmailChange`, or as `emailCode` to the
52
+ * `auth.*TwoFactor` methods.
53
+ */
54
+ requestConfirmationCode(purpose: ConfirmationCodePurpose): Promise<SingleResponse<ConfirmationCodeSent>>;
55
+ /**
56
+ * Request email change. Confirm with `password`, or with `email_code` for an
57
+ * account that has no password.
58
+ */
37
59
  requestEmailChange(input: RequestEmailChangeInput): Promise<SingleResponse<{
38
60
  success: true;
39
61
  token?: string;
@@ -59,16 +59,42 @@ export class SettingsResource {
59
59
  revokeSession(sessionId) {
60
60
  return this.client.delete(`/settings/sessions/${sessionId}`);
61
61
  }
62
- /** Revoke all sessions */
62
+ /**
63
+ * Revoke every session AND every API key of the account, including the key
64
+ * this client uses: after it resolves, this client is signed out too. For
65
+ * "sign out of all other devices", use `revokeOtherSessions`.
66
+ */
63
67
  revokeAllSessions() {
64
68
  return this.client.delete('/settings/sessions');
65
69
  }
70
+ /**
71
+ * Sign out of all other devices. Revokes every Better Auth session and the
72
+ * account's other API keys, and keeps this device: the calling key always
73
+ * survives, and so does the session named by `keep_session_token`. An
74
+ * app-bound key only revokes that app's keys.
75
+ */
76
+ revokeOtherSessions(input = {}) {
77
+ return this.client.post('/settings/sessions/revoke-others', input);
78
+ }
66
79
  // ── Account Security ──
67
80
  /** Change password */
68
81
  changePassword(input) {
69
82
  return this.client.put('/settings/password', input);
70
83
  }
71
- /** Request email change */
84
+ /**
85
+ * Email a six-digit confirmation code to the account's current address.
86
+ * Only for accounts with no password (`profiles.me().has_password === false`);
87
+ * a password account answers `password_required`. Send the code as
88
+ * `email_code` to `requestEmailChange`, or as `emailCode` to the
89
+ * `auth.*TwoFactor` methods.
90
+ */
91
+ requestConfirmationCode(purpose) {
92
+ return this.client.post('/settings/confirmation-code', { purpose });
93
+ }
94
+ /**
95
+ * Request email change. Confirm with `password`, or with `email_code` for an
96
+ * account that has no password.
97
+ */
72
98
  requestEmailChange(input) {
73
99
  return this.client.post('/settings/email-change', input);
74
100
  }