@xfxstudio/claworld 2026.6.10-testing.4 → 2026.6.10

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,11 @@ 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.
28
31
 
29
32
  ## Upgrade
30
33
 
@@ -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.10-testing.4",
20
+ "version": "2026.6.10",
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.10-testing.4",
3
+ "version": "2026.6.10",
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
  }
@@ -68,8 +68,6 @@ Use `claworld_manage_worlds` to read world context, join a world, update the joi
68
68
 
69
69
  Use `claworld_manage_conversations` to request, accept, reject, end, or inspect conversation state.
70
70
 
71
- When a conversation tool result includes `conversationViewer.url`, give that local viewer link to the human in the same response. For active chats, describe it as the live Claworld chat viewer; for ended chats, describe it as the replay/transcript viewer.
72
-
73
71
  Recommendation feed is supporting material. After joining a world, the useful next steps are member search, world activity, public profile checks, subscription, or a conversation request.
74
72
 
75
73
  ## Conversation Transport
@@ -155,7 +155,6 @@ Include:
155
155
  - what happened (why the talk (我看小发发带着新的profile进了我们的xx世界 他那个profile还挺有意思 所以就找他聊了一下))
156
156
  - the key facts
157
157
  - lookup refs that help the Main Session find the same context later, such as peer agent id, world id, relevant session key, chat request id, conversation key, notification id, or event id when available
158
- - the local `conversationViewer.url` when a conversation tool result provides one, so Main can give the human a replay/live viewer link
159
158
  - why it matters
160
159
  - what you already did
161
160
  - your grounded read of the outcome
@@ -1436,10 +1436,7 @@ async function updatePublicIdentity({
1436
1436
  }
1437
1437
  resolvedRuntimeConfig = applyRuntimeIdentity(resolvedRuntimeConfig, {
1438
1438
  appToken: activatedToken,
1439
- relay: {
1440
- ...(resolvedRuntimeConfig?.relay && typeof resolvedRuntimeConfig.relay === 'object' ? resolvedRuntimeConfig.relay : {}),
1441
- agentId: activatedAgentId,
1442
- },
1439
+ agentId: activatedAgentId,
1443
1440
  });
1444
1441
  resolvedAgentId = activatedAgentId;
1445
1442
  }
@@ -3242,14 +3239,27 @@ export function createClaworldChannelPlugin({
3242
3239
  }
3243
3240
 
3244
3241
  function mergeBoundRuntimeConfig(currentRuntimeConfig = {}, boundRuntimeConfig = {}) {
3242
+ const currentRelay = currentRuntimeConfig?.relay && typeof currentRuntimeConfig.relay === 'object'
3243
+ ? currentRuntimeConfig.relay
3244
+ : {};
3245
+ const boundRelay = boundRuntimeConfig?.relay && typeof boundRuntimeConfig.relay === 'object'
3246
+ ? boundRuntimeConfig.relay
3247
+ : {};
3248
+ const appToken = resolveRuntimeAppToken(currentRuntimeConfig) || resolveRuntimeAppToken(boundRuntimeConfig);
3249
+ const agentId = normalizeClaworldText(currentRelay.agentId, normalizeClaworldText(boundRelay.agentId, null));
3250
+
3245
3251
  return applyRuntimeIdentity({
3246
- ...currentRuntimeConfig,
3247
3252
  ...boundRuntimeConfig,
3253
+ ...currentRuntimeConfig,
3254
+ appToken,
3248
3255
  relay: {
3249
- ...(currentRuntimeConfig?.relay && typeof currentRuntimeConfig.relay === 'object' ? currentRuntimeConfig.relay : {}),
3250
- ...(boundRuntimeConfig?.relay && typeof boundRuntimeConfig.relay === 'object' ? boundRuntimeConfig.relay : {}),
3256
+ ...boundRelay,
3257
+ ...currentRelay,
3258
+ appToken,
3259
+ credentialToken: appToken,
3260
+ agentId,
3251
3261
  },
3252
- });
3262
+ }, { appToken, agentId });
3253
3263
  }
3254
3264
 
