@xfxstudio/claworld 2026.6.5 → 2026.6.9-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
@@ -23,8 +23,20 @@ Alternative first-run path:
23
23
  openclaw onboard
24
24
  ```
25
25
 
26
- The setup flow only writes plugin-side config and binding.
27
- It does not require backend activation and it does not run an installer CLI.
26
+ The setup flow writes plugin-side config and binding for the local `main`
27
+ agent. Workspace-local `.claworld/` files are maintained by the runtime prompt
28
+ bootstrap in the active OpenClaw workspace.
29
+ Backend activation remains a first-use runtime step. Setup runs through the
30
+ OpenClaw host lifecycle.
31
+
32
+ ## Upgrade
33
+
34
+ For an existing Claworld install, update the tracked npm package and restart the gateway:
35
+
36
+ ```bash
37
+ openclaw plugins update @xfxstudio/claworld
38
+ openclaw gateway restart
39
+ ```
28
40
 
29
41
  ## First-Use Activation
30
42
 
@@ -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.5",
20
+ "version": "2026.6.9-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.5",
3
+ "version": "2026.6.9-testing.1",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -37,7 +37,7 @@
37
37
  "node": ">=22"
38
38
  },
39
39
  "peerDependencies": {
40
- "openclaw": ">=2026.3.22"
40
+ "openclaw": ">=2026.4.5"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "openclaw": {
@@ -71,7 +71,10 @@
71
71
  "install": {
72
72
  "npmSpec": "@xfxstudio/claworld",
73
73
  "defaultChoice": "npm",
74
- "minHostVersion": ">=2026.3.22"
74
+ "minHostVersion": ">=2026.4.5"
75
+ },
76
+ "compat": {
77
+ "pluginApi": ">=2026.4.5"
75
78
  }
76
79
  }
77
80
  }
@@ -61,8 +61,8 @@ openclaw agents bind --agent main --bind claworld:claworld
61
61
  When the plugin is already installed, check the version and update it in place.
62
62
 
63
63
  ```bash
64
- openclaw plugins update claworld --dry-run
65
- openclaw plugins update claworld
64
+ openclaw plugins update @xfxstudio/claworld --dry-run
65
+ openclaw plugins update @xfxstudio/claworld
66
66
  openclaw gateway restart
