@xfxstudio/claworld 0.2.12 → 0.2.14

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 (62) hide show
  1. package/README.md +45 -19
  2. package/index.js +0 -1
  3. package/openclaw.plugin.json +1 -1
  4. package/package.json +1 -5
  5. package/skills/claworld-help/SKILL.md +84 -91
  6. package/skills/claworld-join-and-chat/SKILL.md +9 -9
  7. package/src/openclaw/index.js +0 -3
  8. package/src/openclaw/plugin/account-identity.js +0 -1
  9. package/src/openclaw/plugin/claworld-channel-plugin.js +8 -253
  10. package/src/openclaw/plugin/managed-config.js +1 -7
  11. package/src/openclaw/plugin/onboarding.js +128 -103
  12. package/src/openclaw/plugin/register.js +183 -232
  13. package/src/openclaw/plugin/relay-client.js +8 -5
  14. package/src/openclaw/runtime/product-shell-helper.js +11 -364
  15. package/src/openclaw/runtime/tool-contracts.js +0 -182
  16. package/src/openclaw/runtime/tool-inventory.js +4 -27
  17. package/bin/claworld.mjs +0 -9
  18. package/src/lib/agent-profile.js +0 -74
  19. package/src/lib/http-auth.js +0 -151
  20. package/src/lib/policy.js +0 -114
  21. package/src/openclaw/installer/cli.js +0 -406
  22. package/src/openclaw/installer/constants.js +0 -14
  23. package/src/openclaw/installer/core.js +0 -2122
  24. package/src/openclaw/installer/doctor.js +0 -876
  25. package/src/openclaw/installer/workspace-contract.js +0 -427
  26. package/src/product-shell/agent-cards/card-routes.js +0 -64
  27. package/src/product-shell/agent-cards/card-service.js +0 -287
  28. package/src/product-shell/agent-cards/spec-builder.js +0 -167
  29. package/src/product-shell/agent-cards/storage/image-host-storage.js +0 -192
  30. package/src/product-shell/agent-cards/storage/local-public-storage.js +0 -74
  31. package/src/product-shell/agent-cards/svg-renderer.js +0 -325
  32. package/src/product-shell/agent-cards/template-registry.js +0 -131
  33. package/src/product-shell/catalog/default-world-catalog.js +0 -38
  34. package/src/product-shell/contracts/candidate-feed.js +0 -393
  35. package/src/product-shell/contracts/world-manifest.js +0 -369
  36. package/src/product-shell/conversation-feedback/conversation-feedback-service.js +0 -261
  37. package/src/product-shell/feedback/feedback-contract.js +0 -13
  38. package/src/product-shell/feedback/feedback-routes.js +0 -98
  39. package/src/product-shell/feedback/feedback-service.js +0 -252
  40. package/src/product-shell/index.js +0 -212
  41. package/src/product-shell/matching/matchmaking-service.js +0 -395
  42. package/src/product-shell/membership/membership-service.js +0 -284
  43. package/src/product-shell/onboarding/onboarding-routes.js +0 -37
  44. package/src/product-shell/onboarding/onboarding-service.js +0 -220
  45. package/src/product-shell/orchestration/world-conversation-orchestrator.js +0 -28
  46. package/src/product-shell/profile/profile-service.js +0 -142
  47. package/src/product-shell/profile/public-identity-routes.js +0 -160
  48. package/src/product-shell/profile/public-identity-service.js +0 -192
  49. package/src/product-shell/search/search-service.js +0 -393
  50. package/src/product-shell/social/chat-request-approval-policy.js +0 -332
  51. package/src/product-shell/social/chat-request-routes.js +0 -130
  52. package/src/product-shell/social/chat-request-service.js +0 -723
  53. package/src/product-shell/social/friend-routes.js +0 -82
  54. package/src/product-shell/social/friend-service.js +0 -557
  55. package/src/product-shell/social/social-routes.js +0 -21
  56. package/src/product-shell/social/social-service.js +0 -136
  57. package/src/product-shell/worlds/world-admin-service.js +0 -486
  58. package/src/product-shell/worlds/world-authorization.js +0 -136
  59. package/src/product-shell/worlds/world-broadcast-service.js +0 -296
  60. package/src/product-shell/worlds/world-routes.js +0 -403
  61. package/src/product-shell/worlds/world-service.js +0 -89
  62. package/src/product-shell/worlds/world-text.js +0 -75
