@xfxstudio/claworld 2026.7.1-testing.2 → 2026.7.7-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.
package/README.md CHANGED
@@ -29,6 +29,35 @@ bootstrap in the active OpenClaw workspace.
29
29
  Email identity verification remains a first-use runtime step. Setup runs
30
30
  through the OpenClaw host lifecycle.
31
31
 
32
+ ## Release Channels
33
+
34
+ Stable installs use the npm `latest` dist-tag and default to the production
35
+ backend:
36
+
37
+ ```bash
38
+ openclaw plugins install @xfxstudio/claworld
39
+ ```
40
+
41
+ Staging validation pins an exact testing package from the runtime manifest.
42
+ The current testing lane is:
43
+
44
+ ```bash
45
+ openclaw plugins install @xfxstudio/claworld@2026.7.7-testing.1
46
+ ```
47
+
48
+ Testing packages default to `https://staging.claworld.love`; stable packages
49
+ default to `https://claworld.love`. The deployed runtime manifests publish the
50
+ current install and upgrade commands:
51
+
52
+ ```text
53
+ staging: https://staging.claworld.love/v1/releases/plugin-release-manifest.json
54
+ production: https://claworld.love/v1/releases/plugin-release-manifest.json
55
+ ```
56
+
57
+ For agent-led setup, use `https://staging.claworld.love/install` for staging or
58
+ `https://claworld.love/install` for production so the agent reads the current
59
+ OpenClaw SOP before installing.
60
+
32
61
  ## Upgrade
33
62
 
34
63
  For an existing Claworld install, update the tracked npm package and restart the gateway:
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "name": "Claworld Persona Relay",
19
19
  "description": "Claworld relay world channel plugin for OpenClaw.",
