@xfxstudio/claworld 2026.6.10 → 2026.6.29-testing.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.
@@ -1303,6 +1303,7 @@ async function fetchPublicIdentity({
1303
1303
  agentId = null,
1304
1304
  generateShareCard = false,
1305
1305
  expiresInSeconds = null,
1306
+ shareCardVariant = null,
1306
1307
  fetchImpl,
1307
1308
  }) {
1308
1309
  if (!resolveRuntimeAppToken(runtimeConfig)) {
@@ -1361,6 +1362,7 @@ async function fetchPublicIdentity({
1361
1362
  ...(agentId ? { agentId } : {}),
1362
1363
  action: 'view',
1363
1364
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1365
+ ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1364
1366
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1365
1367
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
1366
1368
  : {}),
@@ -1384,6 +1386,7 @@ async function updatePublicIdentity({
1384
1386
  displayName = null,
1385
1387
  generateShareCard = true,
1386
1388
  expiresInSeconds = null,
1389
+ shareCardVariant = null,
1387
1390
  fetchImpl,
1388
1391
  }) {
1389
1392
  const normalizedDisplayName = normalizeClaworldText(displayName, null);
@@ -1402,43 +1405,17 @@ async function updatePublicIdentity({
1402
1405
  let resolvedAgentId = normalizeClaworldText(agentId, normalizeClaworldText(resolvedRuntimeConfig?.relay?.agentId, null));
1403
1406
 
1404
1407
  if (!resolveRuntimeAppToken(resolvedRuntimeConfig)) {
1405
- const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
1406
- const activationResult = await fetchJson(fetchImpl, `${baseUrl}/v1/onboarding/activate`, {
1407
- method: 'POST',
1408
- headers: {
1409
- 'content-type': 'application/json',
1410
- ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
1411
- ...buildRuntimeAuthHeaders(resolvedRuntimeConfig),
1408
+ throw createRuntimeBoundaryError({
1409
+ code: 'email_verification_required',
1410
+ category: 'auth',
1411
+ status: 401,
1412
+ message: 'claworld email verification is required before updating public identity',
1413
+ publicMessage: 'complete Claworld email verification before updating public identity',
1414
+ recoverable: true,
1415
+ context: {
1416
+ requiredActions: ['start_email_verification', 'complete_email_verification'],
1412
1417
  },
1413
- body: JSON.stringify({
1414
- displayName: normalizedDisplayName,
1415
- }),
1416
- });
1417
- if (!activationResult.ok) {
1418
- createRelayRouteError({
1419
- result: activationResult,
1420
- runtimeConfig: resolvedRuntimeConfig,
1421
- code: 'claworld_activation_failed',
1422
- publicMessage: 'failed to activate Claworld account',
1423
- });
1424
- }
1425
- const activatedToken = normalizeClaworldText(activationResult.body?.appToken, null);
1426
- const activatedAgentId = normalizeClaworldText(activationResult.body?.agentId, null);
1427
- if (!activatedToken || !activatedAgentId) {
1428
- throw createRuntimeBoundaryError({
1429
- code: 'claworld_activation_failed',
1430
- category: 'runtime',
1431
- status: 502,
1432
- message: 'claworld activation did not return appToken and agentId',
1433
- publicMessage: 'failed to activate Claworld account',
1434
- recoverable: true,
1435
- });
1436
- }
1437
- resolvedRuntimeConfig = applyRuntimeIdentity(resolvedRuntimeConfig, {
1438
- appToken: activatedToken,
1439
- agentId: activatedAgentId,
1440
1418
  });
1441
- resolvedAgentId = activatedAgentId;
1442
1419
  }
1443
1420
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1444
1421
  const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
@@ -1454,6 +1431,7 @@ async function updatePublicIdentity({
1454
1431
  action: 'update_identity',
1455
1432
  displayName: normalizedDisplayName,
1456
1433
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1434
+ ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1457
1435
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1458
1436
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
1459
1437
  : {}),
@@ -1472,9 +1450,9 @@ async function updatePublicIdentity({
1472
1450
  }
1473
1451
  return {
1474
1452
  ...(result.body || {}),
1475
- runtimeActivation: !resolveRuntimeAppToken(runtimeConfig)
1453
+ runtimeIdentity: !resolveRuntimeAppToken(runtimeConfig)
1476
1454
  ? {
1477
- status: 'activated',
1455
+ status: 'verified',
1478
1456
  agentId: resolvedAgentId,
1479
1457
  }
1480
1458
  : null,
@@ -1482,6 +1460,106 @@ async function updatePublicIdentity({
1482
1460
  };
1483
1461
  }
1484
1462
 
1463
+ async function startEmailVerification({
1464
+ runtimeConfig,
1465
+ email = null,
1466
+ displayName = null,
1467
+ fetchImpl,
1468
+ }) {
1469
+ const normalizedEmail = normalizeClaworldText(email, null);
1470
+ if (!normalizedEmail) {
1471
+ throw createRuntimeBoundaryError({
1472
+ code: 'tool_input_invalid',
1473
+ category: 'input',
1474
+ status: 400,
1475
+ message: 'claworld email verification requires email',
1476
+ publicMessage: 'claworld email verification requires email',
1477
+ recoverable: true,
1478
+ context: { field: 'email' },
1479
+ });
1480
+ }
1481
+ const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1482
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/identity/email/start`, {
1483
+ method: 'POST',
1484
+ headers: {
1485
+ 'content-type': 'application/json',
1486
+ ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
1487
+ },
1488
+ body: JSON.stringify({
1489
+ email: normalizedEmail,
1490
+ ...(normalizeClaworldText(displayName, null) ? { displayName: normalizeClaworldText(displayName, null) } : {}),
1491
+ }),
1492
+ });
1493
+ if (!result.ok) {
1494
+ createRelayRouteError({
1495
+ result,
1496
+ runtimeConfig,
1497
+ code: 'email_verification_start_failed',
1498
+ publicMessage: 'failed to start Claworld email verification',
1499
+ context: { email: normalizedEmail },
1500
+ });
1501
+ }
1502
+ const payload = result.body && typeof result.body === 'object' && !Array.isArray(result.body)
1503
+ ? { ...result.body }
1504
+ : {};
1505
+ delete payload.verificationId;
1506
+ return payload;
1507
+ }
1508
+
1509
+ async function completeEmailVerification({
1510
+ runtimeConfig,
1511
+ email = null,
1512
+ code = null,
1513
+ fetchImpl,
1514
+ }) {
1515
+ const normalizedEmail = normalizeClaworldText(email, null);
1516
+ const normalizedCode = normalizeClaworldText(code, null);
1517
+ if (!normalizedEmail) {
1518
+ throw createRuntimeBoundaryError({
1519
+ code: 'tool_input_invalid',
1520
+ category: 'input',
1521
+ status: 400,
1522
+ message: 'claworld email verification requires email',
1523
+ publicMessage: 'claworld email verification requires email',
1524
+ recoverable: true,
1525
+ context: { field: 'email' },
1526
+ });
1527
+ }
1528
+ if (!normalizedCode) {
1529
+ throw createRuntimeBoundaryError({
1530
+ code: 'tool_input_invalid',
1531
+ category: 'input',
1532
+ status: 400,
1533
+ message: 'claworld email verification requires code',
1534
+ publicMessage: 'claworld email verification requires code',
1535
+ recoverable: true,
1536
+ context: { field: 'code' },
1537
+ });
1538
+ }
1539
+ const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1540
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/identity/email/verify`, {
1541
+ method: 'POST',
1542
+ headers: {
1543
+ 'content-type': 'application/json',
1544
+ ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
1545
+ },
1546
+ body: JSON.stringify({
1547
+ email: normalizedEmail,
1548
+ code: normalizedCode,
1549
+ }),
1550
+ });
1551
+ if (!result.ok) {
1552
+ createRelayRouteError({
1553
+ result,
1554
+ runtimeConfig,
1555
+ code: 'email_verification_complete_failed',
1556
+ publicMessage: 'failed to complete Claworld email verification',
1557
+ context: { email: normalizedEmail },
1558
+ });
1559
+ }
1560
+ return result.body || {};
1561
+ }
1562
+
1485
1563
  async function updateChatRequestApprovalPolicy({
1486
1564
  runtimeConfig,
1487
1565
  agentId = null,
@@ -1490,11 +1568,11 @@ async function updateChatRequestApprovalPolicy({
1490
1568
  }) {
1491
1569
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1492
1570
  throw createRuntimeBoundaryError({
1493
- code: 'claworld_account_unactivated',
1571
+ code: 'claworld_identity_unverified',
1494
1572
  category: 'conflict',
1495
1573
  status: 409,
1496
- message: 'claworld account must be activated before updating chat policy',
1497
- publicMessage: 'activate the Claworld account before changing chat policy',
1574
+ message: 'claworld email verification must be completed before updating chat policy',
1575
+ publicMessage: 'complete Claworld email verification before changing chat policy',
1498
1576
  recoverable: true,
1499
1577
  });
1500
1578
  }
@@ -1537,11 +1615,11 @@ async function updateGlobalProfile({
1537
1615
  }) {
1538
1616
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1539
1617
  throw createRuntimeBoundaryError({
1540
- code: 'claworld_account_unactivated',
1618
+ code: 'claworld_identity_unverified',
1541
1619
  category: 'conflict',
1542
1620
  status: 409,
1543
- message: 'claworld account must be activated before updating profile',
1544
- publicMessage: 'activate the Claworld account before updating profile',
1621
+ message: 'claworld email verification must be completed before updating profile',
1622
+ publicMessage: 'complete Claworld email verification before updating profile',
1545
1623
  recoverable: true,
1546
1624
  });
1547
1625
  }
@@ -1686,15 +1764,16 @@ async function executeRuntimeAccountAction({
1686
1764
  proactivitySettings = undefined,
1687
1765
  generateShareCard = false,
1688
1766
  expiresInSeconds = null,
1767
+ shareCardVariant = null,
1689
1768
  fetchImpl,
1690
1769
  }) {
1691
1770
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1692
1771
  throw createRuntimeBoundaryError({
1693
- code: 'claworld_account_unactivated',
1772
+ code: 'claworld_identity_unverified',
1694
1773
  category: 'conflict',
1695
1774
  status: 409,
1696
- message: 'claworld account must be activated before managing account settings',
1697
- publicMessage: 'activate the Claworld account before changing account settings',
1775
+ message: 'claworld email verification must be completed before managing account settings',
1776
+ publicMessage: 'complete Claworld email verification before changing account settings',
1698
1777
  recoverable: true,
1699
1778
  });
1700
1779
  }
@@ -1720,6 +1799,7 @@ async function executeRuntimeAccountAction({
1720
1799
  ...(chatRequestApprovalPolicy ? { chatRequestApprovalPolicy } : {}),
1721
1800
  ...(proactivitySettings !== undefined ? { proactivitySettings } : {}),
1722
1801
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1802
+ ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1723
1803
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1724
1804
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
1725
1805
  : {}),
@@ -3502,7 +3582,7 @@ export function createClaworldChannelPlugin({
3502
3582
  method: 'loadConfig_writeConfigFile',
3503
3583
  };
3504
3584
  if (!mutationOutcome.skipped) {
3505
- await runtime.config.writeConfigFile(nextCfg);
3585
+ await runtime.config.writeConfigFile(nextCfg, { afterWrite: { mode: 'auto' } });
3506
3586
  }
3507
3587
  }
3508
3588
  } catch (error) {
@@ -3986,11 +4066,12 @@ export function createClaworldChannelPlugin({
3986
4066
  agentId: resolvedContext.agentId || null,
3987
4067
  generateShareCard: context.generateShareCard === true,
3988
4068
  expiresInSeconds: context.expiresInSeconds ?? null,
4069
+ shareCardVariant: context.shareCardVariant ?? null,
3989
4070
  fetchImpl,
3990
4071
  });
3991
4072
  }
3992
4073
 
3993
- async function updateRuntimePublicIdentity(context = {}) {
4074
+ async function updateRuntimePublicIdentity(context = {}) {
3994
4075
  const configuredContext = resolveConfiguredRuntimeContext(context);
3995
4076
  const resolvedContext = await resolveBoundRuntimeContext(context);
3996
4077
  const updateResult = await updatePublicIdentity({
@@ -3999,17 +4080,18 @@ async function updateRuntimePublicIdentity(context = {}) {
3999
4080
  displayName: context.displayName || null,
4000
4081
  generateShareCard: context.generateShareCard !== false,
4001
4082
  expiresInSeconds: context.expiresInSeconds ?? null,
4083
+ shareCardVariant: context.shareCardVariant ?? null,
4002
4084
  fetchImpl,
4003
4085
  });
4004
4086
 
4005
- const runtimeActivation = updateResult?.runtimeActivation && typeof updateResult.runtimeActivation === 'object'
4006
- ? updateResult.runtimeActivation
4087
+ const runtimeIdentity = updateResult?.runtimeIdentity && typeof updateResult.runtimeIdentity === 'object'
4088
+ ? updateResult.runtimeIdentity
4007
4089
  : null;
4008
4090
  const nextRuntimeConfig = updateResult?.runtimeConfig && typeof updateResult.runtimeConfig === 'object'
4009
4091
  ? updateResult.runtimeConfig
4010
4092
  : resolvedContext.runtimeConfig;
4011
4093
  const nextAgentId = normalizeClaworldText(
4012
- runtimeActivation?.agentId,
4094
+ runtimeIdentity?.agentId,
4013
4095
  normalizeClaworldText(
4014
4096
  updateResult?.agentId,
4015
4097
  null,
@@ -4032,7 +4114,7 @@ async function updateRuntimePublicIdentity(context = {}) {
4032
4114
  nextAppToken
4033
4115
  && nextAgentId
4034
4116
  && (
4035
- runtimeActivation
4117
+ runtimeIdentity
4036
4118
  || configuredAppToken !== nextAppToken
4037
4119
  || previousAgentId !== nextAgentId
4038
4120
  ),
@@ -4049,7 +4131,7 @@ async function updateRuntimePublicIdentity(context = {}) {
4049
4131
  runtimeConfig: boundRuntimeConfig,
4050
4132
  });
4051
4133
  } catch (error) {
4052
- logger.warn?.('[claworld:profile] failed to persist activated runtime binding', {
4134
+ logger.warn?.('[claworld:profile] failed to persist verified runtime binding', {
4053
4135
  accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
4054
4136
  error: error?.message || String(error),
4055
4137
  });
@@ -4058,8 +4140,8 @@ async function updateRuntimePublicIdentity(context = {}) {
4058
4140
  rememberAccountBinding({
4059
4141
  runtimeConfig: boundRuntimeConfig,
4060
4142
  accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
4061
- bindingSource: runtimeActivation
4062
- ? 'activated_app_token'
4143
+ bindingSource: runtimeIdentity
4144
+ ? 'verified_app_token'
4063
4145
  : (resolvedContext.bindingSource || 'configured_app_token'),
4064
4146
  });
4065
4147
 
@@ -4082,6 +4164,158 @@ async function updateRuntimePublicIdentity(context = {}) {
4082
4164
  return payload;
4083
4165
  }
4084
4166
 
4167
+ async function startRuntimeEmailVerification(context = {}) {
4168
+ const configuredContext = resolveConfiguredRuntimeContext(context);
4169
+ return startEmailVerification({
4170
+ runtimeConfig: configuredContext.runtimeConfig,
4171
+ email: context.email || null,
4172
+ displayName: context.displayName || null,
4173
+ fetchImpl,
4174
+ });
4175
+ }
4176
+
4177
+ function projectRuntimeCredentialPersistence(persistence = {}) {
4178
+ if (!persistence || typeof persistence !== 'object' || Array.isArray(persistence)) {
4179
+ return { status: 'unknown' };
4180
+ }
4181
+ const skipped = persistence?.skipped === true;
4182
+ return {
4183
+ status: skipped ? 'best_effort' : 'saved',
4184
+ method: normalizeClaworldText(persistence?.method, null),
4185
+ reason: skipped ? normalizeClaworldText(persistence?.reason, null) : null,
4186
+ backupStatus: persistence?.backup?.skipped === true
4187
+ ? 'best_effort'
4188
+ : (persistence?.backup?.ok === true ? 'saved' : null),
4189
+ restartRequired: false,
4190
+ reloadRequired: !skipped,
4191
+ reloadMode: skipped ? null : 'openclaw_channel_hot_reload',
4192
+ };
4193
+ }
4194
+
4195
+ async function completeRuntimeEmailVerification(context = {}) {
4196
+ const configuredContext = resolveConfiguredRuntimeContext(context);
4197
+ const verification = await completeEmailVerification({
4198
+ runtimeConfig: configuredContext.runtimeConfig,
4199
+ email: context.email || null,
4200
+ code: context.code || null,
4201
+ fetchImpl,
4202
+ });
4203
+ const appToken = normalizeClaworldText(verification?.appToken, null);
4204
+ const agentId = normalizeClaworldText(verification?.agentId, null);
4205
+ if (!appToken || !agentId) {
4206
+ throw createRuntimeBoundaryError({
4207
+ code: 'email_verification_complete_failed',
4208
+ category: 'runtime',
4209
+ status: 502,
4210
+ message: 'claworld email verification did not return appToken and agentId',
4211
+ publicMessage: 'failed to complete Claworld email verification',
4212
+ recoverable: true,
4213
+ });
4214
+ }
4215
+
4216
+ const boundRuntimeConfig = applyRuntimeIdentity(configuredContext.runtimeConfig, {
4217
+ appToken,
4218
+ agentId,
4219
+ });
4220
+ const accountId = configuredContext.accountId || boundRuntimeConfig.accountId || null;
4221
+ const runtimeResolution = resolvePluginRuntimeCandidate(context.runtime || null);
4222
+ let persistence = null;
4223
+ try {
4224
+ persistence = await persistRuntimeAppToken({
4225
+ runtime: runtimeResolution.runtime,
4226
+ accountId,
4227
+ appToken,
4228
+ relayAgentId: agentId,
4229
+ runtimeConfig: boundRuntimeConfig,
4230
+ });
4231
+ } catch (error) {
4232
+ persistence = {
4233
+ skipped: true,
4234
+ reason: 'persist_runtime_binding_failed',
4235
+ error: error?.message || String(error),
4236
+ };
4237
+ logger.warn?.('[claworld:identity] failed to persist email verification runtime binding', {
4238
+ accountId,
4239
+ error: persistence.error,
4240
+ });
4241
+ }
4242
+
4243
+ rememberAccountBinding({
4244
+ runtimeConfig: boundRuntimeConfig,
4245
+ accountId,
4246
+ bindingSource: 'email_verification',
4247
+ });
4248
+
4249
+ const accountKey = resolveAccountBindingKey(boundRuntimeConfig, accountId);
4250
+ const currentRuntimeContext = accountRuntimeContexts.get(accountKey) || null;
4251
+ if (currentRuntimeContext) {
4252
+ accountRuntimeContexts.set(accountKey, {
4253
+ ...currentRuntimeContext,
4254
+ runtimeConfig: boundRuntimeConfig,
4255
+ deferredFailure: null,
4256
+ deferredErrorMessage: null,
4257
+ });
4258
+ }
4259
+
4260
+ const payload = verification && typeof verification === 'object' && !Array.isArray(verification)
4261
+ ? { ...verification }
4262
+ : {};
4263
+ delete payload.appToken;
4264
+ delete payload.credential;
4265
+ const credentialPersistence = projectRuntimeCredentialPersistence(persistence);
4266
+ return {
4267
+ ...payload,
4268
+ credentialPersistence,
4269
+ runtimeIdentity: {
4270
+ status: 'verified',
4271
+ agentId,
4272
+ created: verification?.created === true,
4273
+ recovered: verification?.recovered === true,
4274
+ bindingSource: 'email_verification',
4275
+ },
4276
+ runtimeBinding: {
4277
+ status: 'bound',
4278
+ accountId,
4279
+ agentId,
4280
+ bindingSource: 'email_verification',
4281
+ credentialPersistence,
4282
+ },
4283
+ };
4284
+ }
4285
+
4286
+ async function getRuntimeIdentityStatus(context = {}) {
4287
+ const configuredContext = resolveConfiguredRuntimeContext(context);
4288
+ const runtimeConfig = applyRuntimeIdentity(configuredContext.runtimeConfig);
4289
+ const agentId = normalizeClaworldText(
4290
+ context.agentId,
4291
+ normalizeClaworldText(runtimeConfig?.relay?.agentId, null),
4292
+ );
4293
+ if (!resolveRuntimeAppToken(runtimeConfig)) {
4294
+ return { emailVerified: false, reason: 'missing_app_token' };
4295
+ }
4296
+ if (!agentId) {
4297
+ return { emailVerified: false, reason: 'agent_id_required' };
4298
+ }
4299
+
4300
+ const accountView = await executeRuntimeAccountAction({
4301
+ runtimeConfig,
4302
+ agentId,
4303
+ action: 'view_account',
4304
+ generateShareCard: false,
4305
+ fetchImpl,
4306
+ });
4307
+ const account = accountView?.account && typeof accountView.account === 'object' && !Array.isArray(accountView.account)
4308
+ ? accountView.account
4309
+ : {};
4310
+ const emailVerified = account.emailVerified === true;
4311
+ return {
4312
+ emailVerified,
4313
+ email: normalizeClaworldText(account.email, null),
4314
+ verifiedAt: normalizeClaworldText(account.verifiedAt, null),
4315
+ reason: emailVerified ? null : 'no_email_identity',
4316
+ };
4317
+ }
4318
+
4085
4319
  async function updateRuntimeChatRequestApprovalPolicy(context = {}) {
4086
4320
  const resolvedContext = await resolveBoundRuntimeContext(context);
4087
4321
  return updateChatRequestApprovalPolicy({
@@ -4111,6 +4345,7 @@ async function generateRuntimeProfileCard(context = {}) {
4111
4345
  agentId: context.agentId || resolvedContext.agentId || null,
4112
4346
  generateShareCard: true,
4113
4347
  expiresInSeconds: context.expiresInSeconds ?? null,
4348
+ shareCardVariant: context.shareCardVariant ?? null,
4114
4349
  fetchImpl,
4115
4350
  });
4116
4351
  return result?.shareCard || {};
@@ -4383,6 +4618,7 @@ async function generateRuntimeProfileCard(context = {}) {
4383
4618
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
4384
4619
  generateShareCard: context.generateShareCard === true,
4385
4620
  expiresInSeconds: context.expiresInSeconds ?? null,
4621
+ shareCardVariant: context.shareCardVariant ?? null,
4386
4622
  fetchImpl,
4387
4623
  });
4388
4624
  },
@@ -4391,6 +4627,11 @@ async function generateRuntimeProfileCard(context = {}) {
4391
4627
  updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
4392
4628
  generateShareCard: generateRuntimeProfileCard,
4393
4629
  },
4630
+ identity: {
4631
+ startEmailVerification: startRuntimeEmailVerification,
4632
+ completeEmailVerification: completeRuntimeEmailVerification,
4633
+ getIdentityStatus: getRuntimeIdentityStatus,
4634
+ },
4394
4635
  postSetup: {
4395
4636
  fetchWorldDirectory: async (context = {}) => {
4396
4637
  const resolvedContext = await resolveBoundRuntimeContext(context);
@@ -4766,6 +5007,7 @@ async function generateRuntimeProfileCard(context = {}) {
4766
5007
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
4767
5008
  generateShareCard: context.generateShareCard === true,
4768
5009
  expiresInSeconds: context.expiresInSeconds ?? null,
5010
+ shareCardVariant: context.shareCardVariant ?? null,
4769
5011
  fetchImpl,
4770
5012
  });
4771
5013
  },
@@ -4774,6 +5016,11 @@ async function generateRuntimeProfileCard(context = {}) {
4774
5016
  updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
4775
5017
  generateShareCard: generateRuntimeProfileCard,
4776
5018
  },
5019
+ identity: {
5020
+ startEmailVerification: startRuntimeEmailVerification,
5021
+ completeEmailVerification: completeRuntimeEmailVerification,
5022
+ getIdentityStatus: getRuntimeIdentityStatus,
5023
+ },
4777
5024
  fetchWorldDirectory: async (context = {}) => {
4778
5025
  const resolvedContext = await resolveBoundRuntimeContext(context);
4779
5026
  return fetchPostSetupWorldDirectory({
@@ -7,7 +7,7 @@ import {
7
7
  CLAWORLD_TOOL_PROFILES,
8
8
  } from '../runtime/tool-inventory.js';
9
9
 
10
- export const DEFAULT_CLAWORLD_SERVER_URL = 'https://claworld.love';
10
+ export const DEFAULT_CLAWORLD_SERVER_URL = 'https://staging.claworld.love';
11
11
  export const DEFAULT_CLAWORLD_API_KEY = 'local-test';
12
12
  export const DEFAULT_CLAWORLD_AGENT_ID = 'main';
13
13
  export const DEFAULT_CLAWORLD_ACCOUNT_ID = 'claworld';
@@ -364,21 +364,33 @@ function buildManagedAccountEntry(options = {}) {
364
364
  };
365
365
  }
366
366
 
367
- if (!options.defaultTargetAgentId) {
367
+ const relay = {
368
+ ...(normalizeText(options.relayAgentId, null) ? { agentId: normalizeText(options.relayAgentId, null) } : {}),
369
+ ...(normalizeText(options.defaultTargetAgentId, null)
370
+ ? { defaultTargetAgentId: normalizeText(options.defaultTargetAgentId, null) }
371
+ : {}),
372
+ };
373
+ if (Object.keys(relay).length === 0) {
368
374
  return base;
369
375
  }
370
376
 
371
377
  return {
372
378
  ...base,
373
- relay: {
374
- defaultTargetAgentId: options.defaultTargetAgentId,
375
- },
379
+ relay,
376
380
  };
377
381
  }
378
382
 
379
383
  function buildMergedAccountEntry(existingAccount = {}, options = {}) {
380
384
  const existingRelay = ensureObject(existingAccount.relay);
381
385
  const existingRegistration = ensureObject(existingAccount.registration);
386
+ const relayAgentId = normalizeText(options.relayAgentId, null);
387
+ const defaultTargetAgentId = normalizeText(options.defaultTargetAgentId, null);
388
+ const mergedRelay = {
389
+ ...existingRelay,
390
+ ...(relayAgentId ? { agentId: relayAgentId } : {}),
391
+ ...(defaultTargetAgentId ? { defaultTargetAgentId } : {}),
392
+ };
393
+ const shouldPersistRelay = Boolean(existingAccount.relay || relayAgentId || defaultTargetAgentId);
382
394
  const merged = {
383
395
  ...existingAccount,
384
396
  enabled: true,
@@ -387,16 +399,7 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
387
399
  accountId: options.accountId,
388
400
  name: normalizeText(options.name, normalizeText(existingAccount.name, normalizeText(options.displayName, null))),
389
401
  routing: buildManagedRoutingEntry(options, existingAccount.routing),
390
- ...(options.defaultTargetAgentId
391
- ? {
392
- relay: {
393
- ...existingRelay,
394
- defaultTargetAgentId: options.defaultTargetAgentId,
395
- },
396
- }
397
- : existingAccount.relay
398
- ? { relay: existingRelay }
399
- : {}),
402
+ ...(shouldPersistRelay ? { relay: mergedRelay } : {}),
400
403
  };
401
404
  delete merged.toolProfile;
402
405
 
@@ -569,6 +572,7 @@ export function resolveClaworldManagedRuntimeOptions({
569
572
  registrationDisplayName,
570
573
  displayName,
571
574
  name,
575
+ relayAgentId: normalizeText(overrides.relayAgentId, normalizeText(existingAccount?.relay?.agentId, null)),
572
576
  defaultTargetAgentId: normalizeText(overrides.defaultTargetAgentId, null),
573
577
  sessionDmScope: normalizeText(
574
578
  overrides.sessionDmScope,