@xfxstudio/claworld 2026.6.29-testing.1 → 2026.7.1-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
@@ -74,12 +74,16 @@ Also re-run:
74
74
 
75
75
  ## Local Development
76
76
 
77
- For a repo checkout, materialize the package root first:
77
+ For a repo checkout, install the plugin from the repository root:
78
78
 
79
79
  ```bash
80
- npm run build:plugin:package
81
- openclaw plugins install /absolute/path/to/packages/openclaw-plugin
80
+ openclaw plugins install /absolute/path/to/claworld-openclaw-plugin
82
81
  ```
83
82
 
84
- If you change plugin code, rebuild the package root before reinstalling or
85
- retesting it in a real host.
83
+ If you change plugin code, rerun the tests and reinstall the checkout before
84
+ retesting it in a real host:
85
+
86
+ ```bash
87
+ npm test
88
+ openclaw plugins update @xfxstudio/claworld
89
+ ```
@@ -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.6.29-testing.1",
20
+ "version": "2026.7.1-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.6.29-testing.1",
3
+ "version": "2026.7.1-testing.1",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -20,11 +20,11 @@
20
20
  ],
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://github.com/Lightningxxl/claworld.git"
23
+ "url": "git+https://github.com/Lightningxxl/claworld-openclaw-plugin.git"
24
24
  },
25
- "homepage": "https://github.com/Lightningxxl/claworld",
25
+ "homepage": "https://github.com/Lightningxxl/claworld-openclaw-plugin",
26
26
  "bugs": {
27
- "url": "https://github.com/Lightningxxl/claworld/issues"
27
+ "url": "https://github.com/Lightningxxl/claworld-openclaw-plugin/issues"
28
28
  },
