@xfxstudio/claworld 2026.4.21-testing.1 → 2026.4.21-testing.2

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.
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "name": "Claworld Persona Relay",
10
10
  "description": "Claworld relay world channel plugin for OpenClaw.",
11
- "version": "2026.4.21-testing.1",
11
+ "version": "2026.4.21-testing.2",
12
12
  "configSchema": {
13
13
  "type": "object",
14
14
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfxstudio/claworld",
3
- "version": "2026.4.21-testing.1",
3
+ "version": "2026.4.21-testing.2",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,4 +1,3 @@
1
- import { detectOpenclawHost } from '../host-version.js';
2
1
  import { CLAWORLD_PLUGIN_CURRENT_VERSION } from '../plugin-version.js';
3
2
  import { getClaworldRuntime } from '../plugin/runtime.js';
4
3
 
@@ -123,6 +122,7 @@ const MODEL_ID_PATHS = [
123
122
  ];
124
123
 
125
124
  const OPENCLAW_VERSION_PATHS = [
125
+ ['version'],
126
126
  ['host', 'version'],
127
127
  ['openclaw', 'version'],
128
128
  ['meta', 'hostVersion'],
@@ -150,18 +150,8 @@ function resolveModelDiagnostics(sources = []) {
150
150
  };
151
151
  }
152
152
 
153
- let cachedOpenclawVersionPromise = null;
154
-
155
- async function detectOpenclawVersion(runtime = null) {
156
- const exposedVersion = pickDiagnosticValue([runtime], OPENCLAW_VERSION_PATHS, normalizeText);
157
- if (exposedVersion) return exposedVersion;
158
- if (!runtime) return null;
159
- if (!cachedOpenclawVersionPromise) {
160
- cachedOpenclawVersionPromise = detectOpenclawHost()
161
- .then((result) => normalizeText(result?.version, null))
162
- .catch(() => null);
163
- }
164
- return cachedOpenclawVersionPromise;
153
+ function detectOpenclawVersion(runtime = null) {
154
+ return pickDiagnosticValue([runtime], OPENCLAW_VERSION_PATHS, normalizeText);
165
155
  }
166
156
 
167
157
  export async function collectFeedbackDiagnostics({
@@ -170,10 +160,8 @@ export async function collectFeedbackDiagnostics({
170
160
  pluginVersion = null,
171
161
  } = {}) {
172
162
  const resolvedRuntime = resolveRuntimeCandidate(runtime);
173
- const [loadedConfig, openclawVersion] = await Promise.all([
174
- loadRuntimeConfig(resolvedRuntime),
175
- detectOpenclawVersion(resolvedRuntime),
176
- ]);
163
+ const loadedConfig = await loadRuntimeConfig(resolvedRuntime);
164
+ const openclawVersion = detectOpenclawVersion(resolvedRuntime);
177
165
  const modelDiagnostics = resolveModelDiagnostics([
178
166
  resolvedRuntime,
179
167
  loadedConfig,
@@ -1,222 +0,0 @@
1
- import { accessSync, constants as FS_CONSTANTS } from 'fs';
2
- import path from 'path';
3
- import { spawnSync } from 'child_process';
4
-
5
- export const DEFAULT_OPENCLAW_BIN = 'openclaw';
6
-
7
- function normalizeText(value, fallback = null) {
8
- if (value == null) return fallback;
9
- const normalized = String(value).trim();
10
- return normalized || fallback;
11
- }
12
-
13
- function createOpenclawVersionError(code, message, context = {}) {
14
- const error = new Error(message);
15
- error.code = code;
16
- error.context = context;
17
- return error;
18
- }
19
-
20
- function isExplicitCommandPath(command = '') {
21
- const normalized = String(command || '').trim();
22
- if (!normalized) return false;
23
- return normalized.includes('/') || normalized.includes('\\') || path.isAbsolute(normalized);
24
- }
25
-
26
- function splitPathEnvEntries(pathValue = '') {
27
- return String(pathValue || '')
28
- .split(path.delimiter)
29
- .map((entry) => entry.trim())
30
- .filter(Boolean);
31
- }
32
-
33
- function isNodeModulesBinEntry(entry = '') {
34
- const normalized = path.resolve(String(entry || ''));
35
- return path.basename(normalized) === '.bin'
36
- && path.basename(path.dirname(normalized)) === 'node_modules';
37
- }
38
-
39
- function resolveCommandNameCandidates(command = '', env = process.env) {
40
- const normalized = String(command || '').trim();
41
- if (!normalized) return [];
42
- if (process.platform !== 'win32' || path.extname(normalized)) {
43
- return [normalized];
44
- }
45
-
46
- const pathExt = splitPathEnvEntries(env?.PATHEXT || process.env.PATHEXT || '.COM;.EXE;.BAT;.CMD')
47
- .map((ext) => ext.toLowerCase());
48
- return [...new Set([normalized, ...pathExt.map((ext) => `${normalized}${ext}`)])];
49
- }
50
-
51
- function hasExecutableAccess(filePath = '') {
52
- try {
53
- accessSync(filePath, FS_CONSTANTS.X_OK);
54
- return true;
55
- } catch {
56
- return false;
57
- }
58
- }
59
-
60
- function resolveOpenclawCliBinary({
61
- openclawBin = DEFAULT_OPENCLAW_BIN,
62
- env = process.env,
63
- } = {}) {
64
- const requestedBin = normalizeText(openclawBin, DEFAULT_OPENCLAW_BIN);
65
- if (
66
- requestedBin !== DEFAULT_OPENCLAW_BIN
67
- || isExplicitCommandPath(requestedBin)
68
- ) {
69
- return {
70
- requestedBin,
71
- binaryPath: requestedBin,
72
- binarySource: isExplicitCommandPath(requestedBin) ? 'explicit_path' : 'explicit_command',
73
- skippedLocalBinaryPaths: [],
74
- };
75
- }
76
-
77
- const candidates = [];
78
- for (const entry of splitPathEnvEntries(env?.PATH || process.env.PATH || '')) {
79
- for (const name of resolveCommandNameCandidates(requestedBin, env)) {
80
- const candidatePath = path.join(entry, name);
81
- if (hasExecutableAccess(candidatePath)) {
82
- candidates.push(candidatePath);
83
- }
84
- }
85
- }
86
-
87
- const uniqueCandidates = [...new Set(candidates)];
88
- const hostCandidates = uniqueCandidates.filter((candidate) => !isNodeModulesBinEntry(path.dirname(candidate)));
89
- const localCandidates = uniqueCandidates.filter((candidate) => isNodeModulesBinEntry(path.dirname(candidate)));
90
- const binaryPath = hostCandidates[0] || uniqueCandidates[0] || requestedBin;
91
-
92
- return {
93
- requestedBin,
94
- binaryPath,
95
- binarySource: hostCandidates[0]
96
- ? 'host_path'
97
- : uniqueCandidates[0]
98
- ? 'package_local_path'
99
- : 'default_command',
100
- skippedLocalBinaryPaths: localCandidates.filter((candidate) => candidate !== binaryPath),
101
- };
102
- }
103
-
104
- function defaultCommandRunner({
105
- bin,
106
- args = [],
107
- cwd = process.cwd(),
108
- env = process.env,
109
- } = {}) {
110
- const result = spawnSync(bin, args, {
111
- cwd,
112
- env,
113
- encoding: 'utf8',
114
- stdio: ['ignore', 'pipe', 'pipe'],
115
- shell: false,
116
- windowsHide: true,
117
- });
118
- if (result.error) throw result.error;
119
- return {
120
- status: Number.isInteger(result.status) ? result.status : 1,
121
- stdout: result.stdout || '',
122
- stderr: result.stderr || '',
123
- };
124
- }
125
-
126
- function parseCommandVersion(text) {
127
- const match = String(text || '').match(/OpenClaw\s+([0-9]+(?:\.[0-9]+)+(?:-[0-9A-Za-z.-]+)?)/i)
128
- || String(text || '').match(/([0-9]+(?:\.[0-9]+)+(?:-[0-9A-Za-z.-]+)?)/);
129
- return match ? match[1] : null;
130
- }
131
-
132
- async function executeCommand({
133
- commandRunner = defaultCommandRunner,
134
- bin,
135
- args = [],
136
- cwd = process.cwd(),
137
- env = process.env,
138
- dryRun = false,
139
- } = {}) {
140
- const resolvedBin = resolveOpenclawCliBinary({
141
- openclawBin: bin,
142
- env,
143
- });
144
- const effectiveBin = commandRunner === defaultCommandRunner
145
- ? resolvedBin.binaryPath
146
- : resolvedBin.requestedBin;
147
- if (dryRun) {
148
- return {
149
- status: 0,
150
- stdout: '',
151
- stderr: '',
152
- requestedBin: resolvedBin.requestedBin,
153
- resolvedBin: resolvedBin.binaryPath,
154
- binSource: resolvedBin.binarySource,
155
- skippedBinCandidates: resolvedBin.skippedLocalBinaryPaths,
156
- };
157
- }
158
-
159
- let result;
160
- try {
161
- result = await commandRunner({
162
- bin: effectiveBin,
163
- args,
164
- cwd,
165
- env,
166
- });
167
- } catch (error) {
168
- throw createOpenclawVersionError(
169
- 'openclaw_command_failed',
170
- error?.message || String(error),
171
- {
172
- bin: resolvedBin.binaryPath,
173
- args,
174
- },
175
- );
176
- }
177
-
178
- return {
179
- status: Number.isInteger(result?.status) ? result.status : 1,
180
- stdout: result?.stdout || '',
181
- stderr: result?.stderr || '',
182
- requestedBin: resolvedBin.requestedBin,
183
- resolvedBin: resolvedBin.binaryPath,
184
- binSource: resolvedBin.binarySource,
185
- skippedBinCandidates: resolvedBin.skippedLocalBinaryPaths,
186
- };
187
- }
188
-
189
- export async function detectOpenclawHost({
190
- openclawBin = DEFAULT_OPENCLAW_BIN,
191
- commandRunner = defaultCommandRunner,
192
- cwd = process.cwd(),
193
- env = process.env,
194
- dryRun = false,
195
- } = {}) {
196
- const result = await executeCommand({
197
- commandRunner,
198
- bin: openclawBin,
199
- args: ['--version'],
200
- cwd,
201
- env,
202
- dryRun,
203
- });
204
- const version = parseCommandVersion(result.stdout || result.stderr);
205
- if (!version) {
206
- throw createOpenclawVersionError(
207
- 'openclaw_version_unreadable',
208
- 'Unable to determine the installed OpenClaw version.',
209
- { result },
210
- );
211
- }
212
- return {
213
- version,
214
- raw: (result.stdout || result.stderr || '').trim(),
215
- requestedBin: result.requestedBin || openclawBin,
216
- binaryPath: result.resolvedBin || openclawBin,
217
- binarySource: result.binSource || 'default_command',
218
- skippedLocalBinaryPaths: Array.isArray(result.skippedBinCandidates)
219
- ? result.skippedBinCandidates
220
- : [],
221
- };
222
- }