@xfxstudio/claworld 2026.6.10-testing.5 → 2026.6.26-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,46 +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),
1412
- },
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
- relay: {
1440
- ...(resolvedRuntimeConfig?.relay && typeof resolvedRuntimeConfig.relay === 'object' ? resolvedRuntimeConfig.relay : {}),
1441
- agentId: activatedAgentId,
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'],
1442
1417
  },
1443
1418
  });
1444
- resolvedAgentId = activatedAgentId;
1445
1419
  }
1446
1420
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1447
1421
  const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
@@ -1457,6 +1431,7 @@ async function updatePublicIdentity({
1457
1431
  action: 'update_identity',
1458
1432
  displayName: normalizedDisplayName,
1459
1433
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1434
+ ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1460
1435
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1461
1436
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
1462
1437
  : {}),
@@ -1475,9 +1450,9 @@ async function updatePublicIdentity({
1475
1450
  }
1476
1451
  return {
1477
1452
  ...(result.body || {}),
1478
- runtimeActivation: !resolveRuntimeAppToken(runtimeConfig)
1453
+ runtimeIdentity: !resolveRuntimeAppToken(runtimeConfig)
1479
1454
  ? {
1480
- status: 'activated',
1455
+ status: 'verified',
1481
1456
  agentId: resolvedAgentId,
1482
1457
  }
1483
1458
  : null,
@@ -1485,6 +1460,106 @@ async function updatePublicIdentity({
1485
1460
  };
1486
1461
  }
1487
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
+
1488
1563
  async function updateChatRequestApprovalPolicy({
1489
1564
  runtimeConfig,
1490
1565
  agentId = null,
@@ -1493,11 +1568,11 @@ async function updateChatRequestApprovalPolicy({
1493
1568
  }) {
1494
1569
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1495
1570
  throw createRuntimeBoundaryError({
1496
- code: 'claworld_account_unactivated',
1571
+ code: 'claworld_identity_unverified',
1497
1572
  category: 'conflict',
1498
1573
  status: 409,
1499
- message: 'claworld account must be activated before updating chat policy',
1500
- 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',
1501
1576
  recoverable: true,
1502
1577
  });
1503
1578
  }
@@ -1540,11 +1615,11 @@ async function updateGlobalProfile({
1540
1615
  }) {
1541
1616
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1542
1617
  throw createRuntimeBoundaryError({
1543
- code: 'claworld_account_unactivated',
1618
+ code: 'claworld_identity_unverified',
1544
1619
  category: 'conflict',
1545
1620
  status: 409,
1546
- message: 'claworld account must be activated before updating profile',
1547
- 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',
1548
1623
  recoverable: true,
1549
1624
  });
1550
1625
  }
@@ -1689,15 +1764,16 @@ async function executeRuntimeAccountAction({
1689
1764
  proactivitySettings = undefined,
1690
1765
  generateShareCard = false,
1691
1766
  expiresInSeconds = null,
1767
+ shareCardVariant = null,
1692
1768
  fetchImpl,
1693
1769
  }) {
1694
1770
  if (!resolveRuntimeAppToken(runtimeConfig)) {
1695
1771
  throw createRuntimeBoundaryError({
1696
- code: 'claworld_account_unactivated',
1772
+ code: 'claworld_identity_unverified',
1697
1773
  category: 'conflict',
1698
1774
  status: 409,
1699
- message: 'claworld account must be activated before managing account settings',
1700
- 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',
1701
1777
  recoverable: true,
1702
1778
  });
1703
1779
  }
@@ -1723,6 +1799,7 @@ async function executeRuntimeAccountAction({
1723
1799
  ...(chatRequestApprovalPolicy ? { chatRequestApprovalPolicy } : {}),
1724
1800
  ...(proactivitySettings !== undefined ? { proactivitySettings } : {}),
1725
1801
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1802
+ ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1726
1803
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1727
1804
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
1728
1805
  : {}),
@@ -3242,14 +3319,27 @@ export function createClaworldChannelPlugin({
3242
3319
  }
3243
3320
 
3244
3321
  function mergeBoundRuntimeConfig(currentRuntimeConfig = {}, boundRuntimeConfig = {}) {
3322
+ const currentRelay = currentRuntimeConfig?.relay && typeof currentRuntimeConfig.relay === 'object'
3323
+ ? currentRuntimeConfig.relay
3324
+ : {};
3325
+ const boundRelay = boundRuntimeConfig?.relay && typeof boundRuntimeConfig.relay === 'object'
3326
+ ? boundRuntimeConfig.relay
3327
+ : {};
3328
+ const appToken = resolveRuntimeAppToken(currentRuntimeConfig) || resolveRuntimeAppToken(boundRuntimeConfig);
3329
+ const agentId = normalizeClaworldText(currentRelay.agentId, normalizeClaworldText(boundRelay.agentId, null));
3330
+
3245
3331
  return applyRuntimeIdentity({
3246
- ...currentRuntimeConfig,
3247
3332
  ...boundRuntimeConfig,
3333
+ ...currentRuntimeConfig,
3334
+ appToken,
3248
3335
  relay: {
3249
- ...(currentRuntimeConfig?.relay && typeof currentRuntimeConfig.relay === 'object' ? currentRuntimeConfig.relay : {}),
3250
- ...(boundRuntimeConfig?.relay && typeof boundRuntimeConfig.relay === 'object' ? boundRuntimeConfig.relay : {}),
3336
+ ...boundRelay,
3337
+ ...currentRelay,
3338
+ appToken,
3339
+ credentialToken: appToken,
3340
+ agentId,
3251
3341
  },
3252
- });
3342
+ }, { appToken, agentId });
3253
3343
  }
3254
3344
 
3255
3345
  function rememberAccountBinding({ runtimeConfig, accountId = null, bindingSource = 'binding_cache', relayAgent = null }) {
@@ -3270,10 +3360,14 @@ export function createClaworldChannelPlugin({
3270
3360
  const cachedState = accountBindingStates.get(accountKey) || null;
3271
3361
  const cachedBinding = cachedState?.binding || null;
3272
3362
 
3363
+ const normalizedAppToken = resolveRuntimeAppToken(normalizedRuntimeConfig);
3364
+ const cachedAppToken = resolveRuntimeAppToken(cachedBinding?.runtimeConfig || {});
3365
+
3273
3366
  if (
3274
3367
  cachedBinding
3275
3368
  && cachedBinding.runtimeConfig?.serverUrl
3276
3369
  && cachedBinding.runtimeConfig.serverUrl === normalizedRuntimeConfig.serverUrl
3370
+ && (!normalizedAppToken || cachedAppToken === normalizedAppToken)
3277
3371
  ) {
3278
3372
  return {
3279
3373
  ...cachedBinding,
@@ -3488,7 +3582,7 @@ export function createClaworldChannelPlugin({
3488
3582
  method: 'loadConfig_writeConfigFile',
3489
3583
  };
3490
3584
  if (!mutationOutcome.skipped) {
3491
- await runtime.config.writeConfigFile(nextCfg);
3585
+ await runtime.config.writeConfigFile(nextCfg, { afterWrite: { mode: 'auto' } });
3492
3586
  }
3493
3587
  }
3494
3588
  } catch (error) {
@@ -3972,11 +4066,12 @@ export function createClaworldChannelPlugin({
3972
4066
  agentId: resolvedContext.agentId || null,
3973
4067
  generateShareCard: context.generateShareCard === true,
3974
4068
  expiresInSeconds: context.expiresInSeconds ?? null,
4069
+ shareCardVariant: context.shareCardVariant ?? null,
3975
4070
  fetchImpl,
3976
4071
  });
3977
4072
  }
3978
4073
 
3979
- async function updateRuntimePublicIdentity(context = {}) {
4074
+ async function updateRuntimePublicIdentity(context = {}) {
3980
4075
  const configuredContext = resolveConfiguredRuntimeContext(context);
3981
4076
  const resolvedContext = await resolveBoundRuntimeContext(context);
3982
4077
  const updateResult = await updatePublicIdentity({
@@ -3985,17 +4080,18 @@ async function updateRuntimePublicIdentity(context = {}) {
3985
4080
  displayName: context.displayName || null,
3986
4081
  generateShareCard: context.generateShareCard !== false,
3987
4082
  expiresInSeconds: context.expiresInSeconds ?? null,
4083
+ shareCardVariant: context.shareCardVariant ?? null,
3988
4084
  fetchImpl,
3989
4085
  });
3990
4086
 
3991
- const runtimeActivation = updateResult?.runtimeActivation && typeof updateResult.runtimeActivation === 'object'
3992
- ? updateResult.runtimeActivation
4087
+ const runtimeIdentity = updateResult?.runtimeIdentity && typeof updateResult.runtimeIdentity === 'object'
4088
+ ? updateResult.runtimeIdentity
3993
4089
  : null;
3994
4090
  const nextRuntimeConfig = updateResult?.runtimeConfig && typeof updateResult.runtimeConfig === 'object'
3995
4091
  ? updateResult.runtimeConfig
3996
4092
  : resolvedContext.runtimeConfig;
3997
4093
  const nextAgentId = normalizeClaworldText(
3998
- runtimeActivation?.agentId,
4094
+ runtimeIdentity?.agentId,
3999
4095
  normalizeClaworldText(
4000
4096
  updateResult?.agentId,
4001
4097
  null,
@@ -4018,7 +4114,7 @@ async function updateRuntimePublicIdentity(context = {}) {
4018
4114
  nextAppToken
4019
4115
  && nextAgentId
4020
4116
  && (
4021
- runtimeActivation
4117
+ runtimeIdentity
4022
4118
  || configuredAppToken !== nextAppToken
4023
4119
  || previousAgentId !== nextAgentId
4024
4120
  ),
@@ -4035,7 +4131,7 @@ async function updateRuntimePublicIdentity(context = {}) {
4035
4131
  runtimeConfig: boundRuntimeConfig,
4036
4132
  });
4037
4133
  } catch (error) {
4038
- logger.warn?.('[claworld:profile] failed to persist activated runtime binding', {
4134
+ logger.warn?.('[claworld:profile] failed to persist verified runtime binding', {
4039
4135
  accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
4040
4136
  error: error?.message || String(error),
4041
4137
  });
@@ -4044,8 +4140,8 @@ async function updateRuntimePublicIdentity(context = {}) {
4044
4140
  rememberAccountBinding({
4045
4141
  runtimeConfig: boundRuntimeConfig,
4046
4142
  accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
4047
- bindingSource: runtimeActivation
4048
- ? 'activated_app_token'
4143
+ bindingSource: runtimeIdentity
4144
+ ? 'verified_app_token'
4049
4145
  : (resolvedContext.bindingSource || 'configured_app_token'),
4050
4146
  });
4051
4147
 
@@ -4068,6 +4164,158 @@ async function updateRuntimePublicIdentity(context = {}) {
4068
4164
  return payload;
4069
4165
  }
4070
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
+
4071
4319
  async function updateRuntimeChatRequestApprovalPolicy(context = {}) {
4072
4320
  const resolvedContext = await resolveBoundRuntimeContext(context);
4073
4321
  return updateChatRequestApprovalPolicy({
@@ -4097,6 +4345,7 @@ async function generateRuntimeProfileCard(context = {}) {
4097
4345
  agentId: context.agentId || resolvedContext.agentId || null,
4098
4346
  generateShareCard: true,
4099
4347
  expiresInSeconds: context.expiresInSeconds ?? null,
4348
+ shareCardVariant: context.shareCardVariant ?? null,
4100
4349
  fetchImpl,
4101
4350
  });
4102
4351
  return result?.shareCard || {};
@@ -4369,6 +4618,7 @@ async function generateRuntimeProfileCard(context = {}) {
4369
4618
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
4370
4619
  generateShareCard: context.generateShareCard === true,
4371
4620
  expiresInSeconds: context.expiresInSeconds ?? null,
4621
+ shareCardVariant: context.shareCardVariant ?? null,
4372
4622
  fetchImpl,
4373
4623
  });
4374
4624
  },
@@ -4377,6 +4627,11 @@ async function generateRuntimeProfileCard(context = {}) {
4377
4627
  updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
4378
4628
  generateShareCard: generateRuntimeProfileCard,
4379
4629
  },
4630
+ identity: {
4631
+ startEmailVerification: startRuntimeEmailVerification,
4632
+ completeEmailVerification: completeRuntimeEmailVerification,
4633
+ getIdentityStatus: getRuntimeIdentityStatus,
4634
+ },
4380
4635
  postSetup: {
4381
4636
  fetchWorldDirectory: async (context = {}) => {
4382
4637
  const resolvedContext = await resolveBoundRuntimeContext(context);
@@ -4752,6 +5007,7 @@ async function generateRuntimeProfileCard(context = {}) {
4752
5007
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
4753
5008
  generateShareCard: context.generateShareCard === true,
4754
5009
  expiresInSeconds: context.expiresInSeconds ?? null,
5010
+ shareCardVariant: context.shareCardVariant ?? null,
4755
5011
  fetchImpl,
4756
5012
  });
4757
5013
  },
@@ -4760,6 +5016,11 @@ async function generateRuntimeProfileCard(context = {}) {
4760
5016
  updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
4761
5017
  generateShareCard: generateRuntimeProfileCard,
4762
5018
  },
5019
+ identity: {
5020
+ startEmailVerification: startRuntimeEmailVerification,
5021
+ completeEmailVerification: completeRuntimeEmailVerification,
5022
+ getIdentityStatus: getRuntimeIdentityStatus,
5023
+ },
4763
5024
  fetchWorldDirectory: async (context = {}) => {
4764
5025
  const resolvedContext = await resolveBoundRuntimeContext(context);
4765
5026
  return fetchPostSetupWorldDirectory({