@recursiv/sdk 0.7.28 → 0.7.30
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 +20 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -0
- package/dist/resources/e2ee.d.ts +93 -0
- package/dist/resources/e2ee.js +36 -0
- package/dist/resources/protocols.d.ts +104 -1
- package/dist/resources/protocols.js +38 -0
- package/llm.md +14 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ for await (const chunk of r.agents.chatStream(agent.id, { message: 'Hello!' }))
|
|
|
75
75
|
| Resource | Key methods |
|
|
76
76
|
|----------|------------|
|
|
77
77
|
| `r.agents` | `create`, `update`, `chat`, `chatStream`, `grantProjectAccess`, `conversations` |
|
|
78
|
+
| `r.e2ee` | `registerDevice`, `devices`, `revokeDevice`, `publishKeyPackages`, `claimKeyPackage`, `appendEvent`, `events`, `acknowledge` (flag-gated E2EE v2 transport) |
|
|
78
79
|
| `r.brain` | `sendMessage` |
|
|
79
80
|
| `r.commands` | `execute`, `gatePrompt` |
|
|
80
81
|
| `r.projectBrain` | `tasks`, `decisions`, `milestones`, `completeTask`, `usage` |
|
|
@@ -110,7 +111,7 @@ for await (const chunk of r.agents.chatStream(agent.id, { message: 'Hello!' }))
|
|
|
110
111
|
| `r.admin` | User management, stats, content reports (`listReports`, `resolveReport`, `dismissReport`) |
|
|
111
112
|
| `r.dispatcher` | Task queue, claims, signals, outcomes, webhooks |
|
|
112
113
|
| `r.goals` | Org goals with task rollups (group dispatcher tasks) |
|
|
113
|
-
| `r.protocols` | Private Minds safety: `sourceControls` (current enablement and saved choices), `setSourceControl`, `onSourceControlChange`, `reportSource`. Delegated accounts: `nativeSocialAccounts`, `startNativeSocialConnection`, `finishNativeSocialConnection`, `disconnectNativeSocialAccount`. Reviewed replies and optional linked posts: `prepareNativeReply`, `submitNativeReply`, `nativeReplyStatus`, `nativeReplyHistory`, `prepareNativeReplyRemoval`, `removeNativeReply` (require deployed API support and app enablement).
|
|
114
|
+
| `r.protocols` | Private Minds safety: `sourceControls` (current enablement and saved choices), `setSourceControl`, `onSourceControlChange`, `reportSource`. Delegated accounts: `nativeSocialAccounts`, `startNativeSocialConnection`, `finishNativeSocialConnection`, `disconnectNativeSocialAccount`. Reviewed replies and optional linked posts: `prepareNativeReply`, `submitNativeReply`, `nativeReplyStatus`, `nativeReplyHistory`, `prepareNativeReplyRemoval`, `removeNativeReply` (require deployed API support and app enablement). Keyless shared post links: `sharedNetworks(projectId)`, `getSharedConversation(projectId, { protocol, post, readRef? })`. Member public reading: `publicNetworks`, `searchPublicProfiles`, `getPublicProfile`, `getPublicAuthorFeed`, `getFollowingFeed`, `getPublicConversation`, `getPublicTrends`, `getPublicTrendFeed`; private app subscriptions: `listSubscriptions`, `subscribeToProfile`, `unsubscribeFromProfile`, `onSubscriptionChange`. `list` returns bounded adapter `maturity`, `limitations`, and exhaustive `supported`/`planned`/`unsupported` implementation capabilities (not provider health or enablement); settings, candidate refresh/status, search, and read-only quarantined candidate review via `listCandidates` / `getCandidate` |
|
|
114
115
|
|
|
115
116
|
Full reference: see [llm.md](./llm.md) (ships with this package) or the type definitions in `dist/`.
|
|
116
117
|
|
|
@@ -570,3 +571,21 @@ Keep the cursor opaque and discard it when the app or signed-in user changes.
|
|
|
570
571
|
History order is fixed by creation time, so later delivery updates do not move
|
|
571
572
|
older entries across page boundaries. Reopen each result for its current saved
|
|
572
573
|
state and obtain a fresh review before a new write.
|
|
574
|
+
|
|
575
|
+
### Public protocol post links
|
|
576
|
+
|
|
577
|
+
Visitors can read a public conversation in an explicitly configured app without signing in:
|
|
578
|
+
|
|
579
|
+
```ts
|
|
580
|
+
const visitor = new Recursiv({ anonymous: true });
|
|
581
|
+
const { data: networks } = await visitor.protocols.sharedNetworks(projectId);
|
|
582
|
+
const { data: conversation } = await visitor.protocols.getSharedConversation(projectId, {
|
|
583
|
+
protocol: 'nostr', post: publicEventId,
|
|
584
|
+
});
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
These reads apply app moderation, provider public-visibility/deletion checks and bounded
|
|
588
|
+
per-IP/app budgets. They return no subscriptions, personal safety preferences, account
|
|
589
|
+
connections or signing authority. Missing configuration or unavailable safety checks fail
|
|
590
|
+
closed. Signed-in members continue using `getPublicConversation` to apply personal
|
|
591
|
+
blocks/mutes as well. All reply and account endpoints still require authentication.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { PostsResource } from './resources/posts.js';
|
|
|
3
3
|
import { UsersResource } from './resources/users.js';
|
|
4
4
|
import { CommunitiesResource } from './resources/communities.js';
|
|
5
5
|
import { ChatResource } from './resources/chat.js';
|
|
6
|
+
import { E2eeResource } from './resources/e2ee.js';
|
|
6
7
|
import { ProjectsResource } from './resources/projects.js';
|
|
7
8
|
import { AgentsResource } from './resources/agents.js';
|
|
8
9
|
import { EvidenceResource } from './resources/evidence.js';
|
|
@@ -64,6 +65,8 @@ export declare class Recursiv {
|
|
|
64
65
|
readonly users: UsersResource;
|
|
65
66
|
readonly communities: CommunitiesResource;
|
|
66
67
|
readonly chat: ChatResource;
|
|
68
|
+
/** E2EE v2 ciphertext transport (flag-gated). */
|
|
69
|
+
readonly e2ee: E2eeResource;
|
|
67
70
|
readonly projects: ProjectsResource;
|
|
68
71
|
readonly agents: AgentsResource;
|
|
69
72
|
readonly evidence: EvidenceResource;
|
|
@@ -136,6 +139,8 @@ export { PostsResource } from './resources/posts.js';
|
|
|
136
139
|
export { UsersResource } from './resources/users.js';
|
|
137
140
|
export { CommunitiesResource } from './resources/communities.js';
|
|
138
141
|
export { ChatResource } from './resources/chat.js';
|
|
142
|
+
export { E2eeResource } from './resources/e2ee.js';
|
|
143
|
+
export type { E2eeDevice, E2eeEnvelope, E2eeEvent } from './resources/e2ee.js';
|
|
139
144
|
export { ProjectsResource } from './resources/projects.js';
|
|
140
145
|
export { AgentsResource, SUPPORTED_MODELS } from './resources/agents.js';
|
|
141
146
|
export { EvidenceResource } from './resources/evidence.js';
|
|
@@ -189,7 +194,7 @@ export type { UploadMediaInput, UploadUrlInput, UploadUrlResult } from './resour
|
|
|
189
194
|
export { WalletResource } from './resources/wallet.js';
|
|
190
195
|
export { ProtocolsResource } from './resources/protocols.js';
|
|
191
196
|
export { PROTOCOL_ADAPTER_MATURITIES, PROTOCOL_CAPABILITY_OPERATIONS, PROTOCOL_CAPABILITY_STATUSES, } from './resources/protocols.js';
|
|
192
|
-
export type { SocialProfile, SocialSubscription, SocialSubscriptionChange, SocialProfilePage, SocialNetwork, SocialPost, SocialConversation, SocialTrend, SocialTrendProvenance, SocialTrends, SocialTrendFeed, SocialAuthorFeed, SocialFollowingFeed, SocialFollowingSource, SearchPublicProfilesParams, HostedProtocolConnections, HostedProtocol, HostedProtocolIdentity, HostedNostrChallenge, HostedNostrIdentityProof, NativeNostrPrepareInput, NativeNostrPrepared, NativeNostrAccount, NativeNostrPostState, NativeNostrReceipt, NativeSocialProtocol, FederationIdentity, FederationIdentityView, NativeSocialAccount, NativeSocialCallbackInput, NativeReplyPrepareInput, NativeReplyReceipt, NativeReplyBatch, NativeReplyHistory, NativeDelegatedReplyHistoryItem, NativeNostrReplyResult, NativeNostrReplyHistoryItem, NativeReplyRemovalReceipt, NativeReplyRemovalPreview, SocialSourceRef, SocialSourceControl, SocialSourceControlChange, HostedPostPreview, ConnectHostedIdentityInput, PreviewHostedPostInput, PublishHostedPostInput, ListProtocolCandidatesParams, ProtocolAdapterMaturity, ProtocolAdapterMetadata, ProtocolCandidateListResponse, ProtocolCandidatePageMeta, ProtocolCapabilityOperation, ProtocolCapabilityStatus, ProtocolCollectionStatus, ProtocolQuarantinedCandidate, ProtocolRefreshResult, ProtocolSettings, ProtocolSettingsUpdateResult, UpdateSettingsInput as UpdateProtocolSettingsInput, } from './resources/protocols.js';
|
|
197
|
+
export type { SocialProfile, SocialSubscription, SocialSubscriptionChange, SocialProfilePage, SocialNetwork, SocialPost, SocialConversation, SocialTrend, SocialTrendProvenance, SocialTrends, SocialTrendFeed, SocialPopularProfiles, SocialAuthorFeed, SocialFollowingFeed, SocialFollowingSource, SearchPublicProfilesParams, HostedProtocolConnections, HostedProtocol, HostedProtocolIdentity, HostedNostrChallenge, HostedNostrIdentityProof, NativeNostrPrepareInput, NativeNostrPrepared, NativeNostrAccount, NativeNostrPostState, NativeNostrReceipt, NativeSocialProtocol, FederationIdentity, FederationIdentityView, NativeSocialAccount, NativeSocialCallbackInput, NativeReplyPrepareInput, NativeReplyReceipt, NativeReplyBatch, NativeReplyHistory, NativeDelegatedReplyHistoryItem, NativeNostrReplyResult, NativeNostrReplyHistoryItem, NativeReplyRemovalReceipt, NativeReplyRemovalPreview, SocialSourceRef, SocialSourceControl, SocialSourceControlChange, HostedPostPreview, ConnectHostedIdentityInput, PreviewHostedPostInput, PublishHostedPostInput, ListProtocolCandidatesParams, ProtocolAdapterMaturity, ProtocolAdapterMetadata, ProtocolCandidateListResponse, ProtocolCandidatePageMeta, ProtocolCapabilityOperation, ProtocolCapabilityStatus, ProtocolCollectionStatus, ProtocolIngestionReplayResult, ProtocolIngestionStatus, ProtocolQuarantinedCandidate, ProtocolRefreshResult, ProtocolSettings, ProtocolSettingsUpdateResult, ReplayProtocolIngestionJobInput, UpdateSettingsInput as UpdateProtocolSettingsInput, } from './resources/protocols.js';
|
|
193
198
|
export { InboxResource } from './resources/inbox.js';
|
|
194
199
|
export { NetworkResource } from './resources/network.js';
|
|
195
200
|
export { SimulatorResource } from './resources/simulator.js';
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { PostsResource } from './resources/posts.js';
|
|
|
4
4
|
import { UsersResource } from './resources/users.js';
|
|
5
5
|
import { CommunitiesResource } from './resources/communities.js';
|
|
6
6
|
import { ChatResource } from './resources/chat.js';
|
|
7
|
+
import { E2eeResource } from './resources/e2ee.js';
|
|
7
8
|
import { ProjectsResource } from './resources/projects.js';
|
|
8
9
|
import { AgentsResource } from './resources/agents.js';
|
|
9
10
|
import { EvidenceResource } from './resources/evidence.js';
|
|
@@ -65,6 +66,8 @@ export class Recursiv {
|
|
|
65
66
|
users;
|
|
66
67
|
communities;
|
|
67
68
|
chat;
|
|
69
|
+
/** E2EE v2 ciphertext transport (flag-gated). */
|
|
70
|
+
e2ee;
|
|
68
71
|
projects;
|
|
69
72
|
agents;
|
|
70
73
|
evidence;
|
|
@@ -125,6 +128,7 @@ export class Recursiv {
|
|
|
125
128
|
this.users = new UsersResource(client);
|
|
126
129
|
this.communities = new CommunitiesResource(client);
|
|
127
130
|
this.chat = new ChatResource(client);
|
|
131
|
+
this.e2ee = new E2eeResource(client);
|
|
128
132
|
this.projects = new ProjectsResource(client);
|
|
129
133
|
this.agents = new AgentsResource(client);
|
|
130
134
|
this.evidence = new EvidenceResource(client);
|
|
@@ -200,6 +204,7 @@ export { PostsResource } from './resources/posts.js';
|
|
|
200
204
|
export { UsersResource } from './resources/users.js';
|
|
201
205
|
export { CommunitiesResource } from './resources/communities.js';
|
|
202
206
|
export { ChatResource } from './resources/chat.js';
|
|
207
|
+
export { E2eeResource } from './resources/e2ee.js';
|
|
203
208
|
export { ProjectsResource } from './resources/projects.js';
|
|
204
209
|
export { AgentsResource, SUPPORTED_MODELS } from './resources/agents.js';
|
|
205
210
|
export { EvidenceResource } from './resources/evidence.js';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { HttpClient } from '../client.js';
|
|
2
|
+
import type { SingleResponse } from '../types.js';
|
|
3
|
+
/** Public device record from the E2EE v2 directory. Never contains private keys. */
|
|
4
|
+
export interface E2eeDevice {
|
|
5
|
+
id: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
deviceName: string;
|
|
8
|
+
realm: string;
|
|
9
|
+
signingKey: string;
|
|
10
|
+
credential: unknown;
|
|
11
|
+
isRoot: boolean;
|
|
12
|
+
status: 'active' | 'revoked' | string;
|
|
13
|
+
revokedAt: string | null;
|
|
14
|
+
}
|
|
15
|
+
/** Opaque `recursiv-mls-v2-draft1` envelope with base64 MLS bytes. */
|
|
16
|
+
export interface E2eeEnvelope {
|
|
17
|
+
profile: 'recursiv-mls-v2-draft1';
|
|
18
|
+
realm: string;
|
|
19
|
+
conversation: string;
|
|
20
|
+
event_id: string;
|
|
21
|
+
sender_device: string;
|
|
22
|
+
kind: 'application' | 'commit';
|
|
23
|
+
mls: string;
|
|
24
|
+
}
|
|
25
|
+
export interface E2eeEvent {
|
|
26
|
+
seq: number;
|
|
27
|
+
kind: string;
|
|
28
|
+
envelope: E2eeEnvelope;
|
|
29
|
+
/** Present only for the device the Welcome was issued to. */
|
|
30
|
+
welcome: string | null;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* E2EE v2 ciphertext transport. The server relays envelopes and public
|
|
35
|
+
* credentials only; encryption happens in the shared core on each device.
|
|
36
|
+
* Requires the `e2eeV2` network feature flag.
|
|
37
|
+
*/
|
|
38
|
+
export declare class E2eeResource {
|
|
39
|
+
private client;
|
|
40
|
+
constructor(client: HttpClient);
|
|
41
|
+
registerDevice(input: {
|
|
42
|
+
device_name: string;
|
|
43
|
+
realm: string;
|
|
44
|
+
signing_key: string;
|
|
45
|
+
credential: Record<string, unknown>;
|
|
46
|
+
}): Promise<SingleResponse<E2eeDevice>>;
|
|
47
|
+
devices(params?: {
|
|
48
|
+
user_id?: string;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
data: E2eeDevice[];
|
|
51
|
+
}>;
|
|
52
|
+
revokeDevice(deviceId: string): Promise<SingleResponse<E2eeDevice>>;
|
|
53
|
+
publishKeyPackages(input: {
|
|
54
|
+
device_id: string;
|
|
55
|
+
packages: string[];
|
|
56
|
+
}): Promise<SingleResponse<{
|
|
57
|
+
published: number;
|
|
58
|
+
}>>;
|
|
59
|
+
claimKeyPackage(input: {
|
|
60
|
+
device_id: string;
|
|
61
|
+
target_device_id: string;
|
|
62
|
+
}): Promise<SingleResponse<{
|
|
63
|
+
keyPackageId: string;
|
|
64
|
+
bytes: string;
|
|
65
|
+
device: E2eeDevice;
|
|
66
|
+
}>>;
|
|
67
|
+
appendEvent(conversationId: string, input: {
|
|
68
|
+
device_id: string;
|
|
69
|
+
envelope: E2eeEnvelope;
|
|
70
|
+
welcome?: string;
|
|
71
|
+
welcome_for_device_id?: string;
|
|
72
|
+
expected_commit_seq?: number;
|
|
73
|
+
}): Promise<SingleResponse<{
|
|
74
|
+
seq: number;
|
|
75
|
+
duplicate: boolean;
|
|
76
|
+
commitSeq: number;
|
|
77
|
+
}>>;
|
|
78
|
+
events(conversationId: string, params: {
|
|
79
|
+
device_id: string;
|
|
80
|
+
after_seq?: number;
|
|
81
|
+
limit?: number;
|
|
82
|
+
}): Promise<SingleResponse<{
|
|
83
|
+
headSeq: number;
|
|
84
|
+
commitSeq: number;
|
|
85
|
+
events: E2eeEvent[];
|
|
86
|
+
}>>;
|
|
87
|
+
acknowledge(conversationId: string, input: {
|
|
88
|
+
device_id: string;
|
|
89
|
+
seq: number;
|
|
90
|
+
}): Promise<SingleResponse<{
|
|
91
|
+
ackedSeq: number;
|
|
92
|
+
}>>;
|
|
93
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2EE v2 ciphertext transport. The server relays envelopes and public
|
|
3
|
+
* credentials only; encryption happens in the shared core on each device.
|
|
4
|
+
* Requires the `e2eeV2` network feature flag.
|
|
5
|
+
*/
|
|
6
|
+
export class E2eeResource {
|
|
7
|
+
client;
|
|
8
|
+
constructor(client) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
}
|
|
11
|
+
registerDevice(input) {
|
|
12
|
+
return this.client.post('/e2ee/devices', input);
|
|
13
|
+
}
|
|
14
|
+
devices(params) {
|
|
15
|
+
return this.client.get('/e2ee/devices', params);
|
|
16
|
+
}
|
|
17
|
+
revokeDevice(deviceId) {
|
|
18
|
+
return this.client.post(`/e2ee/devices/${encodeURIComponent(deviceId)}/revoke`);
|
|
19
|
+
}
|
|
20
|
+
publishKeyPackages(input) {
|
|
21
|
+
return this.client.post('/e2ee/key-packages', input);
|
|
22
|
+
}
|
|
23
|
+
claimKeyPackage(input) {
|
|
24
|
+
return this.client.post('/e2ee/key-packages/claim', input);
|
|
25
|
+
}
|
|
26
|
+
appendEvent(conversationId, input) {
|
|
27
|
+
// Retries are safe: the server is idempotent on (conversation, device, event id).
|
|
28
|
+
return this.client.post(`/e2ee/conversations/${encodeURIComponent(conversationId)}/events`, input, { retry: true });
|
|
29
|
+
}
|
|
30
|
+
events(conversationId, params) {
|
|
31
|
+
return this.client.get(`/e2ee/conversations/${encodeURIComponent(conversationId)}/events`, params);
|
|
32
|
+
}
|
|
33
|
+
acknowledge(conversationId, input) {
|
|
34
|
+
return this.client.post(`/e2ee/conversations/${encodeURIComponent(conversationId)}/ack`, input);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -130,6 +130,57 @@ export interface ProtocolCandidateDecisionResult {
|
|
|
130
130
|
candidate: ProtocolQuarantinedCandidate;
|
|
131
131
|
decision_id: string;
|
|
132
132
|
}
|
|
133
|
+
/** Operator view of the durable ingestion runtime for the authenticated app (goal ed3759f0 row 7). */
|
|
134
|
+
export interface ProtocolIngestionStatus {
|
|
135
|
+
/** Exactly one ingestion writer per process: the legacy collector or the runtime. */
|
|
136
|
+
mode: 'collector' | 'runtime';
|
|
137
|
+
enabled: boolean;
|
|
138
|
+
simulation: boolean;
|
|
139
|
+
/** Process-wide PROTOCOL_INGESTION_KILL_SWITCH. */
|
|
140
|
+
global_kill_switch: boolean;
|
|
141
|
+
controls_valid: boolean;
|
|
142
|
+
/** Whether this app's tuple is on the PROTOCOL_INGESTION_PROJECTS allow-list. */
|
|
143
|
+
project_allowed: boolean;
|
|
144
|
+
/** This app's operator kill switch (protocol_collection_setting.kill_switch). */
|
|
145
|
+
kill_switch: boolean;
|
|
146
|
+
jobs: {
|
|
147
|
+
queued: number;
|
|
148
|
+
leased: number;
|
|
149
|
+
done: number;
|
|
150
|
+
dead: number;
|
|
151
|
+
};
|
|
152
|
+
quotas: Array<{
|
|
153
|
+
provider_id: string;
|
|
154
|
+
window: 'run' | 'hour' | 'day';
|
|
155
|
+
killed: boolean;
|
|
156
|
+
circuit_open_until: string | null;
|
|
157
|
+
circuit_failures: number;
|
|
158
|
+
consumed: {
|
|
159
|
+
calls: number;
|
|
160
|
+
items: number;
|
|
161
|
+
bytes: number;
|
|
162
|
+
};
|
|
163
|
+
ceilings: {
|
|
164
|
+
calls: number | null;
|
|
165
|
+
items: number | null;
|
|
166
|
+
bytes: number | null;
|
|
167
|
+
};
|
|
168
|
+
}>;
|
|
169
|
+
lanes: Array<{
|
|
170
|
+
provider_id: string;
|
|
171
|
+
source_key: string;
|
|
172
|
+
source_subscription_key: string;
|
|
173
|
+
active: boolean;
|
|
174
|
+
}>;
|
|
175
|
+
}
|
|
176
|
+
export interface ReplayProtocolIngestionJobInput {
|
|
177
|
+
/** Operator note recorded on the audit row; 8 to 1024 characters. */
|
|
178
|
+
reason: string;
|
|
179
|
+
}
|
|
180
|
+
export interface ProtocolIngestionReplayResult {
|
|
181
|
+
job_id: string;
|
|
182
|
+
status: 'replayed';
|
|
183
|
+
}
|
|
133
184
|
/** App/network scope comes only from the authenticated project-bound key. */
|
|
134
185
|
export interface ListProtocolCandidatesParams {
|
|
135
186
|
protocol?: string;
|
|
@@ -497,7 +548,7 @@ export interface SocialNetwork {
|
|
|
497
548
|
url: string;
|
|
498
549
|
};
|
|
499
550
|
coverage: string;
|
|
500
|
-
capabilities: Array<'profile_search' | 'profile_read' | 'original_author_posts' | 'minds_subscription' | 'following_feed' | 'conversation_read' | 'public_trends' | 'trend_feed'>;
|
|
551
|
+
capabilities: Array<'profile_search' | 'profile_read' | 'original_author_posts' | 'minds_subscription' | 'following_feed' | 'conversation_read' | 'public_trends' | 'trend_feed' | 'popular_accounts'>;
|
|
501
552
|
profileSearchPagination: boolean;
|
|
502
553
|
conversationCoverage?: string;
|
|
503
554
|
}
|
|
@@ -598,6 +649,24 @@ export interface SocialTrendFeed extends SocialTrendProvenance {
|
|
|
598
649
|
items: SocialPost[];
|
|
599
650
|
cursor: string | null;
|
|
600
651
|
}
|
|
652
|
+
/** Provider-ranked accounts. `source` says whether this page is the app's hourly index snapshot or a live read. */
|
|
653
|
+
export interface SocialPopularProfiles {
|
|
654
|
+
items: SocialProfile[];
|
|
655
|
+
cursor: string | null;
|
|
656
|
+
provenance: {
|
|
657
|
+
provider: {
|
|
658
|
+
name: string;
|
|
659
|
+
url: string;
|
|
660
|
+
};
|
|
661
|
+
/** The provider's own ranking label, never a Minds popularity score. */
|
|
662
|
+
ranking: string;
|
|
663
|
+
fetchedAt: string;
|
|
664
|
+
coverage: 'provider_ranked_window';
|
|
665
|
+
source: 'index' | 'live';
|
|
666
|
+
/** Provider read time of the served snapshot; null for live reads. */
|
|
667
|
+
snapshotAt: string | null;
|
|
668
|
+
};
|
|
669
|
+
}
|
|
601
670
|
export interface SocialConversation {
|
|
602
671
|
focus: SocialPost;
|
|
603
672
|
/** Oldest available ancestor first, ending with the immediate parent. */
|
|
@@ -634,6 +703,14 @@ export declare class ProtocolsResource {
|
|
|
634
703
|
private subscriptionChanged;
|
|
635
704
|
/** Confirmed safety choices from this authenticated SDK instance. Unsubscribe when its account or view changes. */
|
|
636
705
|
onSourceControlChange(listener: (change: SocialSourceControlChange) => void): () => void;
|
|
706
|
+
/** Public-only conversation catalog for a configured app. Works with an anonymous client. */
|
|
707
|
+
sharedNetworks(projectId: string): Promise<SingleResponse<SocialNetwork[]>>;
|
|
708
|
+
/** Keyless public post read with app moderation; no account state or connected write authority. */
|
|
709
|
+
getSharedConversation(projectId: string, params: {
|
|
710
|
+
protocol: string;
|
|
711
|
+
post: string;
|
|
712
|
+
readRef?: string;
|
|
713
|
+
}): Promise<SingleResponse<SocialConversation>>;
|
|
637
714
|
publicNetworks(): Promise<SingleResponse<SocialNetwork[]>>;
|
|
638
715
|
/** Query the live public network. It does not import users or posts. */
|
|
639
716
|
searchPublicProfiles(params: SearchPublicProfilesParams): Promise<SingleResponse<SocialProfilePage>>;
|
|
@@ -669,6 +746,12 @@ export declare class ProtocolsResource {
|
|
|
669
746
|
limit?: number;
|
|
670
747
|
cursor?: string;
|
|
671
748
|
}): Promise<SingleResponse<SocialTrendFeed>>;
|
|
749
|
+
/** Provider-ranked public accounts with explicit provenance; served from the app's index when a fresh snapshot exists. */
|
|
750
|
+
getPublicPopularProfiles(params: {
|
|
751
|
+
protocol: string;
|
|
752
|
+
limit?: number;
|
|
753
|
+
cursor?: string;
|
|
754
|
+
}): Promise<SingleResponse<SocialPopularProfiles>>;
|
|
672
755
|
/** Prepare one exact shared reply preview. Keep the mutation ID across uncertain responses. */
|
|
673
756
|
prepareNativeReply(input: NativeReplyPrepareInput): Promise<SingleResponse<NativeReplyBatch>>;
|
|
674
757
|
/** Send only explicitly approved delivery IDs from this preview. Repeated submissions reconcile; they do not replay a write. */
|
|
@@ -832,6 +915,26 @@ export declare class ProtocolsResource {
|
|
|
832
915
|
* an agent key may only reject or escalate; escalation needs a reason.
|
|
833
916
|
*/
|
|
834
917
|
decideCandidate(id: string, input: DecideProtocolCandidateInput): Promise<SingleResponse<ProtocolCandidateDecisionResult>>;
|
|
918
|
+
/**
|
|
919
|
+
* Read the ingestion runtime status for the key's app: mode, switches, job
|
|
920
|
+
* counts, quota ledger and lanes. Read-only. Requires the app's
|
|
921
|
+
* content_intelligence_admin binding (404 otherwise) and the same
|
|
922
|
+
* project-admin authorization as listCandidates.
|
|
923
|
+
*/
|
|
924
|
+
ingestionStatus(): Promise<SingleResponse<ProtocolIngestionStatus>>;
|
|
925
|
+
/** Turn the app's ingestion kill switch on: no reservation, screening or approval proceeds. */
|
|
926
|
+
killIngestion(): Promise<SingleResponse<{
|
|
927
|
+
kill_switch: true;
|
|
928
|
+
}>>;
|
|
929
|
+
/** Turn the app's ingestion kill switch off. Does not enable the runtime by itself. */
|
|
930
|
+
resumeIngestion(): Promise<SingleResponse<{
|
|
931
|
+
kill_switch: false;
|
|
932
|
+
}>>;
|
|
933
|
+
/**
|
|
934
|
+
* Requeue one dead ingestion job. Refused (409) while the runtime is
|
|
935
|
+
* disabled, simulating or killed; 404 when no dead job matches in this app.
|
|
936
|
+
*/
|
|
937
|
+
replayIngestionJob(jobId: string, input: ReplayProtocolIngestionJobInput): Promise<SingleResponse<ProtocolIngestionReplayResult>>;
|
|
835
938
|
/**
|
|
836
939
|
* Read one quarantined candidate under the same authorization as listCandidates.
|
|
837
940
|
* Empty and URL dot-segment IDs reject with ValidationError before any request;
|
|
@@ -60,6 +60,16 @@ export class ProtocolsResource {
|
|
|
60
60
|
this.sourceControlListeners.add(listener);
|
|
61
61
|
return () => { this.sourceControlListeners.delete(listener); };
|
|
62
62
|
}
|
|
63
|
+
/** Public-only conversation catalog for a configured app. Works with an anonymous client. */
|
|
64
|
+
sharedNetworks(projectId) {
|
|
65
|
+
return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/networks`);
|
|
66
|
+
}
|
|
67
|
+
/** Keyless public post read with app moderation; no account state or connected write authority. */
|
|
68
|
+
getSharedConversation(projectId, params) {
|
|
69
|
+
return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/conversation`, {
|
|
70
|
+
protocol: params.protocol, post: params.post, readRef: params.readRef,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
63
73
|
publicNetworks() {
|
|
64
74
|
return this.client.get('/protocols/social/networks');
|
|
65
75
|
}
|
|
@@ -96,6 +106,10 @@ export class ProtocolsResource {
|
|
|
96
106
|
getPublicTrendFeed(params) {
|
|
97
107
|
return this.client.get('/protocols/social/trend-feed', { protocol: params.protocol, topic: params.topic, limit: params.limit, cursor: params.cursor });
|
|
98
108
|
}
|
|
109
|
+
/** Provider-ranked public accounts with explicit provenance; served from the app's index when a fresh snapshot exists. */
|
|
110
|
+
getPublicPopularProfiles(params) {
|
|
111
|
+
return this.client.get('/protocols/social/popular-profiles', { protocol: params.protocol, limit: params.limit, cursor: params.cursor });
|
|
112
|
+
}
|
|
99
113
|
/** Prepare one exact shared reply preview. Keep the mutation ID across uncertain responses. */
|
|
100
114
|
prepareNativeReply(input) {
|
|
101
115
|
return this.client.post('/protocols/social/replies/prepare', { clientMutationId: input.clientMutationId, text: input.text,
|
|
@@ -308,6 +322,30 @@ export class ProtocolsResource {
|
|
|
308
322
|
async decideCandidate(id, input) {
|
|
309
323
|
return this.client.post(`/protocols/candidates/${encodeURIComponent(assertCandidateId(id))}/decision`, input);
|
|
310
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Read the ingestion runtime status for the key's app: mode, switches, job
|
|
327
|
+
* counts, quota ledger and lanes. Read-only. Requires the app's
|
|
328
|
+
* content_intelligence_admin binding (404 otherwise) and the same
|
|
329
|
+
* project-admin authorization as listCandidates.
|
|
330
|
+
*/
|
|
331
|
+
ingestionStatus() {
|
|
332
|
+
return this.client.get('/protocols/ingestion/status');
|
|
333
|
+
}
|
|
334
|
+
/** Turn the app's ingestion kill switch on: no reservation, screening or approval proceeds. */
|
|
335
|
+
killIngestion() {
|
|
336
|
+
return this.client.post('/protocols/ingestion/kill', {});
|
|
337
|
+
}
|
|
338
|
+
/** Turn the app's ingestion kill switch off. Does not enable the runtime by itself. */
|
|
339
|
+
resumeIngestion() {
|
|
340
|
+
return this.client.post('/protocols/ingestion/resume', {});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Requeue one dead ingestion job. Refused (409) while the runtime is
|
|
344
|
+
* disabled, simulating or killed; 404 when no dead job matches in this app.
|
|
345
|
+
*/
|
|
346
|
+
async replayIngestionJob(jobId, input) {
|
|
347
|
+
return this.client.post(`/protocols/ingestion/replay/${encodeURIComponent(assertCandidateId(jobId))}`, input);
|
|
348
|
+
}
|
|
311
349
|
/**
|
|
312
350
|
* Read one quarantined candidate under the same authorization as listCandidates.
|
|
313
351
|
* Empty and URL dot-segment IDs reject with ValidationError before any request;
|
package/llm.md
CHANGED
|
@@ -476,6 +476,19 @@ const { data: msgs } = await r.chat.messages(dm.id, { limit: 50 })
|
|
|
476
476
|
|
|
477
477
|
Methods: `conversations`, `communityConversation`, `conversation`, `messages`, `send`, `dm`, `createGroup`, `deleteConversation`, `reactToMessage`, `editMessage`, `deleteMessage`, `markAsRead`, `unreadCount`
|
|
478
478
|
|
|
479
|
+
### r.e2ee — End-to-end encryption transport (flag-gated)
|
|
480
|
+
|
|
481
|
+
Relays opaque MLS envelopes, public device credentials and one-time key packages for the shared E2EE core; the server never sees keys or plaintext. Requires the `e2eeV2` network feature flag; otherwise every call returns `feature_disabled`.
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
const { data: device } = await r.e2ee.registerDevice({ device_name: 'phone-1', realm: 'minds', signing_key, credential });
|
|
485
|
+
await r.e2ee.publishKeyPackages({ device_id: device.id, packages: [keyPackageBase64] });
|
|
486
|
+
const { data: claimed } = await r.e2ee.claimKeyPackage({ device_id: device.id, target_device_id: peerDeviceId });
|
|
487
|
+
await r.e2ee.appendEvent(conversationId, { device_id: device.id, envelope }); // idempotent per event_id
|
|
488
|
+
const { data: page } = await r.e2ee.events(conversationId, { device_id: device.id, after_seq: 0 });
|
|
489
|
+
await r.e2ee.acknowledge(conversationId, { device_id: device.id, seq: page.headSeq });
|
|
490
|
+
```
|
|
491
|
+
|
|
479
492
|
### r.realtime — WebSocket Chat Client
|
|
480
493
|
|
|
481
494
|
Provides persistent real-time streaming and chat presence, useful for building frontends (e.g. React Native, Web).
|
|
@@ -620,7 +633,7 @@ if (subscription.active) {
|
|
|
620
633
|
- `r.inviteCodes` / `r.inviteCodesAdmin` — Invite code management
|
|
621
634
|
- `r.organizationSettings` / `r.organizationSecurity` — Org configuration
|
|
622
635
|
- Delegated social accounts: `r.protocols.nativeSocialAccounts()`, `startNativeSocialConnection({ protocol, identifier })`, `finishNativeSocialConnection({ protocol, state, code?, iss?, error? })`, `disconnectNativeSocialAccount(id)`. Example: `const { data } = await r.protocols.startNativeSocialConnection({ protocol: "bluesky", identifier: "alice.bsky.social" })`; open `data.authorizationUrl`, then complete with the same signed-in app user. Never log callback codes, send passwords, or auto-retry OAuth callbacks. Shared replies (off until schema/API deployment and live verification): `prepareNativeReply({ clientMutationId, text, parent: { protocol, nativeId, readRef? }, accountIds, linkedPostAccountIds?, recoverFrom?: { batchId, deliveryIds } })`, `submitNativeReply(id, { approve: true, deliveryIds })`, `nativeReplyStatus(id)`, `nativeReplyHistory({ limit?, cursor? })`, `prepareNativeReplyRemoval(id, { deliveryIds })`, `removeNativeReply(id, { approve: true, removals })`. Review account, destination, `kind`, source and exact `wireText`; connection is not publication approval. `linkedPostAccountIds` explicitly selects different-network standalone posts with a source link, never matching threaded replies or a same-network denial fallback. Preserve mutation IDs, show per-destination results and reconcile uncertain attempts without reposting. To review selected unsent or definitively rejected deliveries again, use recoverFrom with a new mutation ID, the same source/accounts and freshly reviewed text; preserve that ID on uncertain preparation. Only saved recoverable destinations qualify, current gates still apply, and replacedBy disables old sends atomically. Never restart unknown, accepted or published deliveries. The new preview still needs explicit approval. Saved delegated drafts/results: `const { data: history } = await r.protocols.nativeReplyHistory({ limit: 20 })`; use its opaque cursor for the next page and `nativeReplyStatus(item.id)` for details. This is a private read, not a write or provider refresh, and includes Nostr results marked type=nostr. Use nativeNostrReplyResult(item.id) to check that recorded event on its relay without signing or resending. Discard page state on owner/app changes. See README for examples and the callback, revocation and removal contracts.
|
|
623
|
-
- `r.protocols` — Private app safety: `sourceControls` returns current `enabled` plus paged saved choices; `setSourceControl`, `onSourceControlChange` and `reportSource` share app scope. Example: `const choices = new Map(); const stop = r.protocols.onSourceControlChange(change => choices.set(JSON.stringify([change.source, change.control]), change.enabled));` then `await r.protocols.setSourceControl({ source: { protocol: "bluesky", kind: "actor", nativeId: "did:plc:aaaaaaaaaaaaaaaaaaaaaaaa" }, control: "mute", enabled: true, scope: "minds" });` and call `stop(); choices.clear()` on account change/unmount. Notifications follow an exact server confirmation, never an uncertain response. These preferences and reports apply in Minds, not on the remote network.
|
|
636
|
+
- `r.protocols` — Private app safety: `sourceControls` returns current `enabled` plus paged saved choices; `setSourceControl`, `onSourceControlChange` and `reportSource` share app scope. Example: `const choices = new Map(); const stop = r.protocols.onSourceControlChange(change => choices.set(JSON.stringify([change.source, change.control]), change.enabled));` then `await r.protocols.setSourceControl({ source: { protocol: "bluesky", kind: "actor", nativeId: "did:plc:aaaaaaaaaaaaaaaaaaaaaaaa" }, control: "mute", enabled: true, scope: "minds" });` and call `stop(); choices.clear()` on account change/unmount. Notifications follow an exact server confirmation, never an uncertain response. These preferences and reports apply in Minds, not on the remote network. Keyless post links: `const visitor = new Recursiv({ anonymous: true }); const { data: thread } = await visitor.protocols.getSharedConversation(projectId, { protocol: 'nostr', post: publicEventId })`; `sharedNetworks(projectId)` lists public conversation capabilities. Only configured apps; app moderation and rate limits apply, no member state or write authority. Member public reading: `publicNetworks`, `searchPublicProfiles`, `getPublicProfile`, `getPublicAuthorFeed`, `getFollowingFeed`, `getPublicConversation`, `getPublicTrends`, `getPublicTrendFeed`; private app subscriptions: `listSubscriptions`, `subscribeToProfile`, `unsubscribeFromProfile`, `onSubscriptionChange`. Example after selecting a returned source post: `const { data: thread } = await r.protocols.getPublicConversation({ protocol: post.protocol, post: post.nativeId, readRef: post.readRef })`. Render `focus`, oldest-first `ancestors` and direct `replies`; `public_provider_window` never promises every reply, and `limited` marks known omissions. Requires both `users:read` and `posts:read` on the current human app key. Protocol discovery/settings: `const { data: adapters } = await r.protocols.list()` returns bounded `{ id, name, icon, color, maturity, capabilities, limitations }` metadata; `supported` means implemented, not configured, healthy, authorized, or enabled. Methods: `list`, `status`, `listCandidates`, `getCandidate`, `search`, `getSettings`, `refresh`, `updateSettings`.
|
|
624
637
|
- Native Nostr: `const { data: preview } = await r.protocols.prepareNativeNostr(identityId, { action: "publish", content: draft })`; review and sign the exact public event, then `submitNativeNostr(identityId, { intent: preview.intent, event, approve: true })`. Preparation/submission never auto-retry. After uncertainty, use `getNativeNostrPost(identityId, preview.postId ?? preview.eventId)` before a user-selected retry of the identical intent/event: deletion checks the original note's `postId`, publication checks `eventId`. Check `nativeNostrAccount()` enablement first; keys stay with the signer. For replies, after `nativeNostrAccount()` advertises `reply_text_note`, use `prepareNativeNostr(identityId, { action: "reply", content: draft, parentId: post.nativeId })`. Review returned parent/root/participants/relay and exact event, sign with the connected client signer, then `submitNativeNostr(identityId, { intent, event, approve: true })`. Requires users:read, posts:read and posts:write. Kind1 public notes only; reply enablement and shared UI/live proof remain pending. Do not inherit arbitrary notification tags or relay hints. Signing mutations never auto-retry; check `getNativeNostrPost(identityId, eventId)` after uncertainty before a user-selected identical-event retry.
|
|
625
638
|
- Public trends: require `public_trends` from `publicNetworks()`, then `getPublicTrends({ protocol, limit?, cursor? })`; render `kind: topics` as source topics and `kind: posts` as source posts. With `trend_feed`, open only a returned current topic using `getPublicTrendFeed({ protocol, topic: trend.nativeId, limit?, cursor? })`. Show provider, observedAt and provider_ranked_window coverage; null rankingWindow is unknown, not a daily/global ranking. Preserve source order, canonical IDs and readRef, and opaque cursors. Topic catalogs do not paginate; Mastodon trends stop at 200 source positions. Both methods require users:read plus posts:read on the current human app key; Nostr trends are unsupported. Propagate errors; trend_unavailable means refresh the topic list. No ingestion or native writes.
|
|
626
639
|
- `listCandidates({ protocol?, limit?, cursor? })` and `getCandidate(id)` are read-only quarantine review, not published-post search. Both require `admin` scope, a project-bound key, a live admin role, and existing project-admin access. The key supplies app/network scope; neither method accepts another project or network. They never invoke refresh, change settings, or publish.
|