67
67
  ```
68
68
 
@@ -336,25 +336,6 @@ function inferExistingAgentId(config = {}, accountId = DEFAULT_CLAWORLD_ACCOUNT_
336
336
  return DEFAULT_CLAWORLD_AGENT_ID;
337
337
  }
338
338
 
339
- const MANAGED_LEGACY_BUNDLED_SKILL_NAMES = Object.freeze([
340
- 'claworld-main-session',
341
- 'claworld-manage-worlds',
342
- 'claworld-help',
343
- ]);
344
-
345
- function hasOnlyManagedBundledSkills(value) {
346
- if (!Array.isArray(value) || value.length === 0) return false;
347
- return value.every((skillName) => MANAGED_LEGACY_BUNDLED_SKILL_NAMES.includes(skillName));
348
- }
349
-
350
- function buildManagedAgentEntry(options = {}) {
351
- return {
352
- id: options.agentId,
353
- workspace: options.workspace,
354
- ...(options.agentDirExplicit && options.agentDir ? { agentDir: options.agentDir } : {}),
355
- };
356
- }
357
-
358
339
  function buildManagedRoutingEntry(options = {}, existingRouting = {}) {
359
340
  return {
360
341
  ...ensureObject(existingRouting),
@@ -507,60 +488,6 @@ export function resolveToolNames({ toolProfile = DEFAULT_CLAWORLD_TOOL_PROFILE }
507
488
  return [...baseProfile];
508
489
  }
509
490
 
510
- const MANAGED_BUNDLED_SKILL_NAMES = Object.freeze([
511
- 'claworld-main-session',
512
- 'claworld-manage-worlds',
513
- 'claworld-help',
514
- ]);
515
-
516
- export function resolveManagedAgentSkills({ toolProfile = DEFAULT_CLAWORLD_TOOL_PROFILE } = {}) {
517
- const normalizedProfile = normalizeClaworldToolProfile(toolProfile);
518
- return normalizedProfile === 'full' ? undefined : [...MANAGED_BUNDLED_SKILL_NAMES];
519
- }
520
-
521
- function describeToolAllowEntries(toolNames = []) {
522
- if (toolNames.length === 1) {
523
- return toolNames[0] === '*' ? '1 entry (includes *)' : '1 entry';
524
- }
525
- return toolNames.includes('*')
526
- ? `${toolNames.length} entries (includes *)`
527
- : `${toolNames.length} entries`;
528
- }
529
-
530
- export function buildWorkspaceAgentsContent({
531
- agentId,
532
- accountId,
533
- registrationDisplayName,
534
- appToken = null,
535
- defaultTargetAgentId = null,
536
- } = {}) {
537
- const identityLine = appToken
538
- ? '- relay binding is resolved from the configured appToken at runtime'
539
- : registrationDisplayName
540
- ? '- relay binding is created during runtime bootstrap and persists as backend-issued credentials'
541
- : '- activation is pending until the user completes Claworld public identity setup';
542
-
543
- return `# Claworld Channel Agent
544
-
545
- This workspace is dedicated to the OpenClaw \`claworld\` channel.
546
-
547
- Routing contract:
548
-
549
- - local OpenClaw agent id: \`${agentId}\`
550
- - claworld account id: \`${accountId}\`
551
- ${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : (appToken ? '- credential mode: appToken/manual binding' : '- credential mode: activation pending')}
552
- ${identityLine}
553
- ${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : '- outbound sends require explicit target agentId inputs'}
554
-
555
- Operating rules:
556
-
557
- - keep this workspace focused on Claworld relay and world interactions
558
- - use explicit \`claworld_*\` tools when they are available
559
- - do not treat this workspace as the user's general-purpose main agent
560
- - do not treat this as a separately bootstrapped OpenClaw persona
561
- `;
562
- }
563
-
564
491
  function buildBoundAgentEntry(existingAgent = {}, agentId) {
565
492
  const nextAgent = {
566
493
  ...ensureObject(existingAgent),
@@ -570,41 +497,8 @@ function buildBoundAgentEntry(existingAgent = {}, agentId) {
570
497
  return nextAgent;
571
498
  }
572
499
 
573
- export function buildWorkspaceMemoryContent({
574
- agentId,
575
- accountId,
576
- registrationDisplayName,
577
- appToken = null,
578
- defaultTargetAgentId = null,
579
- } = {}) {
580
- const identityLine = appToken
581
- ? '- relay binding: resolved from appToken at runtime'
582
- : registrationDisplayName
583
- ? '- relay binding: assigned during runtime bootstrap'
584
- : '- relay binding: pending until public identity setup completes';
585
-
586
- return `# Claworld Memory
587
-
588
- - workspace owner: \`${agentId}\`
589
- - claworld account: \`${accountId}\`
590
- ${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : ''}
591
- ${identityLine}
592
- ${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : ''}
593
-
594
- Use this file for durable Claworld-specific notes only.
595
-
596
- - keep world rules, pairing context, and recurring counterpart preferences here when they help future Claworld conversations
597
- - do not duplicate a full standalone OpenClaw bootstrap/persona here
598
- - prefer channel/world-specific memory over general-purpose assistant memory
599
- `;
600
- }
601
-
602
- export function resolveDefaultManagedWorkspace(agentId = DEFAULT_CLAWORLD_AGENT_ID) {
603
- return `~/.openclaw/workspace-${agentId}`;
604
- }
605
-
606
500
  export function resolveDefaultManagedDisplayName(accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
607
- return `${titleCase(accountId)} Channel Agent`;
501
+ return `${titleCase(accountId)} Channel`;
608
502
  }
609
503
 
610
504
  export function resolveClaworldManagedRuntimeOptions({
@@ -615,7 +509,6 @@ export function resolveClaworldManagedRuntimeOptions({
615
509
  installerState = null,
616
510
  } = {}) {
617
511
  const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
618
- const attachToExistingAgent = overrides.attachToExistingAgent !== false;
619
512
  const existingBackup = findClaworldManagedRuntimeBackup(installerState, resolvedAccountId);
620
513
  const inferredAgentId = inferExistingAgentId(cfg, resolvedAccountId)
621
514
  || normalizeText(existingBackup.agentId, null);
@@ -623,20 +516,7 @@ export function resolveClaworldManagedRuntimeOptions({
623
516
  const existingAgent = findAgentEntry(cfg, agentId);
624
517
  const existingAccount = findManagedAccountEntry(cfg, resolvedAccountId);
625
518
  const replaceManagedRuntime = overrides.replaceManagedRuntime !== false;
626
- const explicitWorkspace = normalizeText(overrides.workspace, null);
627
- const manageAgentEntry = overrides.manageAgentEntry === true
628
- || overrides.agentDirExplicit === true
629
- || attachToExistingAgent !== true;
630
- const manageWorkspace = overrides.manageWorkspace === true
631
- || Boolean(explicitWorkspace)
632
- || attachToExistingAgent !== true;
633
- const defaultWorkspace = manageWorkspace ? resolveDefaultManagedWorkspace(agentId) : null;
634
- const workspace = normalizeText(
635
- explicitWorkspace,
636
- replaceManagedRuntime
637
- ? normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace))
638
- : normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace)),
639
- );
519
+ const workspace = normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, null));
640
520
  const serverUrl = normalizeText(
641
521
  overrides.serverUrl,
642
522
  normalizeText(input.httpUrl, normalizeText(input.url, normalizeText(existingBackup.serverUrl, DEFAULT_CLAWORLD_SERVER_URL))),
@@ -680,14 +560,9 @@ export function resolveClaworldManagedRuntimeOptions({
680
560
 
681
561
  return {
682
562
  repoRoot: normalizeText(overrides.repoRoot, null),
683
- attachToExistingAgent,
684
563
  agentId,
685
564
  accountId: resolvedAccountId,
686
565
  workspace,
687
- manageAgentEntry,
688
- manageWorkspace,
689
- agentDir: normalizeText(overrides.agentDir, null),
690
- agentDirExplicit: overrides.agentDirExplicit === true,
691
566
  serverUrl,
692
567
  apiKey,
693
568
  appToken,
@@ -715,7 +590,6 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
715
590
  const replaceManagedRuntime = options.replaceManagedRuntime !== false;
716
591
  const preserveDefaultAccount = options.preserveDefaultAccount === true;
717
592
  const sessionDmScope = normalizeText(options.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE);
718
- const manageAgentEntry = options.manageAgentEntry === true;
719
593
 
720
594
  const removedManagedToolNames = new Set(CLAWORLD_PUBLIC_TOOL_NAMES);
721
595
  if (inputConfig?.tools && typeof inputConfig.tools === 'object') {
@@ -754,72 +628,18 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
754
628
 
755
629
  config.agents = ensureObject(config.agents);
756
630
  const existingAgentList = Array.isArray(config.agents.list) ? [...config.agents.list] : [];
757
- if (manageAgentEntry) {
758
- const managedAgentEntry = buildManagedAgentEntry(options);
759
- if (replaceManagedRuntime) {
760
- const removedAgentEntries = existingAgentList.filter((item) => ensureObject(item).id === options.agentId).length;
761
- config.agents.list = [
762
- ...existingAgentList.filter((item) => ensureObject(item).id !== options.agentId),
763
- {
764
- ...managedAgentEntry,
765
- tools: mergeManagedPluginToolExposure(managedAgentEntry.tools),
766
- },
767
- ];
768
- summary.push(
769
- removedAgentEntries > 0
770
- ? `replaced managed agent entry ${options.agentId}`
771
- : `added workspace-scoped agent entry ${options.agentId}`,
772
- );
773
- } else {
774
- const agentIndex = findAgentIndex(existingAgentList, options.agentId);
775
- if (agentIndex >= 0) {
776
- const existingAgent = ensureObject(existingAgentList[agentIndex]);
777
- const existingAgentDir = normalizeText(existingAgent.agentDir, null);
778
- const keepExistingAgentDir = Boolean(
779
- existingAgentDir
780
- && (
781
- options.agentDirExplicit
782
- || existingAgentDir !== normalizeText(options.agentDir, null)
783
- ),
784
- );
785
- const nextAgentEntry = {
786
- ...existingAgent,
787
- id: options.agentId,
788
- workspace: normalizeText(existingAgent.workspace, options.workspace),
789
- ...(keepExistingAgentDir ? { agentDir: existingAgentDir } : {}),
790
- };
791
- if (!keepExistingAgentDir) {
792
- delete nextAgentEntry.agentDir;
793
- }
794
- if (hasOnlyManagedBundledSkills(existingAgent.skills)) {
795
- delete nextAgentEntry.skills;
796
- }
797
- nextAgentEntry.tools = mergeManagedPluginToolExposure(existingAgent.tools);
798
- existingAgentList[agentIndex] = nextAgentEntry;
799
- summary.push(`updated existing agent entry ${options.agentId}`);
800
- } else {
801
- existingAgentList.push({
802
- ...managedAgentEntry,
803
- tools: mergeManagedPluginToolExposure(managedAgentEntry.tools),
804
- });
805
- summary.push(`added workspace-scoped agent entry ${options.agentId}`);
806
- }
807
- config.agents.list = existingAgentList;
808
- }
631
+ const agentIndex = findAgentIndex(existingAgentList, options.agentId);
632
+ if (agentIndex >= 0) {
633
+ const existingAgent = ensureObject(existingAgentList[agentIndex]);
634
+ existingAgentList[agentIndex] = buildBoundAgentEntry(existingAgent, options.agentId);
635
+ config.agents.list = existingAgentList;
636
+ summary.push(`updated bound agent tool exposure ${options.agentId}`);
809
637
  } else {
810
- const agentIndex = findAgentIndex(existingAgentList, options.agentId);
811
- if (agentIndex >= 0) {
812
- const existingAgent = ensureObject(existingAgentList[agentIndex]);
813
- existingAgentList[agentIndex] = buildBoundAgentEntry(existingAgent, options.agentId);
814
- config.agents.list = existingAgentList;
815
- summary.push(`updated bound agent tool exposure ${options.agentId}`);
816
- } else {
817
- existingAgentList.push(buildBoundAgentEntry({}, options.agentId));
818
- config.agents.list = existingAgentList;
819
- summary.push(`added bound agent entry ${options.agentId}`);
820
- }
821
- summary.push(`attached claworld account ${options.accountId} to existing local agent ${options.agentId}`);
638
+ existingAgentList.push(buildBoundAgentEntry({}, options.agentId));
639
+ config.agents.list = existingAgentList;
640
+ summary.push(`added bound agent entry ${options.agentId}`);
822
641
  }
642
+ summary.push(`attached claworld account ${options.accountId} to local agent ${options.agentId}`);
823
643
 
824
644
  config.channels = ensureObject(config.channels);
825
645
  const existingClaworldRoot = ensureObject(config.channels.claworld);
@@ -133,7 +133,6 @@ export function inspectManagedClaworldInstall({
133
133
  const setupReady = Boolean(
134
134
  managedAccountPresent
135
135
  && managedBindingPresent
136
- && (managedOptions.manageAgentEntry !== true || managedAgentPresent)
137
136
  );
138
137
 
139
138
  let statusLabel = 'needs setup';
@@ -247,8 +246,10 @@ async function applyManagedOnboardingConfig({
247
246
  `Remote backend: ${managedOptions.serverUrl}`,
248
247
  managedOptions.appToken
249
248
  ? 'Activation state: ready via configured appToken'
250
- : 'Activation state: pending until claworld_manage_account(action=update_display_name) runs',
251
- 'This flow refreshes plugin-side config and binds claworld onto the selected local agent. It does not run installer commands or start a backend service.',
249
+ : 'Activation state: pending until claworld_manage_account(action=activate_account) runs',
250
+ 'Workspace memory: runtime prompt bootstrap maintains .claworld/ in the active host workspace',
251
+ 'This flow refreshes plugin-side config and binds claworld onto the selected local agent.',
252
+ 'Setup lifecycle: OpenClaw host-native setup.',
252
253
  ];
253
254
  await prompter.note(
254
255
  noteLines.join('\n'),
@@ -1956,7 +1956,7 @@ function buildRegisteredTools(api, plugin) {
1956
1956
  examples: ['Moza', '小发发'],
1957
1957
  }),
1958
1958
  profile: stringParam({
1959
- description: 'Global plain-text profile for this account. Maximum 200 characters. Use an empty string to clear it. HTML is not supported.',
1959
+ description: 'Global plain-text profile for this account. Maximum 500 characters. Use an empty string to clear it. HTML is not supported.',
1960
1960
  examples: ['喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂'],
1961
1961
  }),
1962
1962
  chatRequestApprovalPolicy: chatRequestApprovalPolicyProperty,