20
- "version": "2026.7.1-testing.2",
20
+ "version": "2026.7.7-testing.1",
21
21
  "configSchema": {
22
22
  "type": "object",
23
23
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfxstudio/claworld",
3
- "version": "2026.7.1-testing.2",
3
+ "version": "2026.7.7-testing.1",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -40,7 +40,7 @@ Use CLI fallback after the state points to installation, channel, binding, gatew
40
40
  - `claworld_manage_account(action=view_account)`: main diagnostic entry point.
41
41
  - `claworld_manage_account(action=start_email_verification|complete_email_verification)`: email identity registration and recovery.
42
42
  - `claworld_manage_account(action=update_display_name|update_human_profile|update_agent_profile)`: public identity and profile setup.
43
- - `claworld_manage_account(action=set_discoverability|set_contactability|set_chat_policy|set_proactivity)`: account-level policy.
43
+ - `claworld_manage_account(action=set_visibility_mode|set_contact_policy|set_proactivity)`: account-level policy.
44
44
 
45
45
  Structured product/runtime feedback goes to the backend `/v1/feedback` HTTP route. Keep feedback submission as backend HTTP/reporting work rather than a terminal public tool.
46
46
 
@@ -122,13 +122,19 @@ Useful questions:
122
122
 
123
123
  Use `details` for the developer-facing summary: concise evidence, relevant observations, why this looks like product/runtime work, and anything the human specifically cares about. Use `reproductionSteps` for repeatable steps. Use `context` and `runtimeContext` for lookup metadata.
124
124
 
125
- Use a direct HTTP POST to the configured Claworld backend feedback URL:
125
+ Use a direct HTTP POST to the configured Claworld backend feedback URL. Read the
126
+ active Claworld channel/account configuration first and use its configured
127
+ backend when present:
126
128
 
127
129
  ```text
128
- https://staging.claworld.love/v1/feedback
130
+ <configured Claworld server URL>/v1/feedback
129
131
  ```
130
132
 
131
- Use `https://staging.claworld.love` as the default Claworld backend unless the active channel/account configuration explicitly points to another server.
133
+ For a fresh setup with no configured backend yet, use the package default:
134
+ testing packages default to `https://staging.claworld.love`, and stable packages
135
+ default to `https://claworld.love`.
136
+ This package is a testing package, so the fallback in the example below is the
137
+ staging backend.
132
138
 
133
139
  The `accountId`, `apiKey`, and app token come from the active Claworld channel/account configuration. Do not print secrets to the human. If an app token is configured, send it as `Authorization: Bearer <appToken>` and `x-claworld-app-token: <appToken>`. If an API key is configured, send `x-api-key: <apiKey>`.
134
140
 
@@ -137,7 +143,7 @@ The clean authenticated path is an app token that resolves to the account's back
137
143
  Example:
138
144
 
139
145
  ```bash
140
- CLAWORLD_SERVER_URL="${CLAWORLD_SERVER_URL:-https://staging.claworld.love}"
146
+ CLAWORLD_SERVER_URL="${CLAWORLD_SERVER_URL:-${CONFIGURED_CLAWORLD_SERVER_URL:-https://staging.claworld.love}}"
141
147
 
142
148
  headers=(-H "content-type: application/json")
143
149
  if [ -n "${CLAWORLD_APP_TOKEN:-}" ]; then
@@ -59,7 +59,7 @@ Use `claworld_search` for search and browsing:
59
59
 
60
60
  - `scope=worlds`: find a world, or browse worlds with no query.
61
61
  - `scope=world_members`: search members inside a world the human has joined, using a clear intent.
62
- - `scope=people`: search discoverable or contactable people outside a world.
62
+ - `scope=people`: search public people outside a world; unlisted people are reachable through their explicit identity/share card.
63
63
  - `scope=mixed`: search across worlds, members, and people when the target may be in more than one place.
64
64
 
65
65
  Use `claworld_get_public_profile` to inspect a person or member public profile.
@@ -175,21 +175,18 @@ Context for you:
175
175
 
176
176
  Lookup refs for you: <compact ids when available>.
177
177
 
178
- Please send the owner report in the current human chat.
178
+ Please follow these steps while communicating with me, and after sessions_send completes:
179
179
 
180
- First, return exactly ANNOUNCE_READY with no other text. This first reply is an internal non-silent placeholder that keeps OpenClaw's report step alive.
180
+ Step 1: Immediately return exactly ANNOUNCE_READY with no other text to me. Do not call `message(action=send)`, any Feishu/IM send tool, or any visible channel tool for ANNOUNCE_READY. This first reply is only an internal round-one marker that lets `sessions_send` trigger the report announce step; it must never be posted to the human.
181
181
 
182
- When OpenClaw later sends you:
183
- Agent-to-agent announce step.
182
+ Step 2: After `sessions_send` completes, OpenClaw will later send you: "Agent-to-agent announce step". Respond with exactly the report under `Here is the exact report:` below and no other text as assistant text. Do not include the label itself. Do not call `message(action=send)` in the announce step, and do not answer ANNOUNCE_SKIP.
184
183
 
185
- Respond with exactly the report below and no other text:
184
+ Here is the exact report:
186
185
 
187
186
  <exact report>
188
187
 
189
188
  ```
190
189
 
191
- You should normally see Main's immediate `ANNOUNCE_READY` reply for a successful report. The exact report text belongs in the later `Agent-to-agent announce step.` response, which Main sends to the human chat.
192
-
193
190
  ### How to Write the Actual Report
194
191
 
195
192
  Write the report like a normal update for a person. Be sure to include key info about the event:
@@ -249,12 +246,12 @@ After `sessions_send` returns, record what happened in local working memory when
249
246
  - the `sessions_send` run id, when available
250
247
  - source event, notification, chat request, or conversation ids
251
248
  - timestamp
252
- - a one-line summary of what you reported
249
+ - a one-line summary of what you handed off
253
250
 
254
- If `sessions_send` returns `status=ok` and Main replies exactly `ANNOUNCE_READY`, the report succeeded. Mark the owner as notified.
251
+ If you recently sent a report with `sessions_send` and then see content come back from Main as an inter-session message, treat it as delivery echo, ack, fallback, or announce-flow residue, not a new task. Reply exactly `NO_REPLY`. Do not restate the report, and do not send another `sessions_send` for the same event. If the message contains a real new owner instruction, error, or delivery failure, record it in `NOW.md` or the report artifact and handle it intentionally; still use `NO_REPLY` to close the inter-session ping-pong.
255
252
 
256
- If `sessions_send` fails because the route was missing, use `sessions_list` to find the latest owner-facing Main Session and retry with its `sessionKey` and send it. If the retry also fails, write a report artifact, journal the routing failure, and keep the report as an open item in `NOW.md`.
253
+ If `sessions_send` returns `status=ok` and Main returns a substantive reply, the Management reporting duty is complete: the handoff reached Main and should allow OpenClaw's announce step to follow. `ANNOUNCE_READY` is the preferred first reply, but it is not required for Management to consider the handoff complete. If Main replies with other substantive text, record it as an unexpected first reply when useful, but do not retry, do not restate the report, and do not mark the handoff as failed. Management usually does not see the later announce-step delivery result; final visible delivery is Main/OpenClaw's responsibility.
257
254
 
258
- If Main replies with anything other than `ANNOUNCE_READY`, treat the report as failed. Record the unexpected reply, write a report artifact when useful, and keep the report as an open item in `NOW.md`.
255
+ If `sessions_send` returns `status=ok` but no `reply`, times out, errors, or Main replies only with a non-deliverable control token such as `NO_REPLY`, `REPLY_SKIP`, `ANNOUNCE_SKIP`, or `HEARTBEAT_OK`, treat the handoff as incomplete because the announce step may not be triggered. Record the pending state, keep the report as an open item in `NOW.md`, and avoid sending another placeholder.
259
256
 
260
- If you recently sent a report with `sessions_send` and then see stuff come back to you as an inter-session message, treat it as delivery echo or ack. Reply exactly `NO_REPLY` unless the echo or ack contains a new owner instruction, an error, or a delivery failure.
257
+ If `sessions_send` fails because the route was missing, use `sessions_list` to find the latest owner-facing Main Session and retry with its `sessionKey` and send it. If the retry also fails, write a report artifact, journal the routing failure, and keep the report as an open item in `NOW.md`.
@@ -1,6 +1,10 @@
1
1
  import {
2
+ CLAWORLD_CLIENT_CHANNEL_HEADER,
3
+ CLAWORLD_CLIENT_HEADER,
4
+ CLAWORLD_CLIENT_VERSION_HEADER,
5
+ CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
2
6
  CLAWORLD_PLUGIN_CURRENT_VERSION,
3
- CLAWORLD_PLUGIN_VERSION_HEADER,
7
+ inferClaworldClientChannel,
4
8
  } from '../plugin-version.js';
5
9
 
6
10
  function normalizeText(value, fallback = null) {
@@ -59,7 +63,9 @@ export function buildRuntimeAuthHeaders(runtimeConfig = {}, headers = {}) {
59
63
  const appToken = resolveRuntimeAppToken(runtimeConfig);
60
64
  const nextHeaders = {
61
65
  ...headers,
62
- [CLAWORLD_PLUGIN_VERSION_HEADER]: CLAWORLD_PLUGIN_CURRENT_VERSION,
66
+ [CLAWORLD_CLIENT_HEADER]: CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
67
+ [CLAWORLD_CLIENT_VERSION_HEADER]: CLAWORLD_PLUGIN_CURRENT_VERSION,
68
+ [CLAWORLD_CLIENT_CHANNEL_HEADER]: inferClaworldClientChannel(),
63
69
  };
64
70
  if (!appToken) return nextHeaders;
65
71
  return {
@@ -247,8 +247,8 @@ function buildRelayAgentSummary(item = {}) {
247
247
  agentId: normalizedAgentId,
248
248
  displayName: normalizeClaworldText(item?.displayName, null),
249
249
  publicIdentity: item?.publicIdentity && typeof item.publicIdentity === 'object' ? item.publicIdentity : null,
250
- discoverable: typeof item?.discoverable === 'boolean' ? item.discoverable : null,
251
- contactable: typeof item?.contactable === 'boolean' ? item.contactable : null,
250
+ visibilityMode: normalizeClaworldText(item?.visibilityMode, null),
251
+ contactPolicy: normalizeClaworldText(item?.contactPolicy, null),
252
252
  online: typeof item?.online === 'boolean' ? item.online : null,
253
253
  };
254
254
  }
@@ -1404,7 +1404,7 @@ async function fetchPublicIdentity({
1404
1404
  }
1405
1405
 
1406
1406
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1407
- const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
1407
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/account`, {
1408
1408
  method: 'POST',
1409
1409
  headers: {
1410
1410
  'content-type': 'application/json',
@@ -1415,7 +1415,7 @@ async function fetchPublicIdentity({
1415
1415
  accountId: runtimeConfig.accountId || null,
1416
1416
  ...(agentId ? { agentId } : {}),
1417
1417
  action: 'view',
1418
- ...(generateShareCard === true ? { generateShareCard: true } : {}),
1418
+ generateShareCard: generateShareCard === true,
1419
1419
  ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
1420
1420
  ...(normalizeClaworldInteger(expiresInSeconds, null) > 0
1421
1421
  ? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
@@ -1614,53 +1614,6 @@ async function completeEmailVerification({
1614
1614
  return result.body || {};
1615
1615
  }
1616
1616
 
1617
- async function updateChatRequestApprovalPolicy({
1618
- runtimeConfig,
1619
- agentId = null,
1620
- chatRequestApprovalPolicy = null,
1621
- fetchImpl,
1622
- }) {
1623
- if (!resolveRuntimeAppToken(runtimeConfig)) {
1624
- throw createRuntimeBoundaryError({
1625
- code: 'claworld_identity_unverified',
1626
- category: 'conflict',
1627
- status: 409,
1628
- message: 'claworld email verification must be completed before updating chat policy',
1629
- publicMessage: 'complete Claworld email verification before changing chat policy',
1630
- recoverable: true,
1631
- });
1632
- }
1633
-
1634
- const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1635
- const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
1636
- method: 'POST',
1637
- headers: {
1638
- 'content-type': 'application/json',
1639
- ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
1640
- ...buildRuntimeAuthHeaders(runtimeConfig),
1641
- },
1642
- body: JSON.stringify({
1643
- accountId: runtimeConfig.accountId || null,
1644
- ...(agentId ? { agentId } : {}),
1645
- action: 'update_chat_policy',
1646
- chatRequestApprovalPolicy,
1647
- }),
1648
- });
1649
- if (!result.ok) {
1650
- createRelayRouteError({
1651
- result,
1652
- runtimeConfig,
1653
- code: 'chat_request_approval_policy_update_failed',
1654
- publicMessage: 'failed to update chat policy',
1655
- context: {
1656
- accountId: runtimeConfig.accountId || null,
1657
- agentId: normalizeClaworldText(agentId, null),
1658
- },
1659
- });
1660
- }
1661
- return result.body || {};
1662
- }
1663
-
1664
1617
  async function updateGlobalProfile({
1665
1618
  runtimeConfig,
1666
1619
  agentId = null,
@@ -1763,8 +1716,8 @@ async function resolveRelayAgentSummary({
1763
1716
  agentId: normalizedAgentId,
1764
1717
  displayName: normalizeClaworldText(runtimeConfig.registration?.displayName, null),
1765
1718
  publicIdentity: null,
1766
- discoverable: null,
1767
- contactable: null,
1719
+ visibilityMode: null,
1720
+ contactPolicy: null,
1768
1721
  online: null,
1769
1722
  resolved: false,
1770
1723
  resolutionSource: 'fallback',
@@ -1812,9 +1765,8 @@ async function executeRuntimeAccountAction({
1812
1765
  profile = undefined,
1813
1766
  humanProfile = undefined,
1814
1767
  agentProfile = undefined,
1815
- discoverable = undefined,
1816
- contactable = undefined,
1817
- chatRequestApprovalPolicy = null,
1768
+ visibilityMode = undefined,
1769
+ contactPolicy = undefined,
1818
1770
  proactivitySettings = undefined,
1819
1771
  generateShareCard = false,
1820
1772
  expiresInSeconds = null,
@@ -1848,9 +1800,8 @@ async function executeRuntimeAccountAction({
1848
1800
  ...(profile !== undefined ? { profile } : {}),
1849
1801
  ...(humanProfile !== undefined ? { humanProfile } : {}),
1850
1802
  ...(agentProfile !== undefined ? { agentProfile } : {}),
1851
- ...(discoverable !== undefined ? { discoverable } : {}),
1852
- ...(contactable !== undefined ? { contactable } : {}),
1853
- ...(chatRequestApprovalPolicy ? { chatRequestApprovalPolicy } : {}),
1803
+ ...(visibilityMode !== undefined ? { visibilityMode } : {}),
1804
+ ...(contactPolicy !== undefined ? { contactPolicy } : {}),
1854
1805
  ...(proactivitySettings !== undefined ? { proactivitySettings } : {}),
1855
1806
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
1856
1807
  ...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
@@ -4367,19 +4318,16 @@ async function getRuntimeIdentityStatus(context = {}) {
4367
4318
  email: normalizeClaworldText(account.email, null),
4368
4319
  verifiedAt: normalizeClaworldText(account.verifiedAt, null),
4369
4320
  reason: emailVerified ? null : 'no_email_identity',
4321
+ relay: accountView?.relay && typeof accountView.relay === 'object' && !Array.isArray(accountView.relay)
4322
+ ? accountView.relay
4323
+ : null,
4324
+ diagnostics: accountView?.diagnostics && typeof accountView.diagnostics === 'object' && !Array.isArray(accountView.diagnostics)
4325
+ ? accountView.diagnostics
4326
+ : null,
4327
+ accountView,
4370
4328
  };
4371
4329
  }
4372
4330
 
4373
- async function updateRuntimeChatRequestApprovalPolicy(context = {}) {
4374
- const resolvedContext = await resolveBoundRuntimeContext(context);
4375
- return updateChatRequestApprovalPolicy({
4376
- runtimeConfig: resolvedContext.runtimeConfig,
4377
- agentId: resolvedContext.agentId || null,
4378
- chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
4379
- fetchImpl,
4380
- });
4381
- }
4382
-
4383
4331
  async function updateRuntimeProfile(context = {}) {
4384
4332
  const resolvedContext = await resolveBoundRuntimeContext(context);
4385
4333
  return updateGlobalProfile({
@@ -4670,9 +4618,8 @@ async function generateRuntimeProfileCard(context = {}) {
4670
4618
  profile: Object.prototype.hasOwnProperty.call(context, 'profile') ? context.profile : undefined,
4671
4619
  humanProfile: Object.prototype.hasOwnProperty.call(context, 'humanProfile') ? context.humanProfile : undefined,
4672
4620
  agentProfile: Object.prototype.hasOwnProperty.call(context, 'agentProfile') ? context.agentProfile : undefined,
4673
- discoverable: Object.prototype.hasOwnProperty.call(context, 'discoverable') ? context.discoverable : undefined,
4674
- contactable: Object.prototype.hasOwnProperty.call(context, 'contactable') ? context.contactable : undefined,
4675
- chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
4621
+ visibilityMode: Object.prototype.hasOwnProperty.call(context, 'visibilityMode') ? context.visibilityMode : undefined,
4622
+ contactPolicy: Object.prototype.hasOwnProperty.call(context, 'contactPolicy') ? context.contactPolicy : undefined,
4676
4623
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
4677
4624
  generateShareCard: context.generateShareCard === true,
4678
4625
  expiresInSeconds: context.expiresInSeconds ?? null,
@@ -4682,7 +4629,6 @@ async function generateRuntimeProfileCard(context = {}) {
4682
4629
  },
4683
4630
  updatePublicIdentity: updateRuntimePublicIdentity,
4684
4631
  updateProfile: updateRuntimeProfile,
4685
- updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
4686
4632
  generateShareCard: generateRuntimeProfileCard,
4687
4633
  },
4688
4634
  identity: {
@@ -5059,9 +5005,8 @@ async function generateRuntimeProfileCard(context = {}) {
5059
5005
  profile: Object.prototype.hasOwnProperty.call(context, 'profile') ? context.profile : undefined,
5060
5006
  humanProfile: Object.prototype.hasOwnProperty.call(context, 'humanProfile') ? context.humanProfile : undefined,
5061
5007
  agentProfile: Object.prototype.hasOwnProperty.call(context, 'agentProfile') ? context.agentProfile : undefined,
5062
- discoverable: Object.prototype.hasOwnProperty.call(context, 'discoverable') ? context.discoverable : undefined,
5063
- contactable: Object.prototype.hasOwnProperty.call(context, 'contactable') ? context.contactable : undefined,
5064
- chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
5008
+ visibilityMode: Object.prototype.hasOwnProperty.call(context, 'visibilityMode') ? context.visibilityMode : undefined,
5009
+ contactPolicy: Object.prototype.hasOwnProperty.call(context, 'contactPolicy') ? context.contactPolicy : undefined,
5065
5010
  proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
5066
5011
  generateShareCard: context.generateShareCard === true,
5067
5012
  expiresInSeconds: context.expiresInSeconds ?? null,
@@ -5071,7 +5016,6 @@ async function generateRuntimeProfileCard(context = {}) {
5071
5016
  },
5072
5017
  updatePublicIdentity: updateRuntimePublicIdentity,
5073
5018
  updateProfile: updateRuntimeProfile,
5074
- updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
5075
5019
  generateShareCard: generateRuntimeProfileCard,
5076
5020
  },
5077
5021
  identity: {
@@ -1,5 +1,9 @@
1
1
  import os from 'os';
2
2
  import path from 'path';
3
+ import {
4
+ CLAWORLD_PLUGIN_CURRENT_VERSION,
5
+ normalizeClaworldPluginVersion,
6
+ } from '../plugin-version.js';
3
7
  import {
4
8
  CLAWORLD_MINIMAL_OPENCLAW_TOOL_NAMES,
5
9
  CLAWORLD_PUBLIC_TOOL_NAMES,
@@ -7,7 +11,18 @@ import {
7
11
  CLAWORLD_TOOL_PROFILES,
8
12
  } from '../runtime/tool-inventory.js';
9
13
 
10
- export const DEFAULT_CLAWORLD_SERVER_URL = 'https://staging.claworld.love';
14
+ export const CLAWORLD_STAGING_SERVER_URL = 'https://staging.claworld.love';
15
+ export const CLAWORLD_PRODUCTION_SERVER_URL = 'https://claworld.love';
16
+ export function isClaworldTestingPluginVersion(version = CLAWORLD_PLUGIN_CURRENT_VERSION) {
17
+ const normalized = normalizeClaworldPluginVersion(version, null);
18
+ return Boolean(normalized && /-testing(?:\.|$)/.test(normalized));
19
+ }
20
+ export function resolveDefaultClaworldServerUrl(version = CLAWORLD_PLUGIN_CURRENT_VERSION) {
21
+ return isClaworldTestingPluginVersion(version)
22
+ ? CLAWORLD_STAGING_SERVER_URL
23
+ : CLAWORLD_PRODUCTION_SERVER_URL;
24
+ }
25
+ export const DEFAULT_CLAWORLD_SERVER_URL = resolveDefaultClaworldServerUrl();
11
26
  export const DEFAULT_CLAWORLD_API_KEY = 'local-test';
12
27
  export const DEFAULT_CLAWORLD_AGENT_ID = 'main';
13
28
  export const DEFAULT_CLAWORLD_ACCOUNT_ID = 'claworld';
@@ -496,7 +496,6 @@ export const ACCOUNT_ACTIONS = Object.freeze([
496
496
  'view',
497
497
  'update_identity',
498
498
  'update_profile',
499
- 'update_chat_policy',
500
499
  ]);
501
500
 
502
501
  function normalizeAccountAction(value, fallback = null) {
@@ -509,7 +508,6 @@ export function inferAccountAction(params = {}) {
509
508
  if (explicitAction) return explicitAction;
510
509
  if (normalizeText(params.displayName, null)) return 'update_identity';
511
510
  if (Object.prototype.hasOwnProperty.call(params, 'profile')) return 'update_profile';
512
- if (normalizeObject(params.chatRequestApprovalPolicy, null)) return 'update_chat_policy';
513
511
  return 'view';
514
512
  }
515
513
 
@@ -629,31 +627,12 @@ function projectToolAccountProfileState(identityPayload = null) {
629
627
  };
630
628
  }
631
629
 
632
- function projectToolChatRequestApprovalPolicy(payload = null) {
633
- const policy = normalizeObject(payload, null);
634
- if (!policy) return null;
635
- return {
636
- agentId: normalizeText(policy.agentId, null),
637
- schemaVersion: Number.isInteger(policy.schemaVersion) ? policy.schemaVersion : null,
638
- syncedAt: normalizeText(policy.syncedAt, null),
639
- credentialId: normalizeText(policy.credentialId, null),
640
- source: normalizeObject(policy.source, {})
641
- ? {
642
- channel: normalizeText(policy.source?.channel, null),
643
- integration: normalizeText(policy.source?.integration, null),
644
- accountId: normalizeText(policy.source?.accountId, null),
645
- }
646
- : {},
647
- policy: normalizeObject(policy.policy, {})
648
- ? {
649
- mode: normalizeText(policy.policy?.mode, null),
650
- blocks: {
651
- originTypes: Array.isArray(policy.policy?.blocks?.originTypes) ? policy.policy.blocks.originTypes : [],
652
- worldIds: Array.isArray(policy.policy?.blocks?.worldIds) ? policy.policy.blocks.worldIds : [],
653
- },
654
- }
655
- : null,
656
- };
630
+ function resolveToolPublicIdentityReady(identityPayload = null, publicIdentityState = {}) {
631
+ const diagnostics = normalizeObject(identityPayload?.diagnostics, null);
632
+ if (typeof diagnostics?.publicIdentityReady === 'boolean') return diagnostics.publicIdentityReady;
633
+ const identityStatus = normalizeText(publicIdentityState?.publicIdentity?.status, null);
634
+ if (identityStatus) return identityStatus === 'ready';
635
+ return identityPayload?.ready === true;
657
636
  }
658
637
 
659
638
  function projectToolPluginVersionStatus(payload = null) {
@@ -685,11 +664,34 @@ export function projectToolAccountViewResponse({
685
664
  accountId = null,
686
665
  pairingPayload = null,
687
666
  identityPayload = null,
667
+ accountPayload = null,
688
668
  } = {}) {
689
669
  const publicIdentityState = projectToolAccountIdentityFields(identityPayload);
690
670
  const accountProfile = projectToolAccountProfileState(identityPayload);
691
- const publicIdentityReady = identityPayload?.ready === true;
692
- const accountProfileReady = accountProfile.ready === true;
671
+ const accountView = normalizeObject(accountPayload, null);
672
+ const accountRecord = normalizeObject(accountView?.account, null);
673
+ const accountRelay = normalizeObject(accountView?.relay, null);
674
+ const accountDiagnostics = normalizeObject(accountView?.diagnostics, null);
675
+ const publicIdentityReady = resolveToolPublicIdentityReady(identityPayload, publicIdentityState);
676
+ const accountProfileReady = accountProfile.ready === true
677
+ || accountRecord?.profileReady === true
678
+ || accountDiagnostics?.accountProfileReady === true;
679
+ const resolvedAccountProfile = accountProfile.ready === true
680
+ ? accountProfile
681
+ : {
682
+ ...accountProfile,
683
+ status: accountProfileReady ? 'ready' : accountProfile.status,
684
+ ready: accountProfileReady,
685
+ profile: normalizeText(
686
+ accountRecord?.agentProfile,
687
+ normalizeText(accountRecord?.profile, accountProfile.profile),
688
+ ),
689
+ reason: accountProfileReady ? null : accountProfile.reason,
690
+ requiredAction: accountProfileReady ? null : accountProfile.requiredAction,
691
+ nextAction: accountProfileReady ? null : accountProfile.nextAction,
692
+ nextTool: accountProfileReady ? null : accountProfile.nextTool,
693
+ missingFields: accountProfileReady ? [] : accountProfile.missingFields,
694
+ };
693
695
  const emailVerified = pairingPayload?.emailVerified === true;
694
696
  const runtimePaired = pairingPayload?.status === 'paired';
695
697
  const bindingReady = typeof pairingPayload?.bindingReady === 'boolean'
@@ -720,11 +722,11 @@ export function projectToolAccountViewResponse({
720
722
  }
721
723
  : !accountProfileReady
722
724
  ? {
723
- requiredAction: accountProfile.requiredAction,
724
- nextAction: accountProfile.nextAction,
725
- nextTool: accountProfile.nextTool,
726
- missingFields: accountProfile.missingFields,
727
- reason: accountProfile.reason,
725
+ requiredAction: resolvedAccountProfile.requiredAction,
726
+ nextAction: resolvedAccountProfile.nextAction,
727
+ nextTool: resolvedAccountProfile.nextTool,
728
+ missingFields: resolvedAccountProfile.missingFields,
729
+ reason: resolvedAccountProfile.reason,
728
730
  }
729
731
  : {
730
732
  requiredAction: null,
@@ -733,8 +735,17 @@ export function projectToolAccountViewResponse({
733
735
  missingFields: [],
734
736
  reason: null,
735
737
  };
736
- const relayResolved = pairingPayload?.relayAgent?.resolved ?? null;
737
- const relayOnline = pairingPayload?.relayAgent?.online ?? null;
738
+ const relayIdentityResolved = typeof pairingPayload?.relayAgent?.resolved === 'boolean'
739
+ ? pairingPayload.relayAgent.resolved
740
+ : null;
741
+ const relayOnline = typeof accountRelay?.online === 'boolean'
742
+ ? accountRelay.online
743
+ : (typeof accountDiagnostics?.relayOnline === 'boolean'
744
+ ? accountDiagnostics.relayOnline
745
+ : (typeof pairingPayload?.relayAgent?.online === 'boolean' ? pairingPayload.relayAgent.online : null));
746
+ const relayResolved = typeof accountRelay?.resolved === 'boolean'
747
+ ? accountRelay.resolved
748
+ : (typeof relayOnline === 'boolean');
738
749
  const resolvedShareCard = identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
739
750
  ? projectToolShareCard(identityPayload.shareCard)
740
751
  : undefined;
@@ -765,6 +776,7 @@ export function projectToolAccountViewResponse({
765
776
  bindingStatus,
766
777
  publicIdentityReady,
767
778
  accountProfileReady,
779
+ relayIdentityResolved,
768
780
  relayPresenceResolved: relayResolved,
769
781
  relayOnline,
770
782
  },
@@ -774,21 +786,20 @@ export function projectToolAccountViewResponse({
774
786
  normalizeText(pairingPayload?.relayAgent?.agentId, null),
775
787
  ),
776
788
  displayName: normalizeText(pairingPayload?.relayAgent?.displayName, null),
777
- discoverable: pairingPayload?.relayAgent?.discoverable ?? null,
778
- contactable: pairingPayload?.relayAgent?.contactable ?? null,
789
+ visibilityMode: normalizeText(pairingPayload?.relayAgent?.visibilityMode, null),
790
+ contactPolicy: normalizeText(pairingPayload?.relayAgent?.contactPolicy, null),
779
791
  online: relayOnline,
780
792
  resolved: relayResolved,
781
793
  bindingStatus,
782
794
  },
783
- profile: accountProfile.profile,
795
+ profile: resolvedAccountProfile.profile,
784
796
  ...publicIdentityState,
785
- accountProfile,
797
+ accountProfile: resolvedAccountProfile,
786
798
  requiredAction: blockedAction.requiredAction,
787
799
  nextAction: blockedAction.nextAction,
788
800
  nextTool: blockedAction.nextTool,
789
801
  missingFields: blockedAction.missingFields,
790
802
  pluginVersionStatus: projectToolPluginVersionStatus(identityPayload?.pluginVersionStatus),
791
- chatRequestApprovalPolicy: projectToolChatRequestApprovalPolicy(identityPayload?.chatRequestApprovalPolicy),
792
803
  ...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
793
804
  };
794
805
  }
@@ -807,7 +818,7 @@ export function projectToolAccountMutationResponse({
807
818
  : (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
808
819
  ? projectToolShareCard(identityPayload.shareCard)
809
820
  : undefined);
810
- const publicIdentityReady = identityPayload?.ready === true;
821
+ const publicIdentityReady = resolveToolPublicIdentityReady(identityPayload, publicIdentityState);
811
822
  const accountProfileReady = accountProfile.ready === true;
812
823
  const emailVerificationPayload = normalizeObject(identityPayload?.emailVerification, null);
813
824
  const emailVerified = identityPayload?.emailVerified === true
@@ -875,7 +886,6 @@ export function projectToolAccountMutationResponse({
875
886
  missingFields: blockedAction.missingFields,
876
887
  reason: blockedAction.reason,
877
888
  pluginVersionStatus: projectToolPluginVersionStatus(identityPayload?.pluginVersionStatus),
878
- chatRequestApprovalPolicy: projectToolChatRequestApprovalPolicy(identityPayload?.chatRequestApprovalPolicy),
879
889
  ...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
880
890
  ...(runtimeIdentity ? { runtimeIdentity } : {}),
881
891
  ...(action === 'update_identity'
@@ -888,10 +898,6 @@ export function projectToolAccountMutationResponse({
888
898
  ? {
889
899
  updated: ['profile'],
890
900
  }
891
- : action === 'update_chat_policy'
892
- ? {
893
- updated: ['chatRequestApprovalPolicy'],
894
- }
895
901
  : {}),
896
902
  };
897
903
  }