@@ -348,18 +348,47 @@ function projectToolManageWorldActionResponse(payload = {}, { accountId = null,
348
348
  };
349
349
  }
350
350
 
351
- const PROFILE_ACTIONS = Object.freeze([
351
+ const CHAT_INBOX_ACTIONS = Object.freeze([
352
+ 'list',
353
+ 'accept',
354
+ 'reject',
355
+ ]);
356
+
357
+ function normalizeChatInboxAction(value, fallback = null) {
358
+ const normalized = normalizeText(value, fallback);
359
+ return CHAT_INBOX_ACTIONS.includes(normalized) ? normalized : fallback;
360
+ }
361
+
362
+ function inferChatInboxAction(params = {}) {
363
+ return normalizeChatInboxAction(params.action, 'list');
364
+ }
365
+
366
+ function projectToolChatInboxActionResponse(payload = {}, { accountId = null, action = 'list' } = {}) {
367
+ const resolvedAction = normalizeChatInboxAction(action, 'list');
368
+ if (resolvedAction === 'list') {
369
+ return {
370
+ action: resolvedAction,
371
+ ...projectToolChatInboxResponse(payload, { accountId }),
372
+ };
373
+ }
374
+ return {
375
+ action: resolvedAction,
376
+ ...projectToolChatRequestMutationResponse(payload, { accountId }),
377
+ };
378
+ }
379
+
380
+ const ACCOUNT_ACTIONS = Object.freeze([
352
381
  'view',
353
382
  'update_identity',
354
383
  ]);
355
384
 
356
- function normalizeProfileAction(value, fallback = null) {
385
+ function normalizeAccountAction(value, fallback = null) {
357
386
  const normalized = normalizeText(value, fallback);
358
- return PROFILE_ACTIONS.includes(normalized) ? normalized : fallback;
387
+ return ACCOUNT_ACTIONS.includes(normalized) ? normalized : fallback;
359
388
  }
360
389
 
361
- function inferProfileAction(params = {}) {
362
- const explicitAction = normalizeProfileAction(params.action, null);
390
+ function inferAccountAction(params = {}) {
391
+ const explicitAction = normalizeAccountAction(params.action, null);
363
392
  if (explicitAction) return explicitAction;
364
393
  if (normalizeText(params.displayName, null)) return 'update_identity';
365
394
  return 'view';
@@ -420,34 +449,89 @@ function projectToolShareCard(payload = null) {
420
449
  };
421
450
  }
422
451
 
423
- function projectToolProfileResponse({
424
- action = 'view',
452
+ function projectToolAccountIdentityFields(identityPayload = null) {
453
+ const projectedIdentity = projectToolPublicIdentity(identityPayload);
454
+ if (projectedIdentity) {
455
+ return {
456
+ publicIdentity: projectedIdentity.publicIdentity,
457
+ recommendedDisplayName: projectedIdentity.recommendedDisplayName,
458
+ requiredAction: projectedIdentity.requiredAction,
459
+ nextAction: projectedIdentity.nextAction,
460
+ nextTool: projectedIdentity.nextTool,
461
+ missingFields: projectedIdentity.missingFields,
462
+ feedbackSummary: projectedIdentity.feedbackSummary,
463
+ };
464
+ }
465
+ return {
466
+ publicIdentity: null,
467
+ recommendedDisplayName: null,
468
+ requiredAction: null,
469
+ nextAction: null,
470
+ nextTool: null,
471
+ missingFields: [],
472
+ feedbackSummary: null,
473
+ };
474
+ }
475
+
476
+ function projectToolAccountViewResponse({
477
+ accountId = null,
478
+ pairingPayload = null,
479
+ identityPayload = null,
480
+ } = {}) {
481
+ const identityReady = identityPayload?.ready === true;
482
+ const ready = pairingPayload?.status === 'paired' && identityReady;
483
+ const resolvedShareCard = identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
484
+ ? projectToolShareCard(identityPayload.shareCard)
485
+ : undefined;
486
+ return {
487
+ action: 'view',
488
+ status: ready ? 'ready' : 'pending',
489
+ ready,
490
+ readiness: pairingPayload?.status === 'paired'
491
+ ? (identityReady ? 'paired_and_ready' : 'paired_but_identity_pending')
492
+ : 'installed_unactivated',
493
+ accountId: normalizeText(pairingPayload?.runtimeConfig?.accountId, normalizeText(accountId, null)),
494
+ reason: normalizeText(pairingPayload?.reason, null),
495
+ bindingSource: normalizeText(pairingPayload?.bindingSource, null),
496
+ activation: {
497
+ status: pairingPayload?.status === 'paired' ? 'ready' : 'pending',
498
+ },
499
+ relay: {
500
+ agentId: normalizeText(
501
+ pairingPayload?.runtimeConfig?.relay?.agentId,
502
+ normalizeText(pairingPayload?.relayAgent?.agentId, null),
503
+ ),
504
+ displayName: normalizeText(pairingPayload?.relayAgent?.displayName, null),
505
+ discoverable: pairingPayload?.relayAgent?.discoverable ?? null,
506
+ contactable: pairingPayload?.relayAgent?.contactable ?? null,
507
+ online: pairingPayload?.relayAgent?.online ?? null,
508
+ resolved: pairingPayload?.relayAgent?.resolved ?? null,
509
+ bindingStatus: pairingPayload?.status === 'paired' ? 'bound' : 'unactivated',
510
+ },
511
+ ...projectToolAccountIdentityFields(identityPayload),
512
+ ...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
513
+ };
514
+ }
515
+
516
+ function projectToolAccountMutationResponse({
517
+ action = 'update_identity',
425
518
  accountId = null,
426
519
  identityPayload = null,
427
520
  shareCard = undefined,
428
521
  runtimeActivation = null,
429
522
  } = {}) {
430
- const projectedIdentity = projectToolPublicIdentity(identityPayload);
431
523
  const resolvedShareCard = shareCard !== undefined
432
524
  ? shareCard
433
525
  : (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
434
526
  ? projectToolShareCard(identityPayload.shareCard)
435
527
  : undefined);
436
- const ready = projectedIdentity?.ready === true;
528
+ const ready = identityPayload?.ready === true;
437
529
  return {
438
530
  action,
439
531
  status: ready ? 'ready' : 'pending',
440
532
  ready,
441
533
  accountId: normalizeText(accountId, null),
442
- ...(projectedIdentity || {
443
- publicIdentity: null,
444
- recommendedDisplayName: null,
445
- requiredAction: null,
446
- nextAction: null,
447
- nextTool: null,
448
- missingFields: [],
449
- feedbackSummary: null,
450
- }),
534
+ ...projectToolAccountIdentityFields(identityPayload),
451
535
  ...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
452
536
  ...(runtimeActivation ? { runtimeActivation } : {}),
453
537
  ...(action === 'update_identity'
@@ -485,7 +569,7 @@ function buildRegisteredTools(api, plugin) {
485
569
  metadata: buildToolMetadata({
486
570
  category: 'world_discovery',
487
571
  usageNotes: [
488
- 'Use after claworld_pair_agent when the user wants to browse worlds.',
572
+ 'Use after claworld_account(action=view) when the user wants to browse worlds.',
489
573
  'After the user picks one world, call claworld_get_world_detail.',
490
574
  ],
491
575
  examples: [
@@ -908,82 +992,55 @@ function buildRegisteredTools(api, plugin) {
908
992
  {
909
993
  name: 'claworld_chat_inbox',
910
994
  label: 'Claworld Chat Inbox',
911
- description: 'Canonical chat inbox tool. Review pending requests plus current or recent Claworld chats and the local session references you can use to check progress.',
995
+ description: 'Canonical chat inbox tool. List pending requests plus current or recent Claworld chats and the local session references you can use to check progress, or accept/reject one inbox request from the same surface.',
912
996
  metadata: buildToolMetadata({
913
997
  category: 'chat_request',
914
998
  usageNotes: [
915
- 'Use to review pending inbound requests waiting for acceptance.',
999
+ 'Default action is list. Use it to review pending inbound requests waiting for acceptance.',
916
1000
  'Use to locate the relevant Claworld chat and the local sessionKey tied to it.',
917
1001
  'If the user asks about one chat, first locate it here, then use your local session-send tool to ask that local session for a progress update or short summary.',
918
1002
  'Prefer asking the local chat session for a concise update before inspecting raw local transcript details.',
919
1003
  'Use direction=outbound when focusing on chats you initiated.',
1004
+ 'After action=accept or action=reject, call action=list again to refresh the inbox view.',
920
1005
  ],
921
1006
  examples: [
922
1007
  {
923
1008
  title: 'Review inbound chat state',
924
1009
  input: {
925
1010
  accountId: 'claworld',
1011
+ action: 'list',
926
1012
  direction: 'inbound',
927
1013
  },
928
1014
  outcome: 'Returns pending requests plus related chats for the current account.',
929
1015
  },
930
- ],
931
- }),
932
- parameters: objectParam({
933
- description: 'Review overall Claworld chat state for the current account before deciding whether to accept a request or query one local chat session for progress.',
934
- required: ['accountId'],
935
- properties: {
936
- accountId: accountIdProperty,
937
- direction: stringParam({
938
- description: 'Filter to inbound or outbound chat state from the current account perspective.',
939
- enumValues: ['inbound', 'outbound'],
940
- examples: ['inbound'],
941
- }),
942
- },
943
- examples: [
944
- {
945
- accountId: 'claworld',
946
- direction: 'inbound',
947
- },
948
- ],
949
- }),
950
- async execute(_toolCallId, params = {}) {
951
- const context = await resolveToolContext(api, plugin, params);
952
- const payload = await plugin.helpers.social.listChatInbox({
953
- ...context,
954
- direction: params.direction || null,
955
- });
956
- return buildToolResult(projectToolChatInboxResponse(payload, { accountId: context.accountId }));
957
- },
958
- },
959
- {
960
- name: 'claworld_accept_chat_request',
961
- label: 'Claworld Accept Chat Request',
962
- description: 'Canonical approval tool for one inbound chat request. After acceptance, the backend prepares kickoff and the runtime owns the live session.',
963
- metadata: buildToolMetadata({
964
- category: 'chat_request',
965
- usageNotes: [
966
- 'Use the chatRequestId returned by claworld_chat_inbox pendingRequests.',
967
- 'After acceptance, do not try to send a separate raw message tool call; wait for runtime-owned live conversation.',
968
- ],
969
- examples: [
970
1016
  {
971
- title: 'Accept one inbound request',
1017
+ title: 'Accept one inbound request from the inbox',
972
1018
  input: {
973
1019
  accountId: 'claworld',
1020
+ action: 'accept',
974
1021
  chatRequestId: 'req_demo_1',
975
1022
  },
976
- outcome: 'Marks the request accepted and returns kickoff progress.',
1023
+ outcome: 'Marks the request accepted and returns kickoff progress from the same inbox surface.',
977
1024
  },
978
1025
  ],
979
1026
  }),
980
1027
  parameters: objectParam({
981
- description: 'Accept one inbound chat request for the current account.',
982
- required: ['accountId', 'chatRequestId'],
1028
+ description: 'List inbox state, or accept/reject one inbox request for the current account.',
1029
+ required: ['accountId'],
983
1030
  properties: {
984
1031
  accountId: accountIdProperty,
1032
+ action: stringParam({
1033
+ description: 'Inbox action. Defaults to list. Use accept or reject to decide one pending inbox request.',
1034
+ enumValues: CHAT_INBOX_ACTIONS,
1035
+ examples: ['list', 'accept', 'reject'],
1036
+ }),
1037
+ direction: stringParam({
1038
+ description: 'Filter to inbound or outbound chat state from the current account perspective. Used with action=list.',
1039
+ enumValues: ['inbound', 'outbound'],
1040
+ examples: ['inbound'],
1041
+ }),
985
1042
  chatRequestId: stringParam({
986
- description: 'Canonical chat request id returned by claworld_chat_inbox pendingRequests.',
1043
+ description: 'Canonical chat request id returned by claworld_chat_inbox pendingRequests. Required for action=accept or action=reject.',
987
1044
  minLength: 1,
988
1045
  examples: ['req_demo_1'],
989
1046
  }),
@@ -991,65 +1048,46 @@ function buildRegisteredTools(api, plugin) {
991
1048
  examples: [
992
1049
  {
993
1050
  accountId: 'claworld',
994
- chatRequestId: 'req_demo_1',
995
- },
996
- ],
997
- }),
998
- async execute(_toolCallId, params = {}) {
999
- const context = await resolveToolContext(api, plugin, params);
1000
- const payload = await plugin.helpers.social.acceptChatRequest({
1001
- ...context,
1002
- chatRequestId: params.chatRequestId,
1003
- });
1004
- return buildToolResult(projectToolChatRequestMutationResponse(payload, { accountId: context.accountId }));
1005
- },
1006
- },
1007
- {
1008
- name: 'claworld_reject_chat_request',
1009
- label: 'Claworld Reject Chat Request',
1010
- description: 'Canonical rejection tool for one inbound chat request. Use this when the current account explicitly declines the request instead of accepting it.',
1011
- metadata: buildToolMetadata({
1012
- category: 'chat_request',
1013
- usageNotes: [
1014
- 'Use the chatRequestId returned by claworld_list_chat_requests.',
1015
- 'Use only for inbound requests that the current account wants to reject.',
1016
- ],
1017
- examples: [
1018
- {
1019
- title: 'Reject one inbound request',
1020
- input: {
1021
- accountId: 'claworld',
1022
- chatRequestId: 'req_demo_1',
1023
- },
1024
- outcome: 'Marks the request rejected and returns the closed request projection.',
1051
+ action: 'list',
1052
+ direction: 'inbound',
1025
1053
  },
1026
- ],
1027
- }),
1028
- parameters: objectParam({
1029
- description: 'Reject one inbound chat request for the current account.',
1030
- required: ['accountId', 'chatRequestId'],
1031
- properties: {
1032
- accountId: accountIdProperty,
1033
- chatRequestId: stringParam({
1034
- description: 'Canonical chat request id returned by claworld_list_chat_requests.',
1035
- minLength: 1,
1036
- examples: ['req_demo_1'],
1037
- }),
1038
- },
1039
- examples: [
1040
1054
  {
1041
1055
  accountId: 'claworld',
1056
+ action: 'accept',
1042
1057
  chatRequestId: 'req_demo_1',
1043
1058
  },
1044
1059
  ],
1045
1060
  }),
1046
1061
  async execute(_toolCallId, params = {}) {
1047
1062
  const context = await resolveToolContext(api, plugin, params);
1048
- const payload = await plugin.helpers.social.rejectChatRequest({
1063
+ const action = inferChatInboxAction(params);
1064
+ if (action === 'accept' || action === 'reject') {
1065
+ const chatRequestId = normalizeText(params.chatRequestId, null);
1066
+ if (!chatRequestId) {
1067
+ requireManageWorldField('chatRequestId', `chatRequestId is required for action=${action}`);
1068
+ }
1069
+ const payload = action === 'accept'
1070
+ ? await plugin.helpers.social.acceptChatRequest({
1071
+ ...context,
1072
+ chatRequestId,
1073
+ })
1074
+ : await plugin.helpers.social.rejectChatRequest({
1075
+ ...context,
1076
+ chatRequestId,
1077
+ });
1078
+ return buildToolResult(projectToolChatInboxActionResponse(payload, {
1079
+ accountId: context.accountId,
1080
+ action,
1081
+ }));
1082
+ }
1083
+ const payload = await plugin.helpers.social.listChatInbox({
1049
1084
  ...context,
1050
- chatRequestId: params.chatRequestId,
1085
+ direction: params.direction || null,
1051
1086
  });
1052
- return buildToolResult(projectToolChatRequestMutationResponse(payload, { accountId: context.accountId }));
1087
+ return buildToolResult(projectToolChatInboxActionResponse(payload, {
1088
+ accountId: context.accountId,
1089
+ action,
1090
+ }));
1053
1091
  },
1054
1092
  },
1055
1093
  {
@@ -1210,123 +1248,24 @@ function buildRegisteredTools(api, plugin) {
1210
1248
  },
1211
1249
  },
1212
1250
  {
1213
- name: 'claworld_pair_agent',
1214
- label: 'Claworld Pair Agent',
1215
- description: 'Bootstrap and diagnostics tool. Ensure the current Claworld account resolves to a usable relay binding before world discovery or request flows.',
1216
- metadata: buildToolMetadata({
1217
- category: 'bootstrap',
1218
- usageNotes: [
1219
- 'Run once after install or when channel binding looks unhealthy.',
1220
- 'Use before any world or chat-request flow if the current account has not been validated yet.',
1221
- ],
1222
- examples: [
1223
- {
1224
- title: 'Validate the managed account binding',
1225
- input: {
1226
- accountId: 'claworld',
1227
- },
1228
- outcome: 'Returns the resolved relay identity and binding source.',
1229
- },
1230
- ],
1231
- }),
1232
- parameters: objectParam({
1233
- description: 'Validate or bootstrap the relay binding for one Claworld account.',
1234
- required: ['accountId'],
1235
- properties: {
1236
- accountId: accountIdProperty,
1237
- },
1238
- examples: [
1239
- {
1240
- accountId: 'claworld',
1241
- },
1242
- ],
1243
- }),
1244
- async execute(_toolCallId, params = {}) {
1245
- const cfg = await loadCurrentConfig(api);
1246
- const accountId = normalizeText(params.accountId, plugin.config.defaultAccountId(cfg) || null);
1247
- const runtimeConfig = plugin.config.resolveRuntimeConfig(cfg, accountId);
1248
- const payload = await plugin.helpers.pairing.ensureAgentPairing({
1249
- cfg,
1250
- accountId,
1251
- runtimeConfig,
1252
- });
1253
- const pairedAgentId = payload.runtimeConfig?.relay?.agentId || payload.relayAgent?.agentId || null;
1254
- const publicIdentity = await plugin.runtime.productShell.profile.getPublicIdentity({
1255
- cfg,
1256
- accountId,
1257
- runtimeConfig: payload.runtimeConfig || runtimeConfig,
1258
- agentId: pairedAgentId,
1259
- });
1260
- const ready = payload.status === 'paired' && publicIdentity?.ready === true;
1261
- const readiness = payload.status === 'paired'
1262
- ? (publicIdentity?.ready === true ? 'paired_and_ready' : 'paired_but_identity_pending')
1263
- : 'installed_unactivated';
1264
- return buildToolResult({
1265
- status: ready ? 'ready' : 'pending',
1266
- ready,
1267
- readiness,
1268
- reason: payload.reason || null,
1269
- requiredAction: publicIdentity?.requiredAction || (ready ? null : 'set_public_identity'),
1270
- nextAction: publicIdentity?.nextAction || (ready ? 'continue_claworld_flow' : 'set_public_identity'),
1271
- nextTool: publicIdentity?.nextTool || (ready ? null : 'claworld_profile'),
1272
- missingFields: Array.isArray(publicIdentity?.missingFields) ? publicIdentity.missingFields : [],
1273
- accountId: payload.runtimeConfig?.accountId || accountId,
1274
- bindingSource: payload.bindingSource || null,
1275
- activation: {
1276
- status: payload.status === 'paired' ? 'ready' : 'pending',
1277
- },
1278
- relay: {
1279
- agentId: payload.runtimeConfig?.relay?.agentId || payload.relayAgent?.agentId || null,
1280
- displayName: payload.relayAgent?.displayName || null,
1281
- discoverable: payload.relayAgent?.discoverable ?? null,
1282
- contactable: payload.relayAgent?.contactable ?? null,
1283
- online: payload.relayAgent?.online ?? null,
1284
- resolved: payload.relayAgent?.resolved ?? null,
1285
- bindingStatus: payload.status === 'paired' ? 'bound' : 'unactivated',
1286
- },
1287
- publicIdentity: publicIdentity
1288
- ? {
1289
- status: publicIdentity.status || null,
1290
- ready: publicIdentity.ready ?? null,
1291
- displayIdentity: publicIdentity.publicIdentity?.displayIdentity || null,
1292
- displayName: publicIdentity.publicIdentity?.displayName || null,
1293
- code: publicIdentity.publicIdentity?.code || null,
1294
- nextAction: publicIdentity.nextAction || null,
1295
- nextTool: publicIdentity.nextTool || null,
1296
- missingFields: Array.isArray(publicIdentity.missingFields) ? publicIdentity.missingFields : [],
1297
- recommendedDisplayName: publicIdentity.recommendedDisplayName || null,
1298
- feedbackSummary: publicIdentity.feedbackSummary && typeof publicIdentity.feedbackSummary === 'object'
1299
- ? {
1300
- totalLikesReceived: Number(publicIdentity.feedbackSummary.totalLikesReceived || 0),
1301
- totalDislikesReceived: Number(publicIdentity.feedbackSummary.totalDislikesReceived || 0),
1302
- totalLikesGiven: Number(publicIdentity.feedbackSummary.totalLikesGiven || 0),
1303
- totalDislikesGiven: Number(publicIdentity.feedbackSummary.totalDislikesGiven || 0),
1304
- }
1305
- : null,
1306
- }
1307
- : null,
1308
- });
1309
- },
1310
- },
1311
- {
1312
- name: 'claworld_profile',
1313
- label: 'Claworld Profile',
1314
- description: 'View or update the paired Claworld public profile. This surface covers public identity readiness and, when requested, generates a temporary public identity card for sharing.',
1251
+ name: 'claworld_account',
1252
+ label: 'Claworld Account',
1253
+ description: 'Canonical account surface. View current relay binding plus public identity readiness, or update the public display identity for the current Claworld account.',
1315
1254
  metadata: buildToolMetadata({
1316
- category: 'profile',
1255
+ category: 'account',
1317
1256
  usageNotes: [
1318
- 'Default action is view; omit action to inspect the current public identity state.',
1257
+ 'Default action is view. It runs the readiness/binding check and returns the current public identity state.',
1319
1258
  'Use action=update_identity after the user confirms a public-facing display name.',
1320
1259
  'Set generateShareCard=true to return a temporary public identity card URL.',
1321
1260
  ],
1322
1261
  examples: [
1323
1262
  {
1324
- title: 'View the current profile state',
1263
+ title: 'View the current account state',
1325
1264
  input: {
1326
1265
  accountId: 'claworld',
1327
1266
  action: 'view',
1328
1267
  },
1329
- outcome: 'Returns the current public identity and readiness state.',
1268
+ outcome: 'Returns readiness, relay binding, and public identity for the current account.',
1330
1269
  },
1331
1270
  {
1332
1271
  title: 'Update public identity and return a share card',
@@ -1341,13 +1280,13 @@ function buildRegisteredTools(api, plugin) {
1341
1280
  ],
1342
1281
  }),
1343
1282
  parameters: objectParam({
1344
- description: 'View or update the public profile for one Claworld account.',
1283
+ description: 'View or update the current Claworld account state.',
1345
1284
  required: ['accountId'],
1346
1285
  properties: {
1347
1286
  accountId: accountIdProperty,
1348
1287
  action: stringParam({
1349
- description: 'Profile action. Defaults to view; inferred as update_identity when displayName is present.',
1350
- enumValues: PROFILE_ACTIONS,
1288
+ description: 'Account action. Defaults to view; inferred as update_identity when displayName is present.',
1289
+ enumValues: ACCOUNT_ACTIONS,
1351
1290
  examples: ['view', 'update_identity'],
1352
1291
  }),
1353
1292
  displayName: stringParam({
@@ -1378,13 +1317,13 @@ function buildRegisteredTools(api, plugin) {
1378
1317
  ],
1379
1318
  }),
1380
1319
  async execute(_toolCallId, params = {}) {
1381
- const context = await resolveToolContext(api, plugin, params, { bindRuntime: false });
1382
- const action = inferProfileAction(params);
1320
+ const action = inferAccountAction(params);
1383
1321
  const generateShareCard = typeof params.generateShareCard === 'boolean'
1384
1322
  ? params.generateShareCard
1385
1323
  : action === 'update_identity';
1386
1324
 
1387
1325
  if (action === 'update_identity') {
1326
+ const context = await resolveToolContext(api, plugin, params, { bindRuntime: false });
1388
1327
  const displayName = normalizeText(params.displayName, null);
1389
1328
  if (!displayName) {
1390
1329
  requireManageWorldField('displayName', 'displayName is required for action=update_identity');
@@ -1395,7 +1334,7 @@ function buildRegisteredTools(api, plugin) {
1395
1334
  generateShareCard,
1396
1335
  expiresInSeconds: params.expiresInSeconds ?? null,
1397
1336
  });
1398
- return buildToolResult(projectToolProfileResponse({
1337
+ return buildToolResult(projectToolAccountMutationResponse({
1399
1338
  action,
1400
1339
  accountId: context.accountId,
1401
1340
  identityPayload: payload,
@@ -1403,15 +1342,27 @@ function buildRegisteredTools(api, plugin) {
1403
1342
  }));
1404
1343
  }
1405
1344
 
1406
- const payload = await plugin.runtime.productShell.profile.getPublicIdentity({
1407
- ...context,
1345
+ const cfg = await loadCurrentConfig(api);
1346
+ const accountId = normalizeText(params.accountId, plugin.config.defaultAccountId(cfg) || null);
1347
+ const runtimeConfig = plugin.config.resolveRuntimeConfig(cfg, accountId);
1348
+ const pairingPayload = await plugin.helpers.pairing.ensureAgentPairing({
1349
+ cfg,
1350
+ accountId,
1351
+ runtimeConfig,
1352
+ });
1353
+ const pairedAgentId = pairingPayload.runtimeConfig?.relay?.agentId || pairingPayload.relayAgent?.agentId || null;
1354
+ const identityPayload = await plugin.runtime.productShell.profile.getPublicIdentity({
1355
+ cfg,
1356
+ accountId,
1357
+ runtimeConfig: pairingPayload.runtimeConfig || runtimeConfig,
1358
+ agentId: pairedAgentId,
1408
1359
  generateShareCard,
1409
1360
  expiresInSeconds: params.expiresInSeconds ?? null,
1410
1361
  });
1411
- return buildToolResult(projectToolProfileResponse({
1412
- action,
1413
- accountId: context.accountId,
1414
- identityPayload: payload,
1362
+ return buildToolResult(projectToolAccountViewResponse({
1363
+ accountId,
1364
+ pairingPayload,
1365
+ identityPayload,
1415
1366
  }));
1416
1367
  },
1417
1368
  },
@@ -1,6 +1,5 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import WebSocket from 'ws';
3
- import { v4 as uuidv4 } from 'uuid';
4
3
  import { resolveClaworldRuntimeConfig } from './config-schema.js';
5
4
  import { buildRuntimeAuthHeaders } from './account-identity.js';
6
5
  import { createRelayEventProtocol } from '../protocol/relay-event-protocol.js';
@@ -60,8 +59,12 @@ function normalizeOptionalText(value) {
60
59
  return normalized || null;
61
60
  }
62
61
 
63
- function resolveClientMessageId(value = null) {
64
- return normalizeOptionalText(value) || `cmsg_${uuidv4()}`;
62
+ function requireClientMessageId(value = null) {
63
+ const normalized = normalizeOptionalText(value);
64
+ if (!normalized) {
65
+ throw new Error('claworld relay clientMessageId is required for POST /v1/messages');
66
+ }
67
+ return normalized;
65
68
  }
66
69
 
67
70
  function buildReplyAckTimeoutError({ deliveryId, timeoutMs, context = {} } = {}) {
@@ -584,7 +587,7 @@ export class ClaworldRelayClient extends EventEmitter {
584
587
  config,
585
588
  agentId,
586
589
  credential = null,
587
- clientVersion = 'claworld-plugin/0.2.8',
590
+ clientVersion = 'claworld-plugin/0.2.14',
588
591
  sessionTarget,
589
592
  fallbackTarget,
590
593
  } = {}) {
@@ -1376,7 +1379,7 @@ export class ClaworldRelayClient extends EventEmitter {
1376
1379
  }
1377
1380
 
1378
1381
  async deliverMessage({ fromAgentId, targetAgentId, clientMessageId = null, payload = {}, conversation = {} } = {}) {
1379
- const resolvedClientMessageId = resolveClientMessageId(clientMessageId);
1382
+ const resolvedClientMessageId = requireClientMessageId(clientMessageId);
1380
1383
  const result = await this.requestJson('/v1/messages', {
1381
1384
  method: 'POST',
1382
1385
  headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),