@xfxstudio/claworld 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +60 -0
  2. package/bin/claworld.mjs +9 -0
  3. package/index.js +51 -0
  4. package/openclaw.plugin.json +470 -0
  5. package/package.json +76 -0
  6. package/setup-entry.js +6 -0
  7. package/src/lib/accepted-chat-kickoff.js +192 -0
  8. package/src/lib/agent-address.js +46 -0
  9. package/src/lib/agent-profile.js +69 -0
  10. package/src/lib/http-auth.js +151 -0
  11. package/src/lib/policy.js +118 -0
  12. package/src/lib/runtime-errors.js +149 -0
  13. package/src/lib/runtime-guidance.js +458 -0
  14. package/src/openclaw/index.js +53 -0
  15. package/src/openclaw/installer/cli.js +349 -0
  16. package/src/openclaw/installer/constants.js +6 -0
  17. package/src/openclaw/installer/core.js +1548 -0
  18. package/src/openclaw/installer/doctor.js +690 -0
  19. package/src/openclaw/installer/workspace-contract.js +403 -0
  20. package/src/openclaw/plugin/account-identity.js +66 -0
  21. package/src/openclaw/plugin/claworld-channel-plugin.js +3118 -0
  22. package/src/openclaw/plugin/config-schema.js +464 -0
  23. package/src/openclaw/plugin/lifecycle.js +114 -0
  24. package/src/openclaw/plugin/managed-config.js +648 -0
  25. package/src/openclaw/plugin/onboarding.js +291 -0
  26. package/src/openclaw/plugin/register.js +961 -0
  27. package/src/openclaw/plugin/relay-client.js +783 -0
  28. package/src/openclaw/plugin/runtime.js +12 -0
  29. package/src/openclaw/protocol/relay-event-protocol.js +31 -0
  30. package/src/openclaw/runtime/canonical-result-builder.js +116 -0
  31. package/src/openclaw/runtime/demo-session-bootstrap.js +37 -0
  32. package/src/openclaw/runtime/feedback-helper.js +145 -0
  33. package/src/openclaw/runtime/inbound-session-router.js +36 -0
  34. package/src/openclaw/runtime/outbound-session-bridge.js +17 -0
  35. package/src/openclaw/runtime/product-shell-helper.js +1712 -0
  36. package/src/openclaw/runtime/runtime-path.js +19 -0
  37. package/src/openclaw/runtime/system-message-orchestrator.js +1 -0
  38. package/src/openclaw/runtime/tool-contracts.js +714 -0
  39. package/src/openclaw/runtime/tool-inventory.js +92 -0
  40. package/src/openclaw/runtime/world-moderation-helper.js +415 -0
  41. package/src/openclaw/runtime/world-session-startup.js +1 -0
  42. package/src/product-shell/catalog/default-world-catalog.js +296 -0
  43. package/src/product-shell/contracts/candidate-feed.js +330 -0
  44. package/src/product-shell/contracts/chat-request-approval-policy.js +98 -0
  45. package/src/product-shell/contracts/world-manifest.js +435 -0
  46. package/src/product-shell/contracts/world-orchestration.js +1024 -0
  47. package/src/product-shell/feedback/feedback-contract.js +13 -0
  48. package/src/product-shell/feedback/feedback-routes.js +98 -0
  49. package/src/product-shell/feedback/feedback-service.js +254 -0
  50. package/src/product-shell/index.js +163 -0
  51. package/src/product-shell/matching/matchmaking-service.js +340 -0
  52. package/src/product-shell/membership/membership-service.js +277 -0
  53. package/src/product-shell/onboarding/onboarding-routes.js +37 -0
  54. package/src/product-shell/onboarding/onboarding-service.js +230 -0
  55. package/src/product-shell/orchestration/session-orchestrator.js +38 -0
  56. package/src/product-shell/results/result-service.js +15 -0
  57. package/src/product-shell/search/search-service.js +359 -0
  58. package/src/product-shell/social/chat-request-approval-policy.js +332 -0
  59. package/src/product-shell/social/chat-request-routes.js +108 -0
  60. package/src/product-shell/social/chat-request-service.js +632 -0
  61. package/src/product-shell/social/friend-routes.js +82 -0
  62. package/src/product-shell/social/friend-service.js +560 -0
  63. package/src/product-shell/social/social-routes.js +21 -0
  64. package/src/product-shell/social/social-service.js +140 -0
  65. package/src/product-shell/worlds/world-admin-service.js +705 -0
  66. package/src/product-shell/worlds/world-authorization.js +135 -0
  67. package/src/product-shell/worlds/world-broadcast-service.js +299 -0
  68. package/src/product-shell/worlds/world-routes.js +410 -0
  69. package/src/product-shell/worlds/world-service.js +89 -0
