@layers/amba 1.0.1 → 4.0.2

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.
@@ -0,0 +1,366 @@
1
+ # Social
2
+
3
+ The social graph and everything that runs on top of it: friendships (with block lists), groups (guilds / clubs), activity feeds with rule-driven filters, 1:1 + group messaging, user-generated reviews, and the moderation queue + trust system that keeps it all from rotting.
4
+
5
+ Most of this is "create-the-rule, let-the-SDK-call-it" — feeds are rule-driven, moderation has its own queue, friend graph is bidirectional. Only the structural pieces (feed rules, moderation rules, group capacity) are MCP-provisioned; the runtime calls (`Amba.friends.sendRequest`, `Amba.messaging.sendMessage`, `Amba.feeds.getActivity`) are SDK-side.
6
+
7
+ ## MCP tools
8
+
9
+ ### Friendships
10
+
11
+ | Tool | Purpose | Example args |
12
+ | --- | --- | --- |
13
+ | `amba_friendships_list` / `amba_list_friendships` | List friendships in a project (admin-side — for a moderator panel). | `{ project_id, status: "accepted", limit: 100 }` |
14
+ | `amba_friendships_get_stats` / `amba_get_friendship_stats` | Aggregate friendship metrics — total accepted, pending, blocked. | `{ project_id }` |
15
+ | `amba_friendships_delete` / `amba_delete_friendship` | Admin-delete a friendship row (e.g. moderation outcome). | `{ project_id, friendship_id }` |
16
+
17
+ Friend requests + accept/decline + block are SDK-side (`Amba.friends.sendRequest(...)` etc.). There's no MCP tool to create a friendship — by design, only end-users can.
18
+
19
+ ### Groups
20
+
21
+ | Tool | Purpose | Example args |
22
+ | --- | --- | --- |
23
+ | `amba_groups_create` / `amba_create_group` | Create a group (guild / club / squad). | `{ project_id, name: "Morning Runners", owner_id: "u_…", description: "5am crew", is_public: true, max_members: 100 }` |
24
+ | `amba_groups_list` / `amba_list_groups` | List groups. | `{ project_id, limit: 50 }` |
25
+ | `amba_groups_update` / `amba_update_group` | Edit a group (rename, change visibility, change cap). | `{ project_id, group_id, max_members: 500 }` |
26
+ | `amba_groups_delete` / `amba_delete_group` | Delete a group. | `{ project_id, group_id }` |
27
+ | `amba_groups_list_members` / `amba_list_group_members` | List members in a group. | `{ project_id, group_id }` |
28
+ | `amba_groups_update_member` / `amba_update_group_member` | Change a member's role (promote to admin / mute). | `{ project_id, group_id, member_id, role: "admin" }` |
29
+ | `amba_groups_remove_member` / `amba_remove_group_member` | Kick a member. | `{ project_id, group_id, member_id }` |
30
+
31
+ ### Feeds
32
+
33
+ Activity feeds are rule-driven: each rule says "events of type X published by users matching Y should appear in feed Z". Items land in feeds automatically when matching events fire.
34
+
35
+ | Tool | Purpose | Example args |
36
+ | --- | --- | --- |
37
+ | `amba_feeds_rules_create` / `amba_create_feed_rule` | Define a feed rule. | `{ project_id, feed: "global", event: "post_published", filter: { all: [{ field: "user.is_creator", op: "==", value: true }] } }` |
38
+ | `amba_feeds_list_rules` | List rules. | `{ project_id, feed }` |
39
+ | `amba_feeds_patch_rule` | Edit a rule (change filter, change destination feed). | `{ project_id, rule_id, filter: {...} }` |
40
+ | `amba_feeds_delete_rule` | Delete a rule. | `{ project_id, rule_id }` |
41
+ | `amba_feeds_list_items` | List items in a feed (admin / debugging). | `{ project_id, feed: "global", limit: 50 }` |
42
+ | `amba_feeds_delete_item` | Remove a single feed item (moderation). | `{ project_id, feed, item_id }` |
43
+
44
+ Conventional feed names: `global` (everyone), `following` (just users you follow), `group:<group_id>` (a single group's feed).
45
+
46
+ ### Messaging
47
+
48
+ Mostly SDK-side — admin tools are for moderation + stats.
49
+
50
+ | Tool | Purpose | Example args |
51
+ | --- | --- | --- |
52
+ | `amba_messaging_list_conversations` | List conversations (admin / moderation view). | `{ project_id, limit: 50 }` |
53
+ | `amba_messaging_list_messages` | List messages in a conversation. | `{ project_id, conversation_id, limit: 100 }` |
54
+ | `amba_messaging_delete_message` | Hard-delete a message (moderation). | `{ project_id, conversation_id, message_id }` |
55
+ | `amba_messaging_get_stats` / `amba_get_messaging_stats` | Aggregate messaging metrics. | `{ project_id }` |
56
+
57
+ ### Moderation
58
+
59
+ | Tool | Purpose | Example args |
60
+ | --- | --- | --- |
61
+ | `amba_moderation_configure` / `amba_configure_moderation` | Set the project's default moderation policy. | `{ project_id, auto_review_threshold: 0.8, default_action: "queue", auto_block_threshold: 0.95 }` |
62
+ | `amba_moderation_list_rules` | List rules. | `{ project_id }` |
63
+ | `amba_moderation_update_rule` | Edit a rule. | `{ project_id, rule_id, action: "block" }` |
64
+ | `amba_moderation_delete_rule` | Delete a rule. | `{ project_id, rule_id }` |
65
+ | `amba_moderation_queue_list` / `amba_get_moderation_queue` | List pending reports. | `{ project_id, status: "pending", limit: 50 }` |
66
+ | `amba_moderation_queue_get` | Fetch one report. | `{ project_id, report_id }` |
67
+ | `amba_moderation_queue_approve` | Approve (mark report as resolved with no action). | `{ project_id, report_id, reason: "false positive" }` |
68
+ | `amba_moderation_queue_reject` | Reject (take action — hide/delete content, ban user). | `{ project_id, report_id, action: "delete_message", reason: "spam" }` |
69
+ | `amba_moderation_queue_escalate` | Escalate to a senior moderator. | `{ project_id, report_id }` |
70
+ | `amba_moderation_list_trust` | List per-user trust scores. | `{ project_id, limit: 100 }` |
71
+ | `amba_moderation_set_trust` | Manually bump a user's trust score. | `{ project_id, user_id, trust_score: 0.9, reason: "verified power user" }` |
72
+
73
+ ### Reviews
74
+
75
+ | Tool | Purpose | Example args |
76
+ | --- | --- | --- |
77
+ | `amba_reviews_list` | List reviews. | `{ project_id, target_type: "catalog_item", target_id: "...", limit: 50 }` |
78
+ | `amba_reviews_list_items` | List the things that have reviews on them. | `{ project_id, target_type: "catalog_item" }` |
79
+ | `amba_reviews_patch` | Edit / hide a review (moderation). | `{ project_id, review_id, hidden: true }` |
80
+ | `amba_reviews_delete` | Delete a review. | `{ project_id, review_id }` |
81
+ | `amba_reviews_get_stats` / `amba_get_review_stats` | Aggregate review stats. | `{ project_id, target_type, target_id }` |
82
+ | `amba_reviews_export` | Export to CSV / JSON. | `{ project_id, format: "csv" }` |
83
+
84
+ ## SDK init per stack
85
+
86
+ `Amba.configure(...)` runs first. Snippets below are the social-only calls.
87
+
88
+ ### Expo
89
+
90
+ ```tsx
91
+ import { Amba } from '@layers/amba-expo';
92
+
93
+ // Send a friend request
94
+ const friendship = await Amba.friends.sendRequest(otherUserId);
95
+ // friendship.status === 'pending' (until the other user accepts)
96
+
97
+ // List friendships (incoming requests, friends, blocks)
98
+ const all = await Amba.friends.getList();
99
+ const friends = await Amba.friends.getFriends(); // accepted only
100
+
101
+ // Accept / decline / unfriend
102
+ await Amba.friends.acceptRequest(friendship.id);
103
+ await Amba.friends.declineRequest(friendship.id);
104
+ await Amba.friends.removeFriend(otherUserId);
105
+ await Amba.friends.blockUser(otherUserId);
106
+
107
+ // Groups
108
+ const group = await Amba.groups.create({ name: 'Morning Runners' });
109
+ const fetched = await Amba.groups.get(group.id);
110
+
111
+ // Messaging — 1:1 conversation
112
+ const conv = await Amba.messaging.createConversation({
113
+ participant_ids: [otherUserId],
114
+ type: 'direct',
115
+ });
116
+ const msg = await Amba.messaging.sendMessage(conv.id, {
117
+ body: 'hey, want to start a daily streak together?',
118
+ });
119
+ const inbox = await Amba.messaging.conversations();
120
+ const messages = await Amba.messaging.listMessages(conv.id, { limit: 50 });
121
+ await Amba.messaging.markRead(conv.id);
122
+
123
+ // Feeds
124
+ const { items, next_cursor } = await Amba.feeds.getActivity('global');
125
+
126
+ // Reviews
127
+ const reviews = await Amba.reviews.list('catalog_item', 'premium_theme');
128
+ await Amba.reviews.create({
129
+ target_type: 'catalog_item',
130
+ target_id: 'premium_theme',
131
+ rating: 5,
132
+ body: 'Beautiful theme!',
133
+ });
134
+
135
+ // Moderation — user-side
136
+ await Amba.moderation.reportUser({
137
+ reported_user_id: otherUserId,
138
+ reason: 'harassment',
139
+ });
140
+ await Amba.moderation.reportContent({
141
+ target_type: 'message',
142
+ target_id: msg.id,
143
+ reason: 'spam',
144
+ });
145
+ ```
146
+
147
+ ### React Native (bare)
148
+
149
+ Identical surface:
150
+
151
+ ```tsx
152
+ import { Amba } from '@layers/amba-react-native';
153
+
154
+ const friendship = await Amba.friends.sendRequest(otherUserId);
155
+ const conv = await Amba.messaging.createConversation({
156
+ participant_ids: [otherUserId],
157
+ type: 'direct',
158
+ });
159
+ const msg = await Amba.messaging.sendMessage(conv.id, { body: 'hi' });
160
+ const feed = await Amba.feeds.getActivity('global');
161
+ ```
162
+
163
+ ### Web
164
+
165
+ ```ts
166
+ import { Amba } from '@layers/amba-web';
167
+
168
+ // Friend graph
169
+ await Amba.friends.sendRequest(otherUserId);
170
+ const friends = await Amba.friends.getFriends();
171
+
172
+ // Messaging
173
+ const conv = await Amba.messaging.createConversation({
174
+ participant_ids: [otherUserId],
175
+ type: 'direct',
176
+ });
177
+ await Amba.messaging.sendMessage(conv.id, { body: 'hello' });
178
+
179
+ // Feed
180
+ const activity = await Amba.feeds.getActivity('global');
181
+ ```
182
+
183
+ With `@layers/amba-react`, build hooks on top:
184
+
185
+ ```tsx
186
+ import { useEffect, useState } from 'react';
187
+ import { Amba } from '@layers/amba-web';
188
+
189
+ export function useConversations() {
190
+ const [conversations, setConversations] = useState<Conversation[] | null>(null);
191
+ useEffect(() => {
192
+ (async () => setConversations(await Amba.messaging.conversations()))();
193
+ }, []);
194
+ return conversations;
195
+ }
196
+ ```
197
+
198
+ ### iOS (Swift)
199
+
200
+ ```swift
201
+ import Amba
202
+
203
+ // Friendships
204
+ let friendship = try await Amba.friends.sendRequest(userId: otherUserId)
205
+ let friends = try await Amba.friends.getFriends()
206
+ _ = try await Amba.friends.acceptRequest(friendshipId: friendship.id)
207
+
208
+ // Groups
209
+ let group = try await Amba.groups.create(GroupCreate(name: "Morning Runners"))
210
+
211
+ // Messaging
212
+ let conv = try await Amba.messaging.createConversation(CreateConversationRequest(
213
+ participantIds: [otherUserId],
214
+ type: .direct
215
+ ))
216
+ let msg = try await Amba.messaging.sendMessage(
217
+ conversationId: conv.id,
218
+ request: SendMessageRequest(body: "hi")
219
+ )
220
+ let convs = try await Amba.messaging.conversations()
221
+ let messages = try await Amba.messaging.listMessages(conversationId: conv.id)
222
+ _ = try await Amba.messaging.markRead(conversationId: conv.id)
223
+
224
+ // Feeds
225
+ let feed = try await Amba.feeds.getActivity(feed: "global")
226
+
227
+ // Reviews
228
+ let reviews = try await Amba.reviews.list(targetType: "catalog_item", targetId: "premium_theme")
229
+ _ = try await Amba.reviews.create(ReviewCreate(
230
+ targetType: "catalog_item",
231
+ targetId: "premium_theme",
232
+ rating: 5,
233
+ body: "Beautiful theme!"
234
+ ))
235
+
236
+ // Moderation
237
+ _ = try await Amba.moderation.reportUser(ReportRequest(
238
+ reportedUserId: otherUserId,
239
+ reason: "harassment"
240
+ ))
241
+ ```
242
+
243
+ ### Android (Kotlin)
244
+
245
+ ```kotlin
246
+ val friendship = Amba.friends.sendRequest(otherUserId)
247
+ val friends = Amba.friends.getFriends()
248
+ Amba.friends.acceptRequest(friendship.id)
249
+
250
+ val group = Amba.groups.create(GroupCreate(name = "Morning Runners"))
251
+
252
+ val conv = Amba.messaging.createConversation(
253
+ CreateConversationRequest(participantIds = listOf(otherUserId), type = "direct")
254
+ )
255
+ val msg = Amba.messaging.sendMessage(
256
+ conversationId = conv.id,
257
+ request = SendMessageRequest(body = "hi")
258
+ )
259
+ Amba.messaging.markRead(conv.id)
260
+
261
+ val feed = Amba.feeds.getActivity("global")
262
+ val reviews = Amba.reviews.list("catalog_item", "premium_theme")
263
+ Amba.moderation.reportUser(ReportRequest(reportedUserId = otherUserId, reason = "harassment"))
264
+ ```
265
+
266
+ ### Flutter
267
+
268
+ ```dart
269
+ import 'package:amba/amba.dart';
270
+
271
+ final friendship = await Amba.friends.sendRequest(otherUserId);
272
+ final friends = await Amba.friends.getFriends();
273
+ await Amba.friends.acceptRequest(friendship.id);
274
+
275
+ final group = await Amba.groups.create(GroupCreate(name: 'Morning Runners'));
276
+
277
+ final conv = await Amba.messaging.createConversation(
278
+ CreateConversationRequest(
279
+ participantIds: [otherUserId],
280
+ type: ConversationType.direct,
281
+ ),
282
+ );
283
+ final msg = await Amba.messaging.sendMessage(
284
+ conv.id,
285
+ SendMessageRequest(body: 'hi'),
286
+ );
287
+ await Amba.messaging.markRead(conv.id);
288
+
289
+ final feed = await Amba.feeds.getActivity('global');
290
+ final reviews = await Amba.reviews.list('catalog_item', 'premium_theme');
291
+ await Amba.moderation.reportUser(
292
+ ReportRequest(reportedUserId: otherUserId, reason: 'harassment'),
293
+ );
294
+ ```
295
+
296
+ ## Common follow-ups
297
+
298
+ Batch.
299
+
300
+ 1. **Which social features?** (multi-select)
301
+ - [x] Friend graph (friend requests, accept/decline, block, unfriend)
302
+ - [ ] Groups / guilds (multi-user)
303
+ - [x] 1:1 messaging
304
+ - [ ] Group messaging
305
+ - [x] Activity feed
306
+ - [ ] User reviews (on catalog items / on other users)
307
+ - [x] Moderation queue + user-report flow (recommended whenever messaging or feed is on)
308
+
309
+ 2. **Default feed:**
310
+ - Global (everyone) (recommended for content_creator, social)
311
+ - Following (only people you friend) (recommended for dating, fitness — privacy-leaning)
312
+ - Both — wire two feeds, let users switch
313
+
314
+ 3. **Feed rule: what event lands in the feed?**
315
+ - For fitness: `workout_completed` (with user details)
316
+ - For social: `post_published`
317
+ - For game: `level_completed`
318
+ - For education: `lesson_completed`
319
+ - Custom — I'll provide
320
+
321
+ 4. **Moderation policy:** (only ask if any social feature was chosen)
322
+ - Auto-block obvious abuse (>= 0.95 confidence), queue the rest (>= 0.8 confidence), allow below (recommended)
323
+ - Queue everything — manual review of all flagged content (slow but human-in-the-loop)
324
+ - Allow everything — only act on user reports (anything-goes; for closed communities only)
325
+
326
+ 5. **Dating-specific:**
327
+ - Match-only messaging (can only message users you've matched with) — recommended for dating apps
328
+ - Open messaging (any user can DM any user)
329
+ - Group chats enabled?
330
+
331
+ 6. **Reviews (only if economy surface is wired):**
332
+ - Catalog item reviews (users rate things they bought)
333
+ - User-on-user reviews (e.g. for marketplaces, dating)
334
+ - Both
335
+
336
+ ## Re-run behavior
337
+
338
+ 1. `.amba/wired.json`:
339
+
340
+ ```json
341
+ {
342
+ "surfaces": {
343
+ "social": {
344
+ "friends": true,
345
+ "groups": false,
346
+ "messaging": { "direct": true, "group": false },
347
+ "feeds": { "rules": ["global/post_published"] },
348
+ "reviews": { "target_types": ["catalog_item"] },
349
+ "moderation": { "auto_review_threshold": 0.8, "auto_block_threshold": 0.95 }
350
+ }
351
+ }
352
+ }
353
+ ```
354
+
355
+ 2. Before creating:
356
+ - `amba_feeds_list_rules` — match on `feed + event + filter`. Collision → ask to update or skip.
357
+ - `amba_groups_list` — group names aren't unique; only skip if `name + owner_id` collides.
358
+ - `amba_moderation_list_rules` — match on rule key.
359
+
360
+ 3. **Never delete a group, friendship, or message without explicit confirmation** — these are user-created. If the user asks to "wipe friendships", give them `amba_moderation_queue_list` to find the actually-problematic rows first.
361
+
362
+ 4. If the user enables messaging on re-run, double-check whether moderation is already wired. If not, **strongly recommend** turning it on before opening the messaging surface to all users — wire it in the same pass (additive — `amba_moderation_configure`).
363
+
364
+ 5. For abusive-user enforcement, prefer trust-score updates (`amba_moderation_set_trust({ trust_score: 0.0 })`) and report rejection over user deletion. Deletion is `amba_users_delete` and is destructive — only on a user-initiated GDPR-style request.
365
+
366
+ 6. Update `wired.json` to append (new rules to `feeds.rules`, new target types to `reviews.target_types`, etc.).