@xfxstudio/claworld 0.2.13 → 0.2.14

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 (57) hide show
  1. package/README.md +4 -4
  2. package/index.js +0 -1
  3. package/openclaw.plugin.json +1 -1
  4. package/package.json +1 -1
  5. package/skills/claworld-help/SKILL.md +19 -27
  6. package/skills/claworld-join-and-chat/SKILL.md +9 -9
  7. package/src/openclaw/index.js +0 -3
  8. package/src/openclaw/plugin/account-identity.js +0 -1
  9. package/src/openclaw/plugin/claworld-channel-plugin.js +8 -253
  10. package/src/openclaw/plugin/managed-config.js +1 -7
  11. package/src/openclaw/plugin/onboarding.js +1 -1
  12. package/src/openclaw/plugin/register.js +183 -232
  13. package/src/openclaw/plugin/relay-client.js +8 -5
  14. package/src/openclaw/runtime/product-shell-helper.js +11 -364
  15. package/src/openclaw/runtime/tool-contracts.js +0 -182
  16. package/src/openclaw/runtime/tool-inventory.js +4 -27
  17. package/src/lib/agent-profile.js +0 -74
  18. package/src/lib/http-auth.js +0 -151
  19. package/src/lib/policy.js +0 -114
  20. package/src/openclaw/installer/constants.js +0 -14
  21. package/src/product-shell/agent-cards/card-routes.js +0 -64
  22. package/src/product-shell/agent-cards/card-service.js +0 -287
  23. package/src/product-shell/agent-cards/spec-builder.js +0 -167
  24. package/src/product-shell/agent-cards/storage/image-host-storage.js +0 -192
  25. package/src/product-shell/agent-cards/storage/local-public-storage.js +0 -74
  26. package/src/product-shell/agent-cards/svg-renderer.js +0 -325
  27. package/src/product-shell/agent-cards/template-registry.js +0 -131
  28. package/src/product-shell/catalog/default-world-catalog.js +0 -38
  29. package/src/product-shell/contracts/candidate-feed.js +0 -393
  30. package/src/product-shell/contracts/world-manifest.js +0 -369
  31. package/src/product-shell/conversation-feedback/conversation-feedback-service.js +0 -261
  32. package/src/product-shell/feedback/feedback-contract.js +0 -13
  33. package/src/product-shell/feedback/feedback-routes.js +0 -98
  34. package/src/product-shell/feedback/feedback-service.js +0 -252
  35. package/src/product-shell/index.js +0 -212
  36. package/src/product-shell/matching/matchmaking-service.js +0 -395
  37. package/src/product-shell/membership/membership-service.js +0 -284
  38. package/src/product-shell/onboarding/onboarding-routes.js +0 -37
  39. package/src/product-shell/onboarding/onboarding-service.js +0 -222
  40. package/src/product-shell/orchestration/world-conversation-orchestrator.js +0 -28
  41. package/src/product-shell/profile/profile-service.js +0 -142
  42. package/src/product-shell/profile/public-identity-routes.js +0 -160
  43. package/src/product-shell/profile/public-identity-service.js +0 -192
  44. package/src/product-shell/search/search-service.js +0 -393
  45. package/src/product-shell/social/chat-request-approval-policy.js +0 -332
  46. package/src/product-shell/social/chat-request-routes.js +0 -130
  47. package/src/product-shell/social/chat-request-service.js +0 -723
  48. package/src/product-shell/social/friend-routes.js +0 -82
  49. package/src/product-shell/social/friend-service.js +0 -557
  50. package/src/product-shell/social/social-routes.js +0 -21
  51. package/src/product-shell/social/social-service.js +0 -136
  52. package/src/product-shell/worlds/world-admin-service.js +0 -486
  53. package/src/product-shell/worlds/world-authorization.js +0 -136
  54. package/src/product-shell/worlds/world-broadcast-service.js +0 -296
  55. package/src/product-shell/worlds/world-routes.js +0 -403
  56. package/src/product-shell/worlds/world-service.js +0 -89
  57. package/src/product-shell/worlds/world-text.js +0 -75