29
29
  "keywords": [
30
30
  "openclaw",
@@ -47,12 +47,21 @@
47
47
  "dependencies": {
48
48
  "ws": "^8.19.0"
49
49
  },
50
+ "devDependencies": {
51
+ "openclaw": "2026.4.9"
52
+ },
50
53
  "publishConfig": {
51
54
  "registry": "https://registry.npmjs.org/",
52
55
  "access": "public"
53
56
  },
54
57
  "scripts": {
55
- "prepack": "node ../../scripts/build-openclaw-plugin-package.mjs --output-dir ."
58
+ "test": "node tests/run-all.js",
59
+ "test:unit": "node tests/run-all.js unit",
60
+ "check:package": "node scripts/check-package.mjs",
61
+ "pack:dry-run": "npm run check:package && npm pack --dry-run --json",
62
+ "publish:stable": "node scripts/publish-package.mjs --tag latest",
63
+ "publish:testing": "node scripts/publish-package.mjs --tag testing",
64
+ "prepack": "npm run check:package"
56
65
  },
57
66
  "openclaw": {
58
67
  "extensions": [
@@ -99,6 +99,24 @@ export function normalizeChatRequestOpeningPayload(input = null) {
99
99
  return Object.keys(payload).length > 0 ? payload : null;
100
100
  }
101
101
 
102
+ function normalizeKickoffBriefInput(kickoffBrief = null) {
103
+ if (kickoffBrief && typeof kickoffBrief === 'object' && !Array.isArray(kickoffBrief)) {
104
+ return kickoffBrief;
105
+ }
106
+ const text = normalizeText(kickoffBrief, null);
107
+ return text ? { text } : null;
108
+ }
109
+
110
+ function resolveKickoffBriefOpeningMessage(kickoffBrief = null, fallback = null) {
111
+ if (!kickoffBrief || typeof kickoffBrief !== 'object' || Array.isArray(kickoffBrief)) {
112
+ return normalizeText(fallback, null);
113
+ }
114
+ return normalizeText(
115
+ kickoffBrief.text,
116
+ normalizeText(kickoffBrief.openingMessage, normalizeText(kickoffBrief.message, normalizeText(fallback, null))),
117
+ );
118
+ }
119
+
102
120
  export function resolveChatRequestOpeningMessage({
103
121
  openingMessage = null,
104
122
  openingPayload = null,
@@ -119,12 +137,8 @@ function resolveKickoffBriefSource({
119
137
  const normalizedContext = requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
120
138
  ? requestContext
121
139
  : {};
122
- const explicitKickoffBrief = kickoffBrief && typeof kickoffBrief === 'object' && !Array.isArray(kickoffBrief)
123
- ? kickoffBrief
124
- : null;
125
- const contextKickoffBrief = normalizedContext.kickoffBrief && typeof normalizedContext.kickoffBrief === 'object' && !Array.isArray(normalizedContext.kickoffBrief)
126
- ? normalizedContext.kickoffBrief
127
- : null;
140
+ const explicitKickoffBrief = normalizeKickoffBriefInput(kickoffBrief);
141
+ const contextKickoffBrief = normalizeKickoffBriefInput(normalizedContext.kickoffBrief);
128
142
  const fallbackSource = normalizeText(source, null) === 'world_broadcast'
129
143
  ? 'world_broadcast_brief'
130
144
  : 'chat_request_brief';
@@ -150,12 +164,8 @@ function resolveChatRequestKickoffBrief({
150
164
  const normalizedContext = requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
151
165
  ? requestContext
152
166
  : {};
153
- const explicitKickoffBrief = kickoffBrief && typeof kickoffBrief === 'object' && !Array.isArray(kickoffBrief)
154
- ? kickoffBrief
155
- : null;
156
- const contextKickoffBrief = normalizedContext.kickoffBrief && typeof normalizedContext.kickoffBrief === 'object' && !Array.isArray(normalizedContext.kickoffBrief)
157
- ? normalizedContext.kickoffBrief
158
- : null;
167
+ const explicitKickoffBrief = normalizeKickoffBriefInput(kickoffBrief);
168
+ const contextKickoffBrief = normalizeKickoffBriefInput(normalizedContext.kickoffBrief);
159
169
  const normalizedOpeningPayload = normalizeChatRequestOpeningPayload(
160
170
  explicitKickoffBrief?.payload
161
171
  ?? contextKickoffBrief?.payload
@@ -163,10 +173,10 @@ function resolveChatRequestKickoffBrief({
163
173
  ?? normalizedContext.openingPayload,
164
174
  );
165
175
  const normalizedOpeningMessage = resolveChatRequestOpeningMessage({
166
- openingMessage:
167
- explicitKickoffBrief?.text
168
- ?? contextKickoffBrief?.text
169
- ?? openingMessage,
176
+ openingMessage: resolveKickoffBriefOpeningMessage(
177
+ explicitKickoffBrief,
178
+ resolveKickoffBriefOpeningMessage(contextKickoffBrief, openingMessage),
179
+ ),
170
180
  openingPayload: normalizedOpeningPayload,
171
181
  requestContext: normalizedContext,
172
182
  });
@@ -271,6 +271,46 @@ function isClaworldPlainObject(value) {
271
271
  return value && typeof value === 'object' && !Array.isArray(value);
272
272
  }
273
273
 
274
+ function resolveClaworldOpeningMessage({
275
+ openingMessage = null,
276
+ message = null,
277
+ text = null,
278
+ kickoffBrief = null,
279
+ openingPayload = null,
280
+ } = {}) {
281
+ const brief = isClaworldPlainObject(kickoffBrief) ? kickoffBrief : null;
282
+ return normalizeClaworldText(
283
+ openingMessage,
284
+ normalizeClaworldText(
285
+ message,
286
+ normalizeClaworldText(
287
+ text,
288
+ normalizeClaworldText(
289
+ typeof kickoffBrief === 'string' ? kickoffBrief : null,
290
+ normalizeClaworldText(
291
+ brief?.text,
292
+ normalizeClaworldText(
293
+ brief?.openingMessage,
294
+ normalizeClaworldText(brief?.message, normalizeClaworldText(openingPayload?.text, null)),
295
+ ),
296
+ ),
297
+ ),
298
+ ),
299
+ ),
300
+ );
301
+ }
302
+
303
+ function normalizeClaworldKickoffBriefInput(kickoffBrief = null, openingMessage = null) {
304
+ if (isClaworldPlainObject(kickoffBrief)) {
305
+ return {
306
+ ...kickoffBrief,
307
+ ...(!resolveClaworldOpeningMessage({ kickoffBrief }) && openingMessage ? { text: openingMessage } : {}),
308
+ };
309
+ }
310
+ const text = normalizeClaworldText(kickoffBrief, null);
311
+ return text ? { text } : null;
312
+ }
313
+
274
314
  function resolveNormalizedText(value, fallback = null) {
275
315
  return normalizeClaworldText(value, fallback);
276
316
  }
@@ -894,6 +934,10 @@ async function createChatRequest({
894
934
  displayName = null,
895
935
  agentCode = null,
896
936
  openingMessage = null,
937
+ message = null,
938
+ text = null,
939
+ kickoffBrief = null,
940
+ openingPayload = null,
897
941
  worldId = null,
898
942
  requestContext = null,
899
943
  fetchImpl,
@@ -912,7 +956,15 @@ async function createChatRequest({
912
956
  });
913
957
  }
914
958
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
915
- const normalizedOpeningMessage = normalizeClaworldText(openingMessage, null);
959
+ const normalizedOpeningPayload = isClaworldPlainObject(openingPayload) ? openingPayload : null;
960
+ const normalizedOpeningMessage = resolveClaworldOpeningMessage({
961
+ openingMessage,
962
+ message,
963
+ text,
964
+ kickoffBrief,
965
+ openingPayload: normalizedOpeningPayload,
966
+ });
967
+ const normalizedKickoffBrief = normalizeClaworldKickoffBriefInput(kickoffBrief, normalizedOpeningMessage);
916
968
  if (!normalizedOpeningMessage) {
917
969
  const message = 'openingMessage is required for chat request kickoff';
918
970
  throw createRuntimeBoundaryError({
@@ -951,6 +1003,8 @@ async function createChatRequest({
951
1003
  displayName: normalizedDisplayName,
952
1004
  agentCode: normalizedAgentCode,
953
1005
  openingMessage: normalizedOpeningMessage,
1006
+ ...(normalizedKickoffBrief ? { kickoffBrief: normalizedKickoffBrief } : {}),
1007
+ ...(normalizedOpeningPayload ? { openingPayload: normalizedOpeningPayload } : {}),
954
1008
  ...(normalizeClaworldText(worldId, null) ? { worldId: normalizeClaworldText(worldId, null) } : {}),
955
1009
  ...(requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
956
1010
  ? { requestContext }
@@ -4553,6 +4607,10 @@ async function generateRuntimeProfileCard(context = {}) {
4553
4607
  displayName: context.displayName || null,
4554
4608
  agentCode: context.agentCode || null,
4555
4609
  openingMessage: context.openingMessage || context.message || context.text || null,
4610
+ message: context.message || null,
4611
+ text: context.text || null,
4612
+ kickoffBrief: context.kickoffBrief || null,
4613
+ openingPayload: context.openingPayload || null,
4556
4614
  worldId: context.worldId || null,
4557
4615
  requestContext,
4558
4616
  fetchImpl,
@@ -201,6 +201,28 @@ function hasExplicitAction(params = {}) {
201
201
  return Object.prototype.hasOwnProperty.call(params, 'action') && normalizeText(params.action, null) != null;
202
202
  }
203
203
 
204
+ function resolveConversationOpeningMessage(params = {}) {
205
+ const kickoffBrief = params?.kickoffBrief && typeof params.kickoffBrief === 'object' && !Array.isArray(params.kickoffBrief)
206
+ ? params.kickoffBrief
207
+ : null;
208
+ return normalizeText(
209
+ params?.openingMessage,
210
+ normalizeText(
211
+ params?.message,
212
+ normalizeText(
213
+ params?.text,
214
+ normalizeText(
215
+ typeof params?.kickoffBrief === 'string' ? params.kickoffBrief : null,
216
+ normalizeText(
217
+ kickoffBrief?.text,
218
+ normalizeText(kickoffBrief?.openingMessage, normalizeText(kickoffBrief?.message, normalizeText(params?.openingPayload?.text, null))),
219
+ ),
220
+ ),
221
+ ),
222
+ ),
223
+ );
224
+ }
225
+
204
226
  function normalizeTerminalAccountAction(params = {}) {
205
227
  if (hasExplicitAction(params)) {
206
228
  const explicitAction = normalizeText(params.action, null);
@@ -1069,6 +1091,16 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1069
1091
  displayName: stringParam({ description: 'Target public display name for request.', minLength: 1 }),
1070
1092
  agentCode: stringParam({ description: 'Target public agent code for request.', minLength: 1 }),
1071
1093
  openingMessage: stringParam({ description: 'Request/re-engagement kickoff message.', minLength: 1 }),
1094
+ message: stringParam({ description: 'Alias for openingMessage on action=request.', minLength: 1 }),
1095
+ text: stringParam({ description: 'Alias for openingMessage on action=request.', minLength: 1 }),
1096
+ kickoffBrief: objectParam({
1097
+ description: 'Structured request kickoff brief. text/openingMessage/message are accepted as opener aliases.',
1098
+ properties: {
1099
+ text: stringParam({ description: 'Request/re-engagement kickoff message.', minLength: 1 }),
1100
+ openingMessage: stringParam({ description: 'Alias for kickoff brief text.', minLength: 1 }),
1101
+ message: stringParam({ description: 'Alias for kickoff brief text.', minLength: 1 }),
1102
+ },
1103
+ }),
1072
1104
  worldId: worldIdProperty,
1073
1105
  direction: stringParam({
1074
1106
  description: 'Top-level alias for filters.direction on action=list_related/get_state.',
@@ -1778,6 +1810,28 @@ function buildRegisteredTools(api, plugin) {
1778
1810
  minLength: 1,
1779
1811
  examples: ['Hi, want to compare trail-running routes in Shanghai?'],
1780
1812
  }),
1813
+ message: stringParam({
1814
+ description: 'Alias for openingMessage.',
1815
+ minLength: 1,
1816
+ }),
1817
+ text: stringParam({
1818
+ description: 'Alias for openingMessage.',
1819
+ minLength: 1,
1820
+ }),
1821
+ kickoffBrief: objectParam({
1822
+ description: 'Structured request kickoff brief. text/openingMessage/message are accepted as opener aliases.',
1823
+ properties: {
1824
+ text: stringParam({ description: 'Request/re-engagement kickoff message.', minLength: 1 }),
1825
+ openingMessage: stringParam({ description: 'Alias for kickoff brief text.', minLength: 1 }),
1826
+ message: stringParam({ description: 'Alias for kickoff brief text.', minLength: 1 }),
1827
+ },
1828
+ }),
1829
+ openingPayload: objectParam({
1830
+ description: 'Optional structured opening payload. text is accepted as opener alias.',
1831
+ properties: {
1832
+ text: stringParam({ description: 'Request/re-engagement kickoff message.', minLength: 1 }),
1833
+ },
1834
+ }),
1781
1835
  worldId: worldIdProperty,
1782
1836
  },
1783
1837
  examples: [
@@ -1798,7 +1852,11 @@ function buildRegisteredTools(api, plugin) {
1798
1852
  ...context,
1799
1853
  displayName: params.displayName,
1800
1854
  agentCode: params.agentCode,
1801
- openingMessage: params.openingMessage || null,
1855
+ openingMessage: resolveConversationOpeningMessage(params),
1856
+ message: params.message || null,
1857
+ text: params.text || null,
1858
+ kickoffBrief: params.kickoffBrief || null,
1859
+ openingPayload: params.openingPayload || null,
1802
1860
  worldId: params.worldId || null,
1803
1861
  });
1804
1862
  return buildToolResult(projectToolChatRequestMutationResponse(payload, { accountId: context.accountId }));
@@ -1427,10 +1427,21 @@ export class ClaworldRelayClient extends EventEmitter {
1427
1427
  });
1428
1428
  }
1429
1429
 
1430
- async createChatRequest({ fromAgentId, displayName, agentCode, requestContext = {} } = {}) {
1430
+ async createChatRequest({
1431
+ fromAgentId,
1432
+ displayName,
1433
+ agentCode,
1434
+ kickoffBrief = null,
1435
+ openingMessage = null,
1436
+ openingPayload = null,
1437
+ requestContext = {},
1438
+ } = {}) {
1431
1439
  const normalized = normalizeChatRequestInput({ requestContext, source: 'direct_lookup' });
1432
1440
  const normalizedDisplayName = normalizeOptionalText(displayName);
1433
1441
  const normalizedAgentCode = normalizeOptionalText(agentCode)?.toUpperCase() || null;
1442
+ const normalizedOpeningPayload = openingPayload && typeof openingPayload === 'object' && !Array.isArray(openingPayload)
1443
+ ? openingPayload
1444
+ : null;
1434
1445
  return await this.requestJson('/v1/chat-requests', {
1435
1446
  method: 'POST',
1436
1447
  headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),
@@ -1438,8 +1449,13 @@ export class ClaworldRelayClient extends EventEmitter {
1438
1449
  fromAgentId,
1439
1450
  ...(normalizedDisplayName ? { displayName: normalizedDisplayName } : {}),
1440
1451
  ...(normalizedAgentCode ? { agentCode: normalizedAgentCode } : {}),
1441
- kickoffBrief: normalized.kickoffBrief || null,
1442
- openingMessage: normalized.openingMessage || null,
1452
+ kickoffBrief: kickoffBrief || normalized.kickoffBrief || null,
1453
+ openingMessage:
1454
+ normalizeOptionalText(openingMessage)
1455
+ || normalizeOptionalText(normalized.openingMessage)
1456
+ || normalizeOptionalText(normalizedOpeningPayload?.text)
1457
+ || null,
1458
+ ...(normalizedOpeningPayload ? { openingPayload: normalizedOpeningPayload } : {}),
1443
1459
  worldId: normalized.conversation?.worldId || null,
1444
1460
  requestContext: requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
1445
1461
  ? requestContext
@@ -1564,6 +1580,7 @@ export class ClaworldRelayClient extends EventEmitter {
1564
1580
  fromAgentId,
1565
1581
  displayName,
1566
1582
  agentCode,
1583
+ openingPayload: normalizedOpeningPayload,
1567
1584
  requestContext: normalizedRequestContext,
1568
1585
  });
1569
1586
  if (requestResult.status !== 201) {
@@ -1,4 +1,3 @@
1
- import { readFileSync } from 'node:fs';
2
1
  import repoPackageJson from '../../package.json' with { type: 'json' };
3
2
 
4
3
  export const CLAWORLD_PLUGIN_PACKAGE_NAME = '@xfxstudio/claworld';
@@ -35,18 +34,6 @@ function resolveCurrentPluginVersion() {
35
34
  return repoVersion;
36
35
  }
37
36
 
38
- try {
39
- const publishSurfaceSource = readFileSync(
40
- new URL('../../packages/openclaw-plugin/package.json', import.meta.url),
41
- 'utf8',
42
- );
43
- const publishSurfacePackageJson = JSON.parse(publishSurfaceSource);
44
- const publishSurfaceVersion = normalizeClaworldPluginVersion(publishSurfacePackageJson?.version, null);
45
- if (publishSurfacePackageJson?.name === CLAWORLD_PLUGIN_PACKAGE_NAME && publishSurfaceVersion) {
46
- return publishSurfaceVersion;
47
- }
48
- } catch {}
49
-
50
37
  return repoVersion || '0.0.0';
51
38
  }
52
39