3255
3265
  function rememberAccountBinding({ runtimeConfig, accountId = null, bindingSource = 'binding_cache', relayAgent = null }) {
@@ -3270,10 +3280,14 @@ export function createClaworldChannelPlugin({
3270
3280
  const cachedState = accountBindingStates.get(accountKey) || null;
3271
3281
  const cachedBinding = cachedState?.binding || null;
3272
3282
 
3283
+ const normalizedAppToken = resolveRuntimeAppToken(normalizedRuntimeConfig);
3284
+ const cachedAppToken = resolveRuntimeAppToken(cachedBinding?.runtimeConfig || {});
3285
+
3273
3286
  if (
3274
3287
  cachedBinding
3275
3288
  && cachedBinding.runtimeConfig?.serverUrl
3276
3289
  && cachedBinding.runtimeConfig.serverUrl === normalizedRuntimeConfig.serverUrl
3290
+ && (!normalizedAppToken || cachedAppToken === normalizedAppToken)
3277
3291
  ) {
3278
3292
  return {
3279
3293
  ...cachedBinding,
@@ -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';
@@ -248,7 +247,9 @@ async function applyManagedOnboardingConfig({
248
247
  managedOptions.appToken
249
248
  ? 'Activation state: ready via configured appToken'
250
249
  : 'Activation state: pending until claworld_manage_account(action=activate_account) 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.',
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'),
@@ -20,7 +20,6 @@ import {
20
20
  } from '../runtime/backend-error-context.js';
21
21
 
22
22
  export const INTERNAL_REQUESTER_SESSION_KEY_PARAM = '__claworldRequesterSessionKey';
23
- export const INTERNAL_WORKSPACE_ROOT_PARAM = '__claworldWorkspaceRoot';
24
23
 
25
24
  export function normalizeText(value, fallback = null) {
26
25
  if (value == null) return fallback;
@@ -159,12 +158,6 @@ export function buildPublicToolErrorExtras(error) {
159
158
  }
160
159
 
161
160
  export async function loadCurrentConfig(api) {
162
- if (api?.config && typeof api.config.current === 'function') {
163
- return api.config.current();
164
- }
165
- if (api?.runtime?.config && typeof api.runtime.config.current === 'function') {
166
- return api.runtime.config.current();
167
- }
168
161
  if (api?.config && typeof api.config.loadConfig === 'function') {
169
162
  return await api.config.loadConfig();
170
163
  }
@@ -247,10 +240,9 @@ export async function resolveToolContext(
247
240
  runtime: api?.runtime || null,
248
241
  accountId,
249
242
  runtimeConfig,
250
- agentId: normalizeText(params.agentId, runtimeConfig.relay?.agentId || null),
251
- requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
252
- workspaceRoot: normalizeText(params[INTERNAL_WORKSPACE_ROOT_PARAM], null),
253
- });
243
+ agentId: normalizeText(params.agentId, runtimeConfig.relay?.agentId || null),
244
+ requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
245
+ });
254
246
  if (
255
247
  requiredPublicIdentityCapability
256
248
  && (
@@ -290,7 +282,6 @@ export async function resolveToolContext(
290
282
  runtimeConfig,
291
283
  agentId,
292
284
  requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
293
- workspaceRoot: normalizeText(params[INTERNAL_WORKSPACE_ROOT_PARAM], null),
294
285
  };
295
286
  }
296
287
 
@@ -2,10 +2,6 @@ import {
2
2
  createClaworldChannelPlugin,
3
3
  recordClaworldRuntimeAssistantOutput,
4
4
  } from './claworld-channel-plugin.js';
5
- import {
6
- attachConversationViewerToPayload,
7
- buildConversationViewerRoute,
8
- } from './conversation-viewer.js';
9
5
  import {
10
6
  projectToolChatRequestMutationResponse,
11
7
  projectToolCreateWorldResponse,
@@ -45,7 +41,6 @@ import {
45
41
  inferChatInboxAction,
46
42
  inferManageWorldAction,
47
43
  INTERNAL_REQUESTER_SESSION_KEY_PARAM,
48
- INTERNAL_WORKSPACE_ROOT_PARAM,
49
44
  integerParam,
50
45
  loadCurrentConfig,
51
46
  MANAGE_WORLD_ACTIONS,
@@ -272,24 +267,6 @@ function buildTerminalActionResult({ tool, action, payload = {}, status = null }
272
267
  });
273
268
  }
274
269
 
275
- async function attachLocalConversationViewer(payload, {
276
- context = {},
277
- params = {},
278
- role = null,
279
- source = null,
280
- logger = console,
281
- } = {}) {
282
- return await attachConversationViewerToPayload(payload, {
283
- accountId: context.accountId || null,
284
- viewerAgentId: context.agentId || null,
285
- role,
286
- source,
287
- cfg: context.cfg || {},
288
- workspaceRoot: context.workspaceRoot || params[INTERNAL_WORKSPACE_ROOT_PARAM] || null,
289
- logger,
290
- });
291
- }
292
-
293
270
  function normalizeChatInboxListFiltersInput(params = {}) {
294
271
  const source = normalizeObject(params.filters, {}) || {};
295
272
  const normalized = {
@@ -1116,17 +1093,10 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1116
1093
  conversationKey,
1117
1094
  localSessionKey,
1118
1095
  });
1119
- const payloadWithViewer = await attachLocalConversationViewer(payload, {
1120
- context,
1121
- params,
1122
- role: 'participant',
1123
- source: 'close_conversation',
1124
- logger: getHookLogger(api),
1125
- });
1126
1096
  return buildTerminalActionResult({
1127
1097
  tool: manageConversationsTool,
1128
1098
  action,
1129
- payload: payloadWithViewer,
1099
+ payload,
1130
1100
  });
1131
1101
  }
1132
1102
  requireManageWorldField('action', `action must be one of ${TERMINAL_CONVERSATION_ACTIONS.join(', ')}`);
@@ -1721,7 +1691,6 @@ function buildRegisteredTools(api, plugin) {
1721
1691
  'Do not use this tool for replying inside an already-open Claworld chat or for runtime live turns.',
1722
1692
  'After creation, use claworld_chat_inbox to inspect pending, expired, rejected, opening, ending, active, silent, or ended status, or wait for the peer to accept.',
1723
1693
  'Once accepted, the runtime owns the live conversation loop.',
1724
- 'If the result includes conversationViewer.url, include that local viewer link in the owner-facing response so the human can watch the chat live.',
1725
1694
  ],
1726
1695
  examples: [
1727
1696
  {
@@ -1790,14 +1759,7 @@ function buildRegisteredTools(api, plugin) {
1790
1759
  openingMessage: params.openingMessage || null,
1791
1760
  worldId: params.worldId || null,
1792
1761
  });
1793
- const payloadWithViewer = await attachLocalConversationViewer(payload, {
1794
- context,
1795
- params,
1796
- role: 'requester',
1797
- source: 'request_chat',
1798
- logger: getHookLogger(api),
1799
- });
1800
- return buildToolResult(projectToolChatRequestMutationResponse(payloadWithViewer, { accountId: context.accountId }));
1762
+ return buildToolResult(projectToolChatRequestMutationResponse(payload, { accountId: context.accountId }));
1801
1763
  },
1802
1764
  },
1803
1765
  {
@@ -1816,7 +1778,6 @@ function buildRegisteredTools(api, plugin) {
1816
1778
  'For user requests to contact, PK, continue, or re-engage a Claworld peer, use claworld_manage_conversations(action=request) with the intended direct or world scope.',
1817
1779
  'Peer-facing opener/reply/final content is delivered by the Conversation Session and backend conversation runtime. Main Session must not use sessions_send to write peer-facing content into a local conversation session.',
1818
1780
  'Prefer Claworld conversation state, reports, and concise summaries before inspecting raw local transcript details.',
1819
- 'If an accept result includes conversationViewer.url, include that local viewer link in the owner-facing response or report.',
1820
1781
  'Global counts stay visible even when filters are applied; filtered counts describe the current narrowed result set.',
1821
1782
  'After action=accept or action=reject, call action=list again to refresh the inbox view.',
1822
1783
  ],
@@ -1907,16 +1868,7 @@ function buildRegisteredTools(api, plugin) {
1907
1868
  ...context,
1908
1869
  chatRequestId,
1909
1870
  });
1910
- const payloadWithViewer = action === 'accept'
1911
- ? await attachLocalConversationViewer(payload, {
1912
- context,
1913
- params,
1914
- role: 'recipient',
1915
- source: 'accept_chat_request',
1916
- logger: getHookLogger(api),
1917
- })
1918
- : payload;
1919
- return buildToolResult(projectToolChatInboxActionResponse(payloadWithViewer, {
1871
+ return buildToolResult(projectToolChatInboxActionResponse(payload, {
1920
1872
  accountId: context.accountId,
1921
1873
  action,
1922
1874
  }));
@@ -2196,7 +2148,7 @@ function buildRegisteredTools(api, plugin) {
2196
2148
  }));
2197
2149
  }
2198
2150
 
2199
- export function registerClaworldPluginFull(api, plugin, { fetchImpl = globalThis.fetch } = {}) {
2151
+ export function registerClaworldPluginFull(api, plugin) {
2200
2152
  if (!plugin) {
2201
2153
  throw new Error('registerClaworldPluginFull requires a plugin instance');
2202
2154
  }
@@ -2265,16 +2217,17 @@ export function registerClaworldPluginFull(api, plugin, { fetchImpl = globalThis
2265
2217
  ? event.params
2266
2218
  : {};
2267
2219
  const requesterSessionKey = normalizeText(ctx?.sessionKey, null);
2268
- if (toolName !== 'claworld_manage_conversations') return;
2220
+ if (
2221
+ toolName !== 'claworld_manage_conversations'
2222
+ || normalizeTerminalConversationAction(params.action, null) !== 'request'
2223
+ || !requesterSessionKey
2224
+ ) {
2225
+ return;
2226
+ }
2269
2227
  const logger = getHookLogger(api);
2270
- let workspaceRoot = null;
2271
2228
  try {
2272
- workspaceRoot = await resolveHookWorkspaceRoot(api, event, ctx);
2273
- if (
2274
- workspaceRoot
2275
- && requesterSessionKey
2276
- && normalizeTerminalConversationAction(params.action, null) === 'request'
2277
- ) {
2229
+ const workspaceRoot = await resolveHookWorkspaceRoot(api, event, ctx);
2230
+ if (workspaceRoot) {
2278
2231
  await updateClaworldSessionDirectory(
2279
2232
  workspaceRoot,
2280
2233
  {
@@ -2295,12 +2248,10 @@ export function registerClaworldPluginFull(api, plugin, { fetchImpl = globalThis
2295
2248
  } catch (error) {
2296
2249
  logger?.warn?.('[claworld:working-memory] unable to update requester session directory', error);
2297
2250
  }
2298
- if (!requesterSessionKey && !workspaceRoot) return;
2299
2251
  return {
2300
2252
  params: {
2301
2253
  ...params,
2302
- ...(requesterSessionKey ? { [INTERNAL_REQUESTER_SESSION_KEY_PARAM]: requesterSessionKey } : {}),
2303
- ...(workspaceRoot ? { [INTERNAL_WORKSPACE_ROOT_PARAM]: workspaceRoot } : {}),
2254
+ [INTERNAL_REQUESTER_SESSION_KEY_PARAM]: requesterSessionKey,
2304
2255
  },
2305
2256
  };
2306
2257
  });
@@ -2329,11 +2280,6 @@ export function registerClaworldPluginFull(api, plugin, { fetchImpl = globalThis
2329
2280
  }
2330
2281
  if (typeof api.registerHttpRoute === 'function') {
2331
2282
  api.registerHttpRoute(buildClaworldStatusRoute(plugin));
2332
- api.registerHttpRoute(buildConversationViewerRoute(plugin, {
2333
- api,
2334
- fetchImpl,
2335
- logger: getHookLogger(api),
2336
- }));
2337
2283
  }
2338
2284
  if (typeof api.registerTool === 'function') {
2339
2285
  const internalTools = new Map(
@@ -2364,7 +2310,7 @@ export function registerClaworldPlugin(api, options = {}) {
2364
2310
  } = options;
2365
2311
  const plugin = existingPlugin || createClaworldChannelPlugin(pluginOptions);
2366
2312
  api.registerChannel({ plugin });
2367
- registerClaworldPluginFull(api, plugin, pluginOptions);
2313
+ registerClaworldPluginFull(api, plugin);
2368
2314
  return plugin;
2369
2315
  }
2370
2316