@@ -3,16 +3,10 @@ export const CLAWORLD_TOOL_CONTRACT_VERSION = 'v1';
3
3
  export const CLAWORLD_CHAT_REQUEST_TOOL_NAMES = Object.freeze([
4
4
  'claworld_request_chat',
5
5
  'claworld_chat_inbox',
6
- 'claworld_accept_chat_request',
7
- 'claworld_reject_chat_request',
8
6
  ]);
9
7
 
10
- export const CLAWORLD_BOOTSTRAP_TOOL_NAMES = Object.freeze([
11
- 'claworld_pair_agent',
12
- ]);
13
-
14
- export const CLAWORLD_PROFILE_TOOL_NAMES = Object.freeze([
15
- 'claworld_profile',
8
+ export const CLAWORLD_ACCOUNT_TOOL_NAMES = Object.freeze([
9
+ 'claworld_account',
16
10
  ]);
17
11
 
18
12
  export const CLAWORLD_FEEDBACK_TOOL_NAMES = Object.freeze([
@@ -30,24 +24,8 @@ export const CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES = Object.freeze([
30
24
  'claworld_manage_world',
31
25
  ]);
32
26
 
33
- export const CLAWORLD_COMPATIBILITY_TOOL_NAMES = Object.freeze([
34
- 'claworld_list_owned_worlds',
35
- 'claworld_prepare_world_join',
36
- 'claworld_search_world',
37
- ]);
38
-
39
- export const CLAWORLD_RETIRED_PUBLIC_TOOL_NAMES = Object.freeze([
40
- 'claworld_send_friend_request',
41
- 'claworld_list_friend_requests',
42
- 'claworld_accept_friend_request',
43
- 'claworld_reject_friend_request',
44
- 'claworld_broadcast_world',
45
- 'claworld_resolve_agent',
46
- ]);
47
-
48
27
  export const CLAWORLD_REGISTERED_TOOL_NAMES = Object.freeze([
49
- ...CLAWORLD_BOOTSTRAP_TOOL_NAMES,
50
- ...CLAWORLD_PROFILE_TOOL_NAMES,
28
+ ...CLAWORLD_ACCOUNT_TOOL_NAMES,
51
29
  ...CLAWORLD_WORLD_TOOL_NAMES,
52
30
  ...CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES,
53
31
  ...CLAWORLD_CHAT_REQUEST_TOOL_NAMES,
@@ -71,8 +49,7 @@ export const CLAWORLD_READ_ONLY_OPENCLAW_TOOL_NAMES = Object.freeze([
71
49
  ]);
72
50
 
73
51
  export const CLAWORLD_PLUGIN_SMOKE_REQUIRED_TOOL_NAMES = Object.freeze([
74
- ...CLAWORLD_BOOTSTRAP_TOOL_NAMES,
75
- ...CLAWORLD_PROFILE_TOOL_NAMES,
52
+ ...CLAWORLD_ACCOUNT_TOOL_NAMES,
76
53
  ...CLAWORLD_WORLD_TOOL_NAMES,
77
54
  ...CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES,
78
55
  ...CLAWORLD_CHAT_REQUEST_TOOL_NAMES,
@@ -1,74 +0,0 @@
1
- import { resolvePublicIdentity } from './public-identity.js';
2
-
3
- function normalizeOptionalString(value, { maxLength = 280 } = {}) {
4
- if (value == null) return null;
5
- const normalized = String(value).trim();
6
- if (!normalized) return null;
7
- return normalized.slice(0, maxLength);
8
- }
9
-
10
- function normalizeTagList(rawTags, { maxItems = 8, maxLength = 24 } = {}) {
11
- if (!Array.isArray(rawTags)) return [];
12
- const seen = new Set();
13
- const tags = [];
14
- for (const value of rawTags) {
15
- const normalized = normalizeOptionalString(value, { maxLength });
16
- if (!normalized) continue;
17
- const key = normalized.toLowerCase();
18
- if (seen.has(key)) continue;
19
- seen.add(key);
20
- tags.push(normalized);
21
- if (tags.length >= maxItems) break;
22
- }
23
- return tags;
24
- }
25
-
26
- function normalizeBooleanFlag(value, fallback = true) {
27
- if (typeof value === 'boolean') return value;
28
- if (typeof value === 'number') {
29
- if (value === 1) return true;
30
- if (value === 0) return false;
31
- }
32
- if (typeof value === 'string') {
33
- const normalized = value.trim().toLowerCase();
34
- if (normalized === 'true' || normalized === '1') return true;
35
- if (normalized === 'false' || normalized === '0') return false;
36
- }
37
- return fallback;
38
- }
39
-
40
- export function resolveAgentDisplayName(agent = {}) {
41
- const publicIdentityDisplayName = normalizeOptionalString(resolvePublicIdentity(agent).displayName, { maxLength: 80 });
42
- if (publicIdentityDisplayName) return publicIdentityDisplayName;
43
- const displayName = normalizeOptionalString(agent.displayName, { maxLength: 80 });
44
- if (displayName) return displayName;
45
- return normalizeOptionalString(agent.agentId, { maxLength: 80 })
46
- || 'agent';
47
- }
48
-
49
- export function normalizeAgentProfile(profile) {
50
- const source = profile && typeof profile === 'object' ? profile : {};
51
- return {
52
- headline: normalizeOptionalString(source.headline, { maxLength: 120 }),
53
- bio: normalizeOptionalString(source.bio, { maxLength: 300 }),
54
- avatarUrl: normalizeOptionalString(source.avatarUrl, { maxLength: 512 }),
55
- tags: normalizeTagList(source.tags),
56
- };
57
- }
58
-
59
- export function resolveAgentVisibility(agent = {}) {
60
- const discoverable = normalizeBooleanFlag(agent.discoverable, true);
61
- const requestedContactable = normalizeBooleanFlag(agent.contactable, true);
62
- return {
63
- discoverable,
64
- contactable: discoverable ? requestedContactable : false,
65
- };
66
- }
67
-
68
- export function normalizeAgentInputMetadata({ displayName, profile, discoverable, contactable } = {}) {
69
- return {
70
- displayName: resolveAgentDisplayName({ displayName }),
71
- profile: normalizeAgentProfile(profile),
72
- ...resolveAgentVisibility({ discoverable, contactable }),
73
- };
74
- }
@@ -1,151 +0,0 @@
1
- function unauthorized(reason) {
2
- return {
3
- error: 'not_authenticated',
4
- reason,
5
- };
6
- }
7
-
8
- function forbidden(reason, extra = {}) {
9
- return {
10
- error: 'forbidden',
11
- reason,
12
- ...extra,
13
- };
14
- }
15
-
16
- function isExpired(isoTs, nowMs = Date.now()) {
17
- if (!isoTs) return false;
18
- const expiresAtMs = Date.parse(isoTs);
19
- if (Number.isNaN(expiresAtMs)) return false;
20
- return expiresAtMs <= nowMs;
21
- }
22
-
23
- function normalizeHeaderValue(value) {
24
- if (Array.isArray(value)) {
25
- const [first] = value;
26
- return typeof first === 'string' ? first.trim() : '';
27
- }
28
- if (typeof value === 'string') return value.trim();
29
- return '';
30
- }
31
-
32
- export function readAppTokenFromRequest(req) {
33
- const authorization = normalizeHeaderValue(req?.headers?.authorization);
34
- if (/^bearer\s+/i.test(authorization)) {
35
- const token = authorization.replace(/^bearer\s+/i, '').trim();
36
- if (token) return { token, source: 'authorization' };
37
- }
38
-
39
- const appTokenHeader = normalizeHeaderValue(req?.headers?.['x-claworld-app-token']);
40
- if (appTokenHeader) return { token: appTokenHeader, source: 'x-claworld-app-token' };
41
-
42
- const legacyRelayToken = normalizeHeaderValue(req?.headers?.['x-relay-token']);
43
- if (legacyRelayToken) return { token: legacyRelayToken, source: 'x-relay-token' };
44
-
45
- return { token: null, source: null };
46
- }
47
-
48
- export function authenticateAppTokenRequest({ store, req }) {
49
- const { token, source } = readAppTokenFromRequest(req);
50
- if (!token) {
51
- return {
52
- present: false,
53
- ok: false,
54
- source: null,
55
- token: null,
56
- agent: null,
57
- credential: null,
58
- error: null,
59
- };
60
- }
61
-
62
- const credential = store.getCredentialByToken(token);
63
- if (!credential) {
64
- return {
65
- present: true,
66
- ok: false,
67
- source,
68
- token,
69
- agent: null,
70
- credential: null,
71
- error: unauthorized('credential_invalid'),
72
- };
73
- }
74
- if (credential.status !== 'active' || credential.revokedAt) {
75
- return {
76
- present: true,
77
- ok: false,
78
- source,
79
- token,
80
- agent: null,
81
- credential,
82
- error: unauthorized('credential_revoked'),
83
- };
84
- }
85
- if (isExpired(credential.expiresAt)) {
86
- return {
87
- present: true,
88
- ok: false,
89
- source,
90
- token,
91
- agent: null,
92
- credential,
93
- error: unauthorized('credential_expired'),
94
- };
95
- }
96
-
97
- const agent = store.getAgent(credential.agentId);
98
- if (!agent) {
99
- return {
100
- present: true,
101
- ok: false,
102
- source,
103
- token,
104
- agent: null,
105
- credential,
106
- error: unauthorized('credential_invalid'),
107
- };
108
- }
109
-
110
- return {
111
- present: true,
112
- ok: true,
113
- source,
114
- token,
115
- agent,
116
- credential,
117
- error: null,
118
- };
119
- }
120
-
121
- export function resolveAuthenticatedAgentId({ store, req, providedAgentId = null, fieldName = 'agentId' } = {}) {
122
- const auth = authenticateAppTokenRequest({ store, req });
123
- if (auth.present && !auth.ok) {
124
- return {
125
- ok: false,
126
- status: 401,
127
- body: auth.error,
128
- };
129
- }
130
-
131
- const explicitAgentId = String(providedAgentId || '').trim() || null;
132
- const authenticatedAgentId = auth.ok ? auth.agent.agentId : null;
133
-
134
- if (explicitAgentId && authenticatedAgentId && explicitAgentId !== authenticatedAgentId) {
135
- return {
136
- ok: false,
137
- status: 403,
138
- body: forbidden('agent_identity_mismatch', {
139
- field: fieldName,
140
- authenticatedAgentId,
141
- providedAgentId: explicitAgentId,
142
- }),
143
- };
144
- }
145
-
146
- return {
147
- ok: true,
148
- auth,
149
- agentId: explicitAgentId || authenticatedAgentId || null,
150
- };
151
- }
package/src/lib/policy.js DELETED
@@ -1,114 +0,0 @@
1
- import { resolveAgentVisibility } from './agent-profile.js';
2
- const ALLOW_DECISION = Object.freeze({ allowed: true });
3
- const EMPTY_SET = Object.freeze(new Set());
4
-
5
- function parsePolicyCsvSet(rawValue) {
6
- if (typeof rawValue !== 'string') return EMPTY_SET;
7
- const values = rawValue
8
- .split(',')
9
- .map((value) => value.trim().toLowerCase())
10
- .filter(Boolean);
11
- return values.length > 0 ? new Set(values) : EMPTY_SET;
12
- }
13
-
14
- function buildRequestDenyPolicyFromEnv(env) {
15
- return Object.freeze({
16
- blockedAgentIds: parsePolicyCsvSet(env.RELAY_POLICY_BLOCKED_AGENT_IDS),
17
- deniedAgentIds: parsePolicyCsvSet(env.RELAY_POLICY_DENIED_AGENT_IDS),
18
- });
19
- }
20
-
21
- function agentInPolicySet(values, candidate) {
22
- const normalized = String(candidate || '').trim().toLowerCase();
23
- return normalized ? values.has(normalized) : false;
24
- }
25
-
26
- const requestDenyPolicy = buildRequestDenyPolicyFromEnv(process.env);
27
-
28
- function deny(status, error, extras = {}) {
29
- return { allowed: false, status, error, ...extras };
30
- }
31
-
32
- export function defaultCanRequest({ fromAgentId, fromAgent, toAgent }) {
33
- const visibility = resolveAgentVisibility(toAgent);
34
- if (agentInPolicySet(requestDenyPolicy.blockedAgentIds, fromAgentId)) {
35
- return deny(403, 'request_blocked_by_policy');
36
- }
37
- if (agentInPolicySet(requestDenyPolicy.deniedAgentIds, fromAgentId)) {
38
- return deny(403, 'request_denied_by_policy');
39
- }
40
- if (toAgent.agentId === fromAgentId) return deny(400, 'self_request_not_allowed');
41
- if (!visibility.discoverable) return deny(403, 'target_not_discoverable');
42
- if (!visibility.contactable) return deny(403, 'target_not_contactable');
43
- return ALLOW_DECISION;
44
- }
45
-
46
- export function defaultCanAccept() {
47
- return ALLOW_DECISION;
48
- }
49
-
50
- export function defaultCanStartSession() {
51
- return ALLOW_DECISION;
52
- }
53
-
54
- export function defaultCanDeliverTurn({ session, roundBudget, fromAgentId }) {
55
- if (session.state !== 'active') {
56
- const terminationReason = typeof session?.terminationReason === 'string' && session.terminationReason.trim()
57
- ? session.terminationReason.trim()
58
- : null;
59
- return deny(terminationReason === 'session_timeout' ? 409 : 400, terminationReason || 'session_not_active');
60
- }
61
- if (roundBudget?.hasExplicitBudget && Number(roundBudget.remainingTurns) <= 0) {
62
- return deny(400, 'max_turns_reached');
63
- }
64
- if (fromAgentId !== session.currentSpeakerAgentId) return deny(400, 'not_current_speaker');
65
- return ALLOW_DECISION;
66
- }
67
-
68
- export function createRelayPolicyHooks(policy) {
69
- const hooks = policy && typeof policy === 'object' ? policy : {};
70
- return {
71
- canRequest: typeof hooks.canRequest === 'function' ? hooks.canRequest : defaultCanRequest,
72
- canAccept: typeof hooks.canAccept === 'function' ? hooks.canAccept : defaultCanAccept,
73
- canStartSession: typeof hooks.canStartSession === 'function' ? hooks.canStartSession : defaultCanStartSession,
74
- canDeliverTurn: typeof hooks.canDeliverTurn === 'function' ? hooks.canDeliverTurn : defaultCanDeliverTurn,
75
- };
76
- }
77
-
78
- export function resolvePolicyDecision(decision, { defaultStatus = 403, defaultError = 'forbidden' } = {}) {
79
- if (decision == null || decision === true) return { allowed: true };
80
- if (decision === false) return { allowed: false, status: defaultStatus, body: { error: defaultError } };
81
- if (typeof decision !== 'object') return { allowed: true };
82
-
83
- const hasDenyShape = decision.allowed === false
84
- || (decision.allowed === undefined && (decision.status !== undefined || decision.error !== undefined || decision.body !== undefined));
85
-
86
- if (!hasDenyShape) return { allowed: true };
87
-
88
- const status = Number.isInteger(decision.status) ? decision.status : defaultStatus;
89
- if (decision.body && typeof decision.body === 'object') return { allowed: false, status, body: decision.body };
90
- const error = typeof decision.error === 'string' && decision.error.trim() ? decision.error : defaultError;
91
- return { allowed: false, status, body: { error } };
92
- }
93
-
94
- export function evaluatePolicyHook({
95
- hook,
96
- context,
97
- hookName,
98
- defaultStatus = 403,
99
- defaultError = 'forbidden',
100
- }) {
101
- try {
102
- return resolvePolicyDecision(hook(context), { defaultStatus, defaultError });
103
- } catch (error) {
104
- return {
105
- allowed: false,
106
- status: 500,
107
- body: {
108
- error: 'policy_hook_error',
109
- hook: hookName,
110
- message: error instanceof Error ? error.message : String(error),
111
- },
112
- };
113
- }
114
- }
@@ -1,14 +0,0 @@
1
- import { createRequire } from 'module';
2
-
3
- const require = createRequire(import.meta.url);
4
- const installerPackageJson = require('../../../package.json');
5
-
6
- export const CLAWORLD_INSTALLER_BIN_NAME = 'claworld';
7
- export const CLAWORLD_INSTALLER_PACKAGE_NAME = '@xfxstudio/claworld';
8
- export const CLAWORLD_INSTALLER_PACKAGE_VERSION = installerPackageJson.version;
9
- export const CLAWORLD_INSTALLER_DEFAULT_PLUGIN_SOURCE = `${CLAWORLD_INSTALLER_PACKAGE_NAME}@${CLAWORLD_INSTALLER_PACKAGE_VERSION}`;
10
- export const CLAWORLD_INSTALLER_COMMAND = 'npx -y @xfxstudio/claworld install';
11
- export const CLAWORLD_DOCTOR_COMMAND = 'npx -y @xfxstudio/claworld doctor';
12
- export const CLAWORLD_UPDATE_COMMAND = 'npx -y @xfxstudio/claworld update';
13
- export const CLAWORLD_UNINSTALL_COMMAND = 'npx -y @xfxstudio/claworld uninstall';
14
- export const CLAWORLD_OPENCLAW_MIN_HOST_VERSION = '>=2026.3.22';
@@ -1,64 +0,0 @@
1
- import { resolveAuthenticatedAgentId } from '../../lib/http-auth.js';
2
-
3
- function sendAgentCardError(res, error) {
4
- const status = Number.isInteger(error?.status) ? error.status : 500;
5
- if (error?.responseBody && typeof error.responseBody === 'object') {
6
- return res.status(status).json(error.responseBody);
7
- }
8
- const code = typeof error?.code === 'string' ? error.code : 'internal_error';
9
- return res.status(status).json({ error: code, message: error?.message || code });
10
- }
11
-
12
- function buildAbsoluteUrl(req, publicPath) {
13
- return `${req.protocol}://${req.get('host')}${publicPath}`;
14
- }
15
-
16
- export function registerAgentCardRoutes(app, { store, agentCardService }) {
17
- app.get('/v1/meta/agent-cards', (_req, res) => {
18
- res.json(agentCardService.getManifest());
19
- });
20
-
21
- app.post('/v1/agent-cards/render', async (req, res) => {
22
- const resolvedAgent = resolveAuthenticatedAgentId({
23
- store,
24
- req,
25
- providedAgentId: req.body?.agentId || null,
26
- fieldName: 'agentId',
27
- });
28
- if (!resolvedAgent.ok) {
29
- return res.status(resolvedAgent.status).json(resolvedAgent.body);
30
- }
31
-
32
- try {
33
- const result = await agentCardService.renderCard({
34
- agentId: resolvedAgent.agentId,
35
- publicHandle: req.body?.publicHandle,
36
- displayName: req.body?.displayName,
37
- templateId: req.body?.templateId,
38
- templateVersion: req.body?.templateVersion,
39
- themeId: req.body?.themeId,
40
- title: req.body?.title,
41
- subtitle: req.body?.subtitle,
42
- ctaLines: req.body?.ctaLines,
43
- qrTargetUrl: req.body?.qrTargetUrl,
44
- footerLabel: req.body?.footerLabel,
45
- badgeText: req.body?.badgeText,
46
- expiresInSeconds: req.body?.expiresInSeconds,
47
- forceRegenerate: req.body?.forceRegenerate === true,
48
- });
49
-
50
- const imageUrl = result.card.imageUrl || (result.card.publicPath ? buildAbsoluteUrl(req, result.card.publicPath) : null);
51
- const downloadUrl = result.card.downloadUrl || imageUrl;
52
- return res.status(result.cacheHit ? 200 : 201).json({
53
- ...result,
54
- card: {
55
- ...result.card,
56
- ...(imageUrl ? { imageUrl } : {}),
57
- ...(downloadUrl ? { downloadUrl } : {}),
58
- },
59
- });
60
- } catch (error) {
61
- return sendAgentCardError(res, error);
62
- }
63
- });
64
- }