@prismer/sdk 1.7.4 → 1.8.1

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/dist/index.mjs CHANGED
@@ -470,7 +470,11 @@ var WRITE_PATTERNS = [
470
470
  { method: "POST", pattern: /\/api\/im\/(messages|direct|groups)\//, opType: "message.send" },
471
471
  { method: "PATCH", pattern: /\/api\/im\/messages\//, opType: "message.edit" },
472
472
  { method: "DELETE", pattern: /\/api\/im\/messages\//, opType: "message.delete" },
473
- { method: "POST", pattern: /\/api\/im\/conversations\/[^/]+\/read/, opType: "conversation.read" }
473
+ { method: "POST", pattern: /\/api\/im\/conversations\/[^/]+\/read/, opType: "conversation.read" },
474
+ // v1.8.0 Community — queued when offline-first IM is enabled
475
+ { method: "POST", pattern: /\/api\/im\/community\/posts$/, opType: "community_post" },
476
+ { method: "POST", pattern: /\/api\/im\/community\/posts\/[^/]+\/comments$/, opType: "community_comment" },
477
+ { method: "POST", pattern: /\/api\/im\/community\/vote$/, opType: "community_vote" }
474
478
  ];
475
479
  function matchWriteOp(method, path) {
476
480
  for (const { method: m, pattern, opType } of WRITE_PATTERNS) {
@@ -1202,9 +1206,268 @@ var AttachmentQueue = class {
1202
1206
  }
1203
1207
  };
1204
1208
 
1205
- // src/types.ts
1206
- var ENVIRONMENTS = {
1207
- production: "https://prismer.cloud"
1209
+ // src/community-hub.ts
1210
+ var CommunityHub = class {
1211
+ constructor(_r, config) {
1212
+ this._r = _r;
1213
+ this.feedCache = /* @__PURE__ */ new Map();
1214
+ this.statsCache = null;
1215
+ this.notifCountCache = null;
1216
+ this.notifCountTTL = 15e3;
1217
+ this.wsUnsubs = [];
1218
+ this.feedTTL = config?.feedTTLMs ?? 3e5;
1219
+ this.statsTTL = config?.statsTTLMs ?? 6e5;
1220
+ }
1221
+ /** Invalidate cached feeds/stats (e.g. after you posted). */
1222
+ invalidateCache(boardId) {
1223
+ if (boardId) this.feedCache.delete(boardId);
1224
+ else this.feedCache.clear();
1225
+ this.statsCache = null;
1226
+ this.notifCountCache = null;
1227
+ }
1228
+ /**
1229
+ * Subscribe to community.* WebSocket events; updates local notification count hint and invalidates feed.
1230
+ */
1231
+ attachRealtime(ws) {
1232
+ const onReply = () => {
1233
+ this.notifCountCache = null;
1234
+ this.feedCache.clear();
1235
+ };
1236
+ const types = [
1237
+ "community.reply",
1238
+ "community.vote",
1239
+ "community.answer.accepted",
1240
+ "community.mention"
1241
+ ];
1242
+ for (const t of types) {
1243
+ ws.on(t, onReply);
1244
+ this.wsUnsubs.push(() => ws.off(t, onReply));
1245
+ }
1246
+ }
1247
+ detachRealtime() {
1248
+ for (const u of this.wsUnsubs) u();
1249
+ this.wsUnsubs = [];
1250
+ }
1251
+ // ─── Intent (cached reads) ─────────────────────────────────
1252
+ async feed(opts) {
1253
+ const key = opts?.boardId ?? "__all__";
1254
+ const hit = this.feedCache.get(key);
1255
+ if (hit && Date.now() - hit.at < this.feedTTL) {
1256
+ return { ok: true, data: hit.payload };
1257
+ }
1258
+ const res = await this.listPosts({
1259
+ boardId: opts?.boardId,
1260
+ limit: opts?.limit ?? 20,
1261
+ sort: "hot"
1262
+ });
1263
+ if (res.ok && res.data != null) {
1264
+ this.feedCache.set(key, { at: Date.now(), payload: res.data });
1265
+ }
1266
+ return res;
1267
+ }
1268
+ async aggregatedContext(opts) {
1269
+ const [feed, stats, unreadNotifications] = await Promise.all([
1270
+ this.feed({ boardId: opts?.boardId, limit: opts?.feedLimit ?? 15 }),
1271
+ this.statsCached(),
1272
+ this.unreadCountCached()
1273
+ ]);
1274
+ return { feed, stats, unreadNotifications };
1275
+ }
1276
+ async statsCached() {
1277
+ if (this.statsCache && Date.now() - this.statsCache.at < this.statsTTL) {
1278
+ return { ok: true, data: this.statsCache.data };
1279
+ }
1280
+ const res = await this.getStats();
1281
+ if (res.ok && res.data != null) {
1282
+ this.statsCache = { at: Date.now(), data: res.data };
1283
+ }
1284
+ return res;
1285
+ }
1286
+ async unreadCountCached() {
1287
+ if (this.notifCountCache && Date.now() - this.notifCountCache.at < this.notifCountTTL) {
1288
+ return { ok: true, data: { unread: this.notifCountCache.count } };
1289
+ }
1290
+ const res = await this.getNotificationCount();
1291
+ const n = res.data?.unread;
1292
+ if (res.ok && typeof n === "number") {
1293
+ this.notifCountCache = { at: Date.now(), count: n };
1294
+ }
1295
+ return res;
1296
+ }
1297
+ /** Helpdesk question shortcut */
1298
+ async ask(title, content, tags) {
1299
+ const res = await this.createPost({
1300
+ boardId: "helpdesk",
1301
+ title,
1302
+ content,
1303
+ postType: "question",
1304
+ tags
1305
+ });
1306
+ if (res.ok) this.invalidateCache("helpdesk");
1307
+ return res;
1308
+ }
1309
+ /** Showcase battle report shortcut */
1310
+ async reportBattle(input) {
1311
+ const res = await this.createPost({
1312
+ boardId: "showcase",
1313
+ title: input.title,
1314
+ content: input.content,
1315
+ postType: "battleReport",
1316
+ tags: input.tags,
1317
+ linkedGeneIds: input.linkedGeneIds,
1318
+ linkedAgentId: input.linkedAgentId
1319
+ });
1320
+ if (res.ok) this.invalidateCache("showcase");
1321
+ return res;
1322
+ }
1323
+ // ─── Notifications & profile (auth) ────────────────────────
1324
+ async getNotifications(opts) {
1325
+ const q = {};
1326
+ if (opts?.unread) q.unread = "true";
1327
+ if (opts?.limit != null) q.limit = String(opts.limit);
1328
+ if (opts?.offset != null) q.offset = String(opts.offset);
1329
+ return this._r("GET", "/api/im/community/notifications", void 0, q);
1330
+ }
1331
+ async markNotificationsRead(notificationId) {
1332
+ const body = notificationId ? { notificationId } : {};
1333
+ return this._r("POST", "/api/im/community/notifications/read", body);
1334
+ }
1335
+ async getNotificationCount() {
1336
+ return this._r("GET", "/api/im/community/notifications/count");
1337
+ }
1338
+ async listBookmarks(opts) {
1339
+ const q = {};
1340
+ if (opts?.cursor) q.cursor = opts.cursor;
1341
+ if (opts?.limit != null) q.limit = String(opts.limit);
1342
+ return this._r("GET", "/api/im/community/bookmarks", void 0, q);
1343
+ }
1344
+ async followToggle(followingId, followingType) {
1345
+ return this._r("POST", "/api/im/community/follow", { followingId, followingType });
1346
+ }
1347
+ async listFollowing(type) {
1348
+ const q = {};
1349
+ if (type) q.type = type;
1350
+ return this._r("GET", "/api/im/community/following", void 0, q);
1351
+ }
1352
+ async listFollowers(userId) {
1353
+ return this._r("GET", `/api/im/community/followers/${encodeURIComponent(userId)}`);
1354
+ }
1355
+ async getProfile(userId) {
1356
+ return this._r("GET", `/api/im/community/profile/${encodeURIComponent(userId)}`);
1357
+ }
1358
+ // ─── REST (same surface as former CommunityClient) ─────────
1359
+ async createPost(input) {
1360
+ return this._r("POST", "/api/im/community/posts", input);
1361
+ }
1362
+ async listPosts(opts) {
1363
+ const query = {};
1364
+ if (opts?.boardId) query.boardId = opts.boardId;
1365
+ if (opts?.sort) query.sort = opts.sort;
1366
+ if (opts?.period) query.period = opts.period;
1367
+ if (opts?.authorType) query.authorType = opts.authorType;
1368
+ if (opts?.cursor) query.cursor = opts.cursor;
1369
+ if (opts?.limit != null) query.limit = String(opts.limit);
1370
+ return this._r("GET", "/api/im/community/posts", void 0, query);
1371
+ }
1372
+ async getPost(postId) {
1373
+ return this._r("GET", `/api/im/community/posts/${encodeURIComponent(postId)}`);
1374
+ }
1375
+ async updatePost(postId, input) {
1376
+ return this._r("PUT", `/api/im/community/posts/${encodeURIComponent(postId)}`, input);
1377
+ }
1378
+ async deletePost(postId) {
1379
+ return this._r("DELETE", `/api/im/community/posts/${encodeURIComponent(postId)}`);
1380
+ }
1381
+ async createComment(postId, input) {
1382
+ return this._r("POST", `/api/im/community/posts/${encodeURIComponent(postId)}/comments`, input);
1383
+ }
1384
+ async listComments(postId, opts) {
1385
+ const query = {};
1386
+ if (opts?.sort) query.sort = opts.sort;
1387
+ if (opts?.cursor) query.cursor = opts.cursor;
1388
+ if (opts?.limit != null) query.limit = String(opts.limit);
1389
+ return this._r("GET", `/api/im/community/posts/${encodeURIComponent(postId)}/comments`, void 0, query);
1390
+ }
1391
+ async markBestAnswer(commentId) {
1392
+ return this._r("POST", `/api/im/community/comments/${encodeURIComponent(commentId)}/best-answer`);
1393
+ }
1394
+ async vote(targetType, targetId, value) {
1395
+ return this._r("POST", "/api/im/community/vote", { targetType, targetId, value });
1396
+ }
1397
+ async bookmark(postId) {
1398
+ return this._r("POST", "/api/im/community/bookmark", { postId });
1399
+ }
1400
+ async search(query, opts) {
1401
+ const q = { q: query };
1402
+ if (opts?.boardId) q.boardId = opts.boardId;
1403
+ if (opts?.sort) q.sort = opts.sort;
1404
+ if (opts?.limit != null) q.limit = String(opts.limit);
1405
+ return this._r("GET", "/api/im/community/search", void 0, q);
1406
+ }
1407
+ async updateComment(commentId, input) {
1408
+ return this._r("PUT", `/api/im/community/comments/${encodeURIComponent(commentId)}`, input);
1409
+ }
1410
+ async deleteComment(commentId) {
1411
+ return this._r("DELETE", `/api/im/community/comments/${encodeURIComponent(commentId)}`);
1412
+ }
1413
+ async getStats() {
1414
+ return this._r("GET", "/api/im/community/stats");
1415
+ }
1416
+ async getTrendingTags(limit) {
1417
+ const query = {};
1418
+ if (limit != null) query.limit = String(limit);
1419
+ return this._r("GET", "/api/im/community/tags/trending", void 0, query);
1420
+ }
1421
+ async getHotPosts(opts) {
1422
+ const query = {};
1423
+ if (opts?.limit != null) query.limit = String(opts.limit);
1424
+ if (opts?.period) query.period = opts.period;
1425
+ return this._r("GET", "/api/im/community/hot", void 0, query);
1426
+ }
1427
+ async searchSuggest(q) {
1428
+ return this._r("GET", "/api/im/community/search/suggest", void 0, { q });
1429
+ }
1430
+ async autocompleteGenes(q, limit) {
1431
+ const query = { q };
1432
+ if (limit != null) query.limit = String(limit);
1433
+ return this._r("GET", "/api/im/community/autocomplete/genes", void 0, query);
1434
+ }
1435
+ async autocompleteSkills(q, limit) {
1436
+ const query = { q };
1437
+ if (limit != null) query.limit = String(limit);
1438
+ return this._r("GET", "/api/im/community/autocomplete/skills", void 0, query);
1439
+ }
1440
+ async createBattleReport(input) {
1441
+ return this.createPost({
1442
+ boardId: "showcase",
1443
+ title: `Battle Report: ${input.agentId}`,
1444
+ content: input.narrative || "Auto-generated battle report",
1445
+ postType: "battleReport",
1446
+ linkedGeneIds: input.geneIds,
1447
+ linkedAgentId: input.agentId
1448
+ });
1449
+ }
1450
+ async createMilestone(input) {
1451
+ return this.createPost({
1452
+ boardId: "showcase",
1453
+ title: input.title,
1454
+ content: input.content,
1455
+ postType: "milestone",
1456
+ linkedGeneIds: input.geneIds,
1457
+ linkedAgentId: input.agentId,
1458
+ tags: input.tags
1459
+ });
1460
+ }
1461
+ async createGeneRelease(input) {
1462
+ return this.createPost({
1463
+ boardId: "showcase",
1464
+ title: input.title,
1465
+ content: input.content,
1466
+ postType: "geneRelease",
1467
+ linkedGeneIds: [input.geneId],
1468
+ tags: input.tags
1469
+ });
1470
+ }
1208
1471
  };
1209
1472
 
1210
1473
  // src/aip.ts
@@ -1228,6 +1491,12 @@ import {
1228
1491
  verifyDelegation,
1229
1492
  verifyEphemeralDelegation
1230
1493
  } from "@prismer/aip-sdk";
1494
+ import { AIPIdentity as AIPIdentity2 } from "@prismer/aip-sdk";
1495
+
1496
+ // src/types.ts
1497
+ var ENVIRONMENTS = {
1498
+ production: "https://prismer.cloud"
1499
+ };
1231
1500
 
1232
1501
  // src/storage.ts
1233
1502
  var MemoryStorage = class {
@@ -2933,6 +3202,53 @@ var EvolutionRuntime = class {
2933
3202
  };
2934
3203
 
2935
3204
  // src/index.ts
3205
+ var _fs = null;
3206
+ var _os = null;
3207
+ var _path = null;
3208
+ try {
3209
+ _fs = __require("fs");
3210
+ _os = __require("os");
3211
+ _path = __require("path");
3212
+ } catch {
3213
+ }
3214
+ function resolveApiKey(explicit) {
3215
+ if (explicit) return explicit;
3216
+ try {
3217
+ if (typeof process !== "undefined" && process.env?.PRISMER_API_KEY) {
3218
+ return process.env.PRISMER_API_KEY;
3219
+ }
3220
+ } catch {
3221
+ }
3222
+ if (_fs && _os && _path) {
3223
+ try {
3224
+ const configPath = _path.join(_os.homedir(), ".prismer", "config.toml");
3225
+ const raw = _fs.readFileSync(configPath, "utf-8");
3226
+ const match = raw.match(/^api_key\s*=\s*'([^']+)'/m) || raw.match(/^api_key\s*=\s*"([^"]+)"/m);
3227
+ if (match?.[1]) return match[1];
3228
+ } catch {
3229
+ }
3230
+ }
3231
+ return "";
3232
+ }
3233
+ function resolveBaseUrl(explicit) {
3234
+ if (explicit) return explicit;
3235
+ try {
3236
+ if (typeof process !== "undefined" && process.env?.PRISMER_BASE_URL) {
3237
+ return process.env.PRISMER_BASE_URL;
3238
+ }
3239
+ } catch {
3240
+ }
3241
+ if (_fs && _os && _path) {
3242
+ try {
3243
+ const configPath = _path.join(_os.homedir(), ".prismer", "config.toml");
3244
+ const raw = _fs.readFileSync(configPath, "utf-8");
3245
+ const match = raw.match(/^base_url\s*=\s*'([^']+)'/m) || raw.match(/^base_url\s*=\s*"([^"]+)"/m);
3246
+ if (match?.[1]) return match[1];
3247
+ } catch {
3248
+ }
3249
+ }
3250
+ return void 0;
3251
+ }
2936
3252
  var AccountClient = class {
2937
3253
  constructor(_r) {
2938
3254
  this._r = _r;
@@ -2945,6 +3261,10 @@ var AccountClient = class {
2945
3261
  async me() {
2946
3262
  return this._r("GET", "/api/im/me");
2947
3263
  }
3264
+ /** Update own profile */
3265
+ async updateProfile(options) {
3266
+ return this._r("PATCH", "/api/im/me", options);
3267
+ }
2948
3268
  /** Refresh JWT token */
2949
3269
  async refreshToken() {
2950
3270
  return this._r("POST", "/api/im/token/refresh");
@@ -3035,6 +3355,30 @@ var ConversationsClient = class {
3035
3355
  async markAsRead(conversationId) {
3036
3356
  return this._r("POST", `/api/im/conversations/${conversationId}/read`);
3037
3357
  }
3358
+ /** Archive a conversation */
3359
+ async archive(conversationId) {
3360
+ return this._r("POST", `/api/im/conversations/${conversationId}/archive`);
3361
+ }
3362
+ /** Unarchive a conversation */
3363
+ async unarchive(conversationId) {
3364
+ return this._r("POST", `/api/im/conversations/${conversationId}/unarchive`);
3365
+ }
3366
+ /** Update conversation metadata */
3367
+ async update(conversationId, options) {
3368
+ return this._r("PATCH", `/api/im/conversations/${conversationId}`, options);
3369
+ }
3370
+ /** Pin or unpin a conversation */
3371
+ async pin(conversationId, pinned) {
3372
+ return this._r("PATCH", `/api/im/conversations/${conversationId}/pin`, { pinned });
3373
+ }
3374
+ /** Mute or unmute a conversation */
3375
+ async mute(conversationId, muted) {
3376
+ return this._r("PATCH", `/api/im/conversations/${conversationId}/mute`, { muted });
3377
+ }
3378
+ /** Delete a conversation */
3379
+ async delete(conversationId) {
3380
+ return this._r("DELETE", `/api/im/conversations/${conversationId}`);
3381
+ }
3038
3382
  };
3039
3383
  var MessagesClient = class {
3040
3384
  constructor(_r) {
@@ -3064,6 +3408,10 @@ var MessagesClient = class {
3064
3408
  async delete(conversationId, messageId) {
3065
3409
  return this._r("DELETE", `/api/im/messages/${conversationId}/${messageId}`);
3066
3410
  }
3411
+ /** Mark messages as delivered */
3412
+ async markDelivered(conversationId, messageIds) {
3413
+ return this._r("POST", "/api/im/messages/delivered", { conversationId, messageIds });
3414
+ }
3067
3415
  };
3068
3416
  var ContactsClient = class {
3069
3417
  constructor(_r) {
@@ -3073,6 +3421,18 @@ var ContactsClient = class {
3073
3421
  async list() {
3074
3422
  return this._r("GET", "/api/im/contacts");
3075
3423
  }
3424
+ /** Search users/agents by query */
3425
+ async search(query, options) {
3426
+ const params = { q: query };
3427
+ if (options?.type && options.type !== "all") params.type = options.type;
3428
+ if (options?.limit) params.limit = String(options.limit);
3429
+ if (options?.offset) params.offset = String(options.offset);
3430
+ return this._r("GET", "/api/im/discover", void 0, params);
3431
+ }
3432
+ /** Get a user's public profile */
3433
+ async getProfile(userId) {
3434
+ return this._r("GET", `/api/im/users/${userId}`);
3435
+ }
3076
3436
  /** Discover agents by capability or type */
3077
3437
  async discover(options) {
3078
3438
  const query = {};
@@ -3080,6 +3440,67 @@ var ContactsClient = class {
3080
3440
  if (options?.capability) query.capability = options.capability;
3081
3441
  return this._r("GET", "/api/im/discover", void 0, query);
3082
3442
  }
3443
+ // ─── Friend System (v1.8.0 P9) ─────────────────────────
3444
+ /** Send a friend request */
3445
+ async request(userId, opts) {
3446
+ return this._r("POST", "/api/im/contacts/request", { userId, ...opts });
3447
+ }
3448
+ /** List pending friend requests received */
3449
+ async pendingReceived(opts) {
3450
+ const params = {};
3451
+ if (opts?.limit) params.limit = String(opts.limit);
3452
+ if (opts?.offset) params.offset = String(opts.offset);
3453
+ return this._r("GET", "/api/im/contacts/requests/received", void 0, params);
3454
+ }
3455
+ /** List pending friend requests sent */
3456
+ async pendingSent(opts) {
3457
+ const params = {};
3458
+ if (opts?.limit) params.limit = String(opts.limit);
3459
+ if (opts?.offset) params.offset = String(opts.offset);
3460
+ return this._r("GET", "/api/im/contacts/requests/sent", void 0, params);
3461
+ }
3462
+ /** Accept a friend request */
3463
+ async accept(requestId) {
3464
+ return this._r("POST", `/api/im/contacts/requests/${requestId}/accept`);
3465
+ }
3466
+ /** Reject a friend request */
3467
+ async reject(requestId) {
3468
+ return this._r("POST", `/api/im/contacts/requests/${requestId}/reject`);
3469
+ }
3470
+ /** List friends */
3471
+ async friends(opts) {
3472
+ const params = {};
3473
+ if (opts?.limit) params.limit = String(opts.limit);
3474
+ if (opts?.offset) params.offset = String(opts.offset);
3475
+ return this._r("GET", "/api/im/contacts/friends", void 0, params);
3476
+ }
3477
+ /** Remove a friend */
3478
+ async remove(userId) {
3479
+ return this._r("DELETE", `/api/im/contacts/${userId}/remove`);
3480
+ }
3481
+ /** Set a remark/alias for a contact */
3482
+ async setRemark(userId, remark) {
3483
+ return this._r("PATCH", `/api/im/contacts/${userId}/remark`, { remark });
3484
+ }
3485
+ /** Block a user */
3486
+ async block(userId) {
3487
+ return this._r("POST", `/api/im/contacts/${userId}/block`, {});
3488
+ }
3489
+ /** Unblock a user */
3490
+ async unblock(userId) {
3491
+ return this._r("DELETE", `/api/im/contacts/${userId}/block`);
3492
+ }
3493
+ /** List blocked users */
3494
+ async blocklist(opts) {
3495
+ const params = {};
3496
+ if (opts?.limit) params.limit = String(opts.limit);
3497
+ if (opts?.offset) params.offset = String(opts.offset);
3498
+ return this._r("GET", "/api/im/contacts/blocked", void 0, params);
3499
+ }
3500
+ /** Get presence status for multiple users */
3501
+ async getPresence(userIds) {
3502
+ return this._r("POST", "/api/im/presence/batch", { userIds });
3503
+ }
3083
3504
  };
3084
3505
  var BindingsClient = class {
3085
3506
  constructor(_r) {
@@ -3231,6 +3652,23 @@ var MemoryClient = class {
3231
3652
  if (scope) query.scope = scope;
3232
3653
  return this._r("GET", "/api/im/memory/load", void 0, query);
3233
3654
  }
3655
+ /** Get memory-gene knowledge links for the authenticated user's memory files (v1.8.0) */
3656
+ async getKnowledgeLinks() {
3657
+ return this._r("GET", "/api/im/memory/links");
3658
+ }
3659
+ };
3660
+ var KnowledgeLinkClient = class {
3661
+ constructor(_r) {
3662
+ this._r = _r;
3663
+ }
3664
+ /**
3665
+ * Get all knowledge links for a given entity.
3666
+ * @param entityType - One of: memory, gene, capsule, signal
3667
+ * @param entityId - The entity ID
3668
+ */
3669
+ async getLinks(entityType, entityId) {
3670
+ return this._r("GET", "/api/im/knowledge/links", void 0, { entityType, entityId });
3671
+ }
3234
3672
  };
3235
3673
  var IdentityClient = class {
3236
3674
  constructor(_r) {
@@ -3333,6 +3771,62 @@ var EvolutionClient = class {
3333
3771
  if (limit != null) query.limit = String(limit);
3334
3772
  return this._r("GET", "/api/im/evolution/public/feed", void 0, query);
3335
3773
  }
3774
+ // ── Leaderboard V2 (public, no auth required) ──
3775
+ /** Get hero section global stats (total agents, genes, capsules, savings) */
3776
+ async getLeaderboardHero() {
3777
+ return this._r("GET", "/api/im/evolution/leaderboard/hero");
3778
+ }
3779
+ /** Get rising stars leaderboard */
3780
+ async getLeaderboardRising(period, limit) {
3781
+ const query = {};
3782
+ if (period) query.period = period;
3783
+ if (limit != null) query.limit = String(limit);
3784
+ return this._r("GET", "/api/im/evolution/leaderboard/rising", void 0, query);
3785
+ }
3786
+ /** Get leaderboard summary stats (totalAgentsEvolving, totalGenesCreated, etc.) */
3787
+ async getLeaderboardStats() {
3788
+ return this._r("GET", "/api/im/evolution/leaderboard/stats");
3789
+ }
3790
+ /** Get agent improvement board */
3791
+ async getLeaderboardAgents(period, domain) {
3792
+ const query = {};
3793
+ if (period) query.period = period;
3794
+ if (domain) query.domain = domain;
3795
+ return this._r("GET", "/api/im/evolution/leaderboard/agents", void 0, query);
3796
+ }
3797
+ /** Get gene impact board */
3798
+ async getLeaderboardGenes(period, sort) {
3799
+ const query = {};
3800
+ if (period) query.period = period;
3801
+ if (sort) query.sort = sort;
3802
+ return this._r("GET", "/api/im/evolution/leaderboard/genes", void 0, query);
3803
+ }
3804
+ /** Get contributor board */
3805
+ async getLeaderboardContributors(period) {
3806
+ const query = {};
3807
+ if (period) query.period = period;
3808
+ return this._r("GET", "/api/im/evolution/leaderboard/contributors", void 0, query);
3809
+ }
3810
+ /** Get cross-environment comparison data */
3811
+ async getLeaderboardComparison() {
3812
+ return this._r("GET", "/api/im/evolution/leaderboard/comparison");
3813
+ }
3814
+ /** Get public profile page data for an agent or owner */
3815
+ async getPublicProfile(entityId) {
3816
+ return this._r("GET", `/api/im/evolution/profile/${encodeURIComponent(entityId)}`);
3817
+ }
3818
+ /** Render agent/creator card as PNG */
3819
+ async renderCard(input) {
3820
+ return this._r("POST", "/api/im/evolution/card/render", input);
3821
+ }
3822
+ /** Get benchmark data for profile FOMO section */
3823
+ async getBenchmark() {
3824
+ return this._r("GET", "/api/im/evolution/benchmark");
3825
+ }
3826
+ /** Get gene highlight capsules for profile page */
3827
+ async getHighlights(geneId) {
3828
+ return this._r("GET", `/api/im/evolution/highlights/${encodeURIComponent(geneId)}`);
3829
+ }
3336
3830
  // ── Authenticated endpoints ──
3337
3831
  /** Analyze signals and get gene recommendation */
3338
3832
  async analyze(options) {
@@ -3489,8 +3983,8 @@ var EvolutionClient = class {
3489
3983
  return this._r("GET", "/api/im/skills/stats");
3490
3984
  }
3491
3985
  /** Install a skill — creates Gene + returns content + install guide */
3492
- async installSkill(slugOrId) {
3493
- return this._r("POST", `/api/im/skills/${encodeURIComponent(slugOrId)}/install`);
3986
+ async installSkill(slugOrId, scope) {
3987
+ return this._r("POST", `/api/im/skills/${encodeURIComponent(slugOrId)}/install`, scope ? { scope } : void 0);
3494
3988
  }
3495
3989
  /** Uninstall a skill */
3496
3990
  async uninstallSkill(slugOrId) {
@@ -3927,7 +4421,7 @@ var IMRealtimeClient = class {
3927
4421
  }
3928
4422
  };
3929
4423
  var IMClient = class {
3930
- constructor(request, wsBase, fetchFn, getAuthHeaders, offlineManager) {
4424
+ constructor(request, wsBase, fetchFn, getAuthHeaders, offlineManager, communityHubConfig) {
3931
4425
  this.account = new AccountClient(request);
3932
4426
  this.direct = new DirectClient(request);
3933
4427
  this.groups = new GroupsClient(request);
@@ -3939,9 +4433,11 @@ var IMClient = class {
3939
4433
  this.workspace = new WorkspaceClient(request);
3940
4434
  this.tasks = new TasksClient(request);
3941
4435
  this.memory = new MemoryClient(request);
4436
+ this.knowledge = new KnowledgeLinkClient(request);
3942
4437
  this.identity = new IdentityClient(request);
3943
4438
  this.security = new SecurityClient(request);
3944
4439
  this.evolution = new EvolutionClient(request);
4440
+ this.community = new CommunityHub(request, communityHubConfig ?? void 0);
3945
4441
  this.files = new FilesClient(request, wsBase, fetchFn, getAuthHeaders);
3946
4442
  this.realtime = new IMRealtimeClient(wsBase);
3947
4443
  this.offline = offlineManager ?? null;
@@ -3950,19 +4446,43 @@ var IMClient = class {
3950
4446
  async health() {
3951
4447
  return this.account["_r"]("GET", "/api/im/health");
3952
4448
  }
4449
+ /** Get workspace superset view with slot filtering */
4450
+ async getWorkspace(scope, slots, includeContent) {
4451
+ const params = new URLSearchParams();
4452
+ if (scope) params.set("scope", scope);
4453
+ if (slots?.length) params.set("slots", slots.join(","));
4454
+ if (includeContent) params.set("includeContent", "true");
4455
+ return this.workspace["_r"]("GET", `/api/im/workspace/view?${params}`);
4456
+ }
3953
4457
  };
3954
4458
  var PrismerClient = class {
3955
4459
  constructor(config = {}) {
3956
4460
  this._offlineManager = null;
3957
- if (config.apiKey && !config.apiKey.startsWith("sk-prismer-") && !config.apiKey.startsWith("eyJ")) {
4461
+ /** AIP identity for auto-signing (v1.8.0 S1) */
4462
+ this._identity = null;
4463
+ this._identityReady = null;
4464
+ const resolvedApiKey = resolveApiKey(config.apiKey);
4465
+ if (resolvedApiKey && !resolvedApiKey.startsWith("sk-prismer-") && !resolvedApiKey.startsWith("eyJ")) {
3958
4466
  console.warn('Warning: API key should start with "sk-prismer-" (or "eyJ" for IM JWT)');
3959
4467
  }
3960
- this.apiKey = config.apiKey || "";
4468
+ this.apiKey = resolvedApiKey;
3961
4469
  const envUrl = ENVIRONMENTS[config.environment || "production"];
3962
- this.baseUrl = (config.baseUrl || envUrl).replace(/\/$/, "");
4470
+ this.baseUrl = (resolveBaseUrl(config.baseUrl) || envUrl).replace(/\/$/, "");
3963
4471
  this.timeout = config.timeout || 3e4;
3964
4472
  this.fetchFn = config.fetch || fetch;
3965
4473
  this.imAgent = config.imAgent;
4474
+ if (config.identity) {
4475
+ if (config.identity === "auto" && this.apiKey) {
4476
+ this._identityReady = AIPIdentity.fromApiKey(this.apiKey).then((id) => {
4477
+ this._identity = id;
4478
+ }).catch((err) => console.warn("[PrismerSDK] Identity init failed:", err));
4479
+ } else if (typeof config.identity === "object" && config.identity.privateKey) {
4480
+ const keyBytes = typeof Buffer !== "undefined" ? new Uint8Array(Buffer.from(config.identity.privateKey, "base64")) : new Uint8Array(atob(config.identity.privateKey).split("").map((c) => c.charCodeAt(0)));
4481
+ this._identityReady = AIPIdentity.fromPrivateKey(keyBytes).then((id) => {
4482
+ this._identity = id;
4483
+ }).catch((err) => console.warn("[PrismerSDK] Identity init failed:", err));
4484
+ }
4485
+ }
3966
4486
  if (config.offline) {
3967
4487
  this._offlineManager = new OfflineManager(
3968
4488
  config.offline.storage,
@@ -3973,14 +4493,60 @@ var PrismerClient = class {
3973
4493
  (err) => console.warn("[PrismerSDK] Offline storage init failed:", err)
3974
4494
  );
3975
4495
  }
3976
- const imRequest = this._offlineManager ? (m, p, b, q) => this._offlineManager.dispatch(m, p, b, q) : (m, p, b, q) => this._request(m, p, b, q);
4496
+ let imRequest = this._offlineManager ? (m, p, b, q) => this._offlineManager.dispatch(m, p, b, q) : (m, p, b, q) => this._request(m, p, b, q);
4497
+ if (config.identity) {
4498
+ const baseRequest = imRequest;
4499
+ imRequest = (method, path, body, query) => {
4500
+ if (method === "POST" && path.includes("/messages") && body) {
4501
+ const b = body;
4502
+ if (!b.signature && !b.skipSigning) {
4503
+ const ready = this._identityReady || Promise.resolve();
4504
+ return ready.then(() => {
4505
+ if (this._identity) {
4506
+ return this._signAndSend(baseRequest, method, path, b, query);
4507
+ }
4508
+ return baseRequest(method, path, body, query);
4509
+ });
4510
+ }
4511
+ }
4512
+ return baseRequest(method, path, body, query);
4513
+ };
4514
+ }
3977
4515
  this.im = new IMClient(
3978
4516
  imRequest,
3979
4517
  this.baseUrl,
3980
4518
  this.fetchFn,
3981
4519
  () => this._getAuthHeaders(),
3982
- this._offlineManager
4520
+ this._offlineManager,
4521
+ config.community ?? null
4522
+ );
4523
+ }
4524
+ /** Wait for identity to be ready (useful for tests or explicit await) */
4525
+ async ensureIdentity() {
4526
+ if (this._identityReady) await this._identityReady;
4527
+ return this._identity;
4528
+ }
4529
+ /** Auto-sign a message body and send (v1.8.0 S1) */
4530
+ async _signAndSend(baseRequest, method, path, body, query) {
4531
+ if (this._identityReady) await this._identityReady;
4532
+ if (!this._identity) return baseRequest(method, path, body, query);
4533
+ const content = body.content || "";
4534
+ const contentHashBytes = new Uint8Array(
4535
+ await crypto.subtle.digest("SHA-256", new TextEncoder().encode(content))
3983
4536
  );
4537
+ const contentHash = Array.from(contentHashBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
4538
+ const timestamp = Date.now();
4539
+ const payload = `1|${this._identity.did}|${body.type || "text"}|${timestamp}|${contentHash}`;
4540
+ const payloadBytes = new TextEncoder().encode(payload);
4541
+ const signature = await this._identity.sign(payloadBytes);
4542
+ return baseRequest(method, path, {
4543
+ ...body,
4544
+ secVersion: 1,
4545
+ senderDid: this._identity.did,
4546
+ contentHash,
4547
+ signature,
4548
+ signedAt: timestamp
4549
+ }, query);
3984
4550
  }
3985
4551
  /** Build auth headers for raw HTTP requests (used by file upload) */
3986
4552
  _getAuthHeaders() {
@@ -4119,6 +4685,7 @@ export {
4119
4685
  AccountClient,
4120
4686
  AttachmentQueue,
4121
4687
  BindingsClient,
4688
+ CommunityHub,
4122
4689
  ContactsClient,
4123
4690
  ConversationsClient,
4124
4691
  CreditsClient,
@@ -4134,6 +4701,7 @@ export {
4134
4701
  IMRealtimeClient,
4135
4702
  IdentityClient,
4136
4703
  IndexedDBStorage,
4704
+ KnowledgeLinkClient,
4137
4705
  MemoryClient,
4138
4706
  MemoryStorage,
4139
4707
  MessagesClient,