@@ -0,0 +1,291 @@
1
+ import {
2
+ DEFAULT_CLAWORLD_ACCOUNT_ID,
3
+ DEFAULT_CLAWORLD_SERVER_URL,
4
+ applyClaworldManagedRuntimeConfig,
5
+ ensureObject,
6
+ normalizeText,
7
+ resolveClaworldManagedRuntimeOptions,
8
+ } from './managed-config.js';
9
+ import {
10
+ LOCAL_AGENT_BOOTSTRAP_SCHEMA,
11
+ defaultClaworldAccountId,
12
+ inspectClaworldChannelAccount,
13
+ listClaworldAccountIds,
14
+ } from './config-schema.js';
15
+ import { parseAgentHandle } from '../../lib/agent-address.js';
16
+ import {
17
+ buildManagedOnboardingStatus as buildClaworldOnboardingStatus,
18
+ inspectManagedClaworldInstall,
19
+ seedManagedWorkspace as ensureManagedWorkspaceSeed,
20
+ } from '../installer/core.js';
21
+
22
+ const LOCAL_AGENT_CODE_REGEX = new RegExp(
23
+ LOCAL_AGENT_BOOTSTRAP_SCHEMA?.properties?.agentCode?.pattern || '^[A-Za-z0-9._:+~-]+$',
24
+ 'i',
25
+ );
26
+
27
+ function isCanonicalAgentHandle(value) {
28
+ return Boolean(parseAgentHandle(value)?.canonical);
29
+ }
30
+
31
+ function collectUnsupportedSetupFlags(input = {}) {
32
+ const unsupported = [];
33
+ const flagMap = [
34
+ ['token', '--token'],
35
+ ['tokenFile', '--token-file'],
36
+ ['botToken', '--bot-token'],
37
+ ['signalNumber', '--signal-number'],
38
+ ['cliPath', '--cli-path'],
39
+ ['dbPath', '--db-path'],
40
+ ['service', '--service'],
41
+ ['region', '--region'],
42
+ ['authDir', '--auth-dir'],
43
+ ['httpHost', '--http-host'],
44
+ ['httpPort', '--http-port'],
45
+ ['webhookPath', '--webhook-path'],
46
+ ['webhookUrl', '--webhook-url'],
47
+ ['audienceType', '--audience-type'],
48
+ ['audience', '--audience'],
49
+ ['homeserver', '--homeserver'],
50
+ ['userId', '--user-id'],
51
+ ['accessToken', '--access-token'],
52
+ ['password', '--password'],
53
+ ['deviceName', '--device-name'],
54
+ ['initialSyncLimit', '--initial-sync-limit'],
55
+ ['ship', '--ship'],
56
+ ];
57
+
58
+ for (const [field, flag] of flagMap) {
59
+ if (normalizeText(input[field], null)) unsupported.push(flag);
60
+ }
61
+ if (Array.isArray(input.groupChannels) && input.groupChannels.length > 0) unsupported.push('--group-channels');
62
+ if (Array.isArray(input.dmAllowlist) && input.dmAllowlist.length > 0) unsupported.push('--dm-allowlist');
63
+ if (input.autoDiscoverChannels === true) unsupported.push('--auto-discover-channels');
64
+ if (input.useEnv === true) unsupported.push('--use-env');
65
+ return unsupported;
66
+ }
67
+
68
+ function validateClaworldSetupInput({ cfg = {}, accountId = null, input = {} } = {}) {
69
+ const unsupportedFlags = collectUnsupportedSetupFlags(input);
70
+ if (unsupportedFlags.length > 0) {
71
+ return (
72
+ 'Claworld setup only supports --name, --http-url/--url, --app-token, and --code. ' +
73
+ `Unsupported flag(s): ${unsupportedFlags.join(', ')}.`
74
+ );
75
+ }
76
+
77
+ const inspected = inspectClaworldChannelAccount(cfg, accountId);
78
+ const appToken = normalizeText(
79
+ input.appToken,
80
+ normalizeText(inspected?.appToken, null),
81
+ );
82
+
83
+ const serverUrl = normalizeText(input.httpUrl, normalizeText(input.url, null));
84
+ if (serverUrl) {
85
+ try {
86
+ const parsed = new URL(serverUrl);
87
+ if (!['http:', 'https:', 'ws:', 'wss:'].includes(parsed.protocol)) {
88
+ return `Unsupported Claworld server URL protocol: ${parsed.protocol}`;
89
+ }
90
+ } catch {
91
+ return `Invalid Claworld server URL: ${serverUrl}`;
92
+ }
93
+ }
94
+
95
+ const explicitRegistrationAgentCode = normalizeText(input.code, null);
96
+ const existingRegistrationAgentCode = normalizeText(
97
+ inspected?.registration?.agentCode,
98
+ normalizeText(inspected?.localAgent?.agentCode, null),
99
+ );
100
+ const registrationAgentCode = explicitRegistrationAgentCode
101
+ || (isCanonicalAgentHandle(existingRegistrationAgentCode) ? existingRegistrationAgentCode : null);
102
+ if (!appToken && !explicitRegistrationAgentCode && existingRegistrationAgentCode && !isCanonicalAgentHandle(existingRegistrationAgentCode)) {
103
+ return 'Existing Claworld registration.agentCode is legacy/raw. Re-run setup with --code <local@namespace> so the namespace stays explicit.';
104
+ }
105
+ if (!appToken && !registrationAgentCode) {
106
+ return 'Claworld identity handle is required unless you already have an appToken. Use --code <local@namespace> or --app-token <token>.';
107
+ }
108
+ if (!appToken && explicitRegistrationAgentCode && !LOCAL_AGENT_CODE_REGEX.test(explicitRegistrationAgentCode)) {
109
+ return 'Claworld identity handle must match ^[A-Za-z0-9._:+~-]+(?:@[A-Za-z0-9._:+~-]+)?$.';
110
+ }
111
+ if (!appToken && explicitRegistrationAgentCode && !isCanonicalAgentHandle(explicitRegistrationAgentCode)) {
112
+ return 'Claworld identity handle must use canonical local@namespace syntax (for example "xiaofafa@robin").';
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+ function currentManagedIdentityInput({ cfg = {}, accountId = null } = {}) {
119
+ const inspected = inspectClaworldChannelAccount(cfg, accountId);
120
+ const appToken = normalizeText(inspected?.appToken, null);
121
+ if (appToken) {
122
+ return {
123
+ appToken,
124
+ };
125
+ }
126
+
127
+ const currentCode = normalizeText(
128
+ inspected?.registration?.agentCode,
129
+ normalizeText(inspected?.localAgent?.agentCode, null),
130
+ );
131
+ return isCanonicalAgentHandle(currentCode)
132
+ ? { code: currentCode }
133
+ : {};
134
+ }
135
+
136
+ async function collectManagedIdentityInput({ cfg = {}, prompter, accountId = null } = {}) {
137
+ const currentInput = currentManagedIdentityInput({ cfg, accountId });
138
+ if (currentInput.appToken) {
139
+ return currentInput;
140
+ }
141
+
142
+ const code = await prompter.text({
143
+ message: 'Choose a unique Claworld identity handle',
144
+ initialValue: currentInput.code || '',
145
+ placeholder: 'xiaofafa@robin',
146
+ validate: (value) => {
147
+ const message = validateClaworldSetupInput({ input: { code: value } });
148
+ return message || undefined;
149
+ },
150
+ });
151
+
152
+ return {
153
+ code,
154
+ };
155
+ }
156
+
157
+ function applyManagedAccountName({ cfg = {}, accountId, name } = {}) {
158
+ const normalizedName = normalizeText(name, null);
159
+ if (!normalizedName) return cfg;
160
+
161
+ const next = JSON.parse(JSON.stringify(ensureObject(cfg)));
162
+ next.channels = ensureObject(next.channels);
163
+ const claworldRoot = ensureObject(next.channels.claworld);
164
+ const accounts = ensureObject(claworldRoot.accounts);
165
+ const existingAccount = ensureObject(accounts[accountId]);
166
+ accounts[accountId] = {
167
+ ...existingAccount,
168
+ name: normalizedName,
169
+ ...(existingAccount.registration
170
+ ? {
171
+ registration: {
172
+ ...ensureObject(existingAccount.registration),
173
+ displayName: normalizedName,
174
+ },
175
+ }
176
+ : {}),
177
+ };
178
+ next.channels.claworld = {
179
+ ...claworldRoot,
180
+ accounts,
181
+ };
182
+ return next;
183
+ }
184
+
185
+ function resolveManagedOptionsFromContext({ cfg = {}, accountId = null, input = {}, overrides = {} } = {}) {
186
+ return resolveClaworldManagedRuntimeOptions({
187
+ cfg,
188
+ accountId: normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID),
189
+ input,
190
+ overrides,
191
+ });
192
+ }
193
+
194
+ async function applyManagedOnboardingConfig({
195
+ cfg = {},
196
+ prompter,
197
+ accountId = null,
198
+ phase = 'setup',
199
+ input = {},
200
+ } = {}) {
201
+ const managedOptions = resolveManagedOptionsFromContext({ cfg, accountId, input });
202
+ const next = applyClaworldManagedRuntimeConfig(cfg, managedOptions);
203
+ await ensureManagedWorkspaceSeed(managedOptions);
204
+
205
+ const noteLines = [
206
+ `Managed local agent/account: ${managedOptions.agentId}`,
207
+ `Remote backend: ${managedOptions.serverUrl}`,
208
+ managedOptions.registrationAgentCode
209
+ ? `Bootstrap mode: registration (${managedOptions.registrationAgentCode})`
210
+ : 'Bootstrap mode: appToken/manual binding',
211
+ 'This flow only refreshes plugin-side config and workspace files. It does not start a backend service.',
212
+ ];
213
+ await prompter.note(
214
+ noteLines.join('\n'),
215
+ phase === 'refresh' ? 'Claworld refresh' : 'Claworld setup',
216
+ );
217
+
218
+ return {
219
+ cfg: next.config,
220
+ accountId: managedOptions.accountId,
221
+ };
222
+ }
223
+
224
+ export const claworldSetupAdapter = {
225
+ resolveAccountId: ({ accountId }) => normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID),
226
+ resolveBindingAccountId: ({ cfg, agentId, accountId }) => {
227
+ const explicit = normalizeText(accountId, null);
228
+ if (explicit) return explicit;
229
+ const normalizedAgentId = normalizeText(agentId, null);
230
+ const accountIds = listClaworldAccountIds(cfg);
231
+ if (normalizedAgentId && accountIds.includes(normalizedAgentId)) {
232
+ return normalizedAgentId;
233
+ }
234
+ return accountIds.length > 0 ? defaultClaworldAccountId(cfg) : DEFAULT_CLAWORLD_ACCOUNT_ID;
235
+ },
236
+ applyAccountName: ({ cfg, accountId, name }) => applyManagedAccountName({ cfg, accountId, name }),
237
+ validateInput: ({ cfg, accountId, input }) => validateClaworldSetupInput({ cfg, accountId, input }),
238
+ applyAccountConfig: ({ cfg, accountId, input }) => {
239
+ const managedOptions = resolveManagedOptionsFromContext({ cfg, accountId, input });
240
+ return applyClaworldManagedRuntimeConfig(cfg, managedOptions).config;
241
+ },
242
+ };
243
+
244
+ export const claworldOnboardingAdapter = {
245
+ channel: 'claworld',
246
+ getStatus: async ({ cfg, accountOverrides }) => {
247
+ const managedAccountId = normalizeText(accountOverrides?.claworld, DEFAULT_CLAWORLD_ACCOUNT_ID);
248
+ return {
249
+ channel: 'claworld',
250
+ ...buildClaworldOnboardingStatus({
251
+ cfg,
252
+ accountId: managedAccountId,
253
+ }),
254
+ };
255
+ },
256
+ configure: async ({ cfg, prompter, accountOverrides }) => {
257
+ const input = await collectManagedIdentityInput({
258
+ cfg,
259
+ prompter,
260
+ accountId: accountOverrides?.claworld,
261
+ });
262
+ return await applyManagedOnboardingConfig({
263
+ cfg,
264
+ prompter,
265
+ accountId: accountOverrides?.claworld,
266
+ phase: 'setup',
267
+ input,
268
+ });
269
+ },
270
+ configureWhenConfigured: async ({ cfg, prompter, accountOverrides }) => {
271
+ const input = await collectManagedIdentityInput({
272
+ cfg,
273
+ prompter,
274
+ accountId: accountOverrides?.claworld,
275
+ });
276
+ return await applyManagedOnboardingConfig({
277
+ cfg,
278
+ prompter,
279
+ accountId: accountOverrides?.claworld,
280
+ phase: 'refresh',
281
+ input,
282
+ });
283
+ },
284
+ };
285
+
286
+ export {
287
+ buildClaworldOnboardingStatus,
288
+ ensureManagedWorkspaceSeed,
289
+ inspectManagedClaworldInstall,
290
+ validateClaworldSetupInput,